<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz" -->

---
title: Long running jobs shouldn't be first-come first-served
description: Inngest offers two separate features, concurrency keys and priority, to control who waits in a backed-up queue and in what order. Concurrency keys create a...
canonical: https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Long running jobs shouldn't be first-come first-served | daily.dev
og:description: Inngest offers two separate features, concurrency keys and priority, to control who waits in a backed-up queue and in what order. Concurrency keys create a...
og:url: https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz
og:image: https://api.daily.dev/og/posts/GU6nohPhZ.png
og:image:alt: Long running jobs shouldn't be first-come first-served
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Long running jobs shouldn't be first-come first-served

**[Inngest Blog](https://daily.dev/sources/inngest)** · 9 min read · 0 upvotes · 0 comments

## Summary

Inngest offers two separate features, concurrency keys and priority, to control who waits in a backed-up queue and in what order. Concurrency keys create a separate queue per account or user, so one customer's burst of work doesn't block others. Priority is a number from -600 to 600 seconds that treats a run as having arrived earlier or later, so an enterprise run passes free runs that arrived less than that many seconds before it, like enterprise plans or dashboard requests. The two can be combined: a concurrency key splits work by account, then priority orders within each account's queue, for example letting interactive requests jump ahead of scheduled batches with `event.data.source == 'dashboard' ? 120 : 0`.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.inngest.com/blog/long-running-jobs-shouldnt-be-first-come-first-served>

## Questions this post answers

### How do I stop one customer's bulk job from blocking everyone else's background jobs in a shared queue?

Add a concurrency key, such as `key: "event.data.account_id"`, to the job's concurrency configuration. Inngest evaluates the key against each triggering event and creates a separate queue per unique value, so a limit like 2 concurrent runs per account stops one customer from taking every slot. A second, keyless limit can still cap the total across all accounts, for example limit 10.

_daily.dev surfaces patterns like this for developers tuning multi-tenant job queues._

### What is the difference between concurrency limits and priority in a job queue?

Concurrency limits cap how many steps run at the same time, while priority controls the order runs are pulled from the queue without adding capacity. In Inngest, priority is an expression returning seconds from -600 to 600: a positive value makes a run act as if it arrived earlier, a negative value as if it arrived later, and zero leaves it unchanged.

_Developers choosing between queue controls can track these trade-offs on daily.dev._

### How do I give enterprise customers faster turnaround than free-tier users in the same job queue?

Use a priority expression instead of splitting queues by plan, since reserving capacity for enterprise work wastes it when unused. An example expression is `event.data.plan == 'enterprise' ? 60 : 0`, which treats enterprise runs as having arrived 60 seconds earlier, letting them pass free runs that arrived less than 60 seconds before them, without starving the free queue indefinitely.

_daily.dev helps developers deciding how to prioritize paid traffic in shared infrastructure._

## Similar posts on daily.dev

- [NEW: Bursty Concurrency—Coverage for Spikes](https://daily.dev/posts/new-bursty-concurrency-coverage-for-spikes-oywvtwix8) · Inngest Blog · 0 upvotes · 0 comments
- [Job queues are deceptively tricky](https://daily.dev/posts/job-queues-are-deceptively-tricky-cj0ydgd0g) · Lobsters · 3 upvotes · 0 comments
- [Task Queue Priority and Fairness: Your Task Queue, your way](https://daily.dev/posts/task-queue-priority-and-fairness-your-task-queue-your-way-oi28edbnk) · Temporal · 0 upvotes · 0 comments
- [Keeping a Postgres queue healthy — PlanetScale](https://daily.dev/posts/keeping-a-postgres-queue-healthy-planetscale-h5pvjk1vk) · Hacker News · 0 upvotes · 0 comments
- [General Availability: Priority-Based Execution in Azure Cosmos DB](https://daily.dev/posts/general-availability-priority-based-execution-in-azure-cosmos-db-yspa5v2nz) · DevBlogs · 0 upvotes · 0 comments

---

Tags: [#backend](https://daily.dev/tags/backend), [#multi-tenancy](https://daily.dev/tags/multi-tenancy), [#inngest](https://daily.dev/tags/inngest)

[View this post on daily.dev](https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Long running jobs shouldn't be first-come first-served","url":"https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz"},"datePublished":"2026-10-20T16:20:07.771Z","dateModified":"2026-10-20T16:41:38.647Z","description":"Inngest offers two separate features, concurrency keys and priority, to control who waits in a backed-up queue and in what order. Concurrency keys create a...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f9f11782d55596ebcf303a187f2407ad?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f9f11782d55596ebcf303a187f2407ad?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Inngest Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Inngest Blog","logo":"https://media.daily.dev/image/upload/s--ieZKUa5y--/c_limit,w_256/f_auto,q_auto/v1789329423/logos/inngest?_a=BAMAMicg0","url":"https://daily.dev/sources/inngest"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"backend,multi-tenancy,inngest","timeRequired":"PT9M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Inngest Blog","item":"https://daily.dev/sources/inngest"},{"@type":"ListItem","position":3,"name":"Long running jobs shouldn't be first-come first-served"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/long-running-jobs-shouldn-t-be-first-come-first-served-gu6nohphz#faq","mainEntity":[{"@type":"Question","name":"How do I stop one customer's bulk job from blocking everyone else's background jobs in a shared queue?","acceptedAnswer":{"@type":"Answer","text":"Add a concurrency key, such as `key: \"event.data.account_id\"`, to the job's concurrency configuration. Inngest evaluates the key against each triggering event and creates a separate queue per unique value, so a limit like 2 concurrent runs per account stops one customer from taking every slot. A second, keyless limit can still cap the total across all accounts, for example limit 10. daily.dev surfaces patterns like this for developers tuning multi-tenant job queues."}},{"@type":"Question","name":"What is the difference between concurrency limits and priority in a job queue?","acceptedAnswer":{"@type":"Answer","text":"Concurrency limits cap how many steps run at the same time, while priority controls the order runs are pulled from the queue without adding capacity. In Inngest, priority is an expression returning seconds from -600 to 600: a positive value makes a run act as if it arrived earlier, a negative value as if it arrived later, and zero leaves it unchanged. Developers choosing between queue controls can track these trade-offs on daily.dev."}},{"@type":"Question","name":"How do I give enterprise customers faster turnaround than free-tier users in the same job queue?","acceptedAnswer":{"@type":"Answer","text":"Use a priority expression instead of splitting queues by plan, since reserving capacity for enterprise work wastes it when unused. An example expression is `event.data.plan == 'enterprise' ? 60 : 0`, which treats enterprise runs as having arrived 60 seconds earlier, letting them pass free runs that arrived less than 60 seconds before them, without starving the free queue indefinitely. daily.dev helps developers deciding how to prioritize paid traffic in shared infrastructure."}}]}
```

