Provisioned concurrency is a serverless setting that keeps a fixed number of function execution environments initialized and ready before any request arrives, so invocations routed to them start without a cold start. The term comes from AWS Lambda, and comparable features exist on other platforms as always-ready or minimum instances.
It trades part of the pay-per-use model of serverless computing for predictable latency: the operator pays for the warm capacity whether or not it is used, and in return the function responds with consistent start-up times during the periods that matter.
How provisioned concurrency removes cold starts
A function on demand runs in an execution environment that the platform creates when a request arrives and no idle environment is free. Creating it means allocating a micro virtual machine or container, downloading the code package, starting the language runtime and running the initialization code outside the handler. That sequence is the cold start, and it can add from under 100 milliseconds to several seconds depending on runtime, package size and dependencies.
With provisioned concurrency, the platform performs those steps ahead of time for the configured number of environments and keeps them alive. Each environment handles one request at a time, so a setting of 50 means up to 50 simultaneous requests can be served warm. Any traffic above that level spills over to on-demand environments, which may still experience cold starts.
The table below lists the main settings and properties that define provisioned concurrency on AWS Lambda.
| Property | Behavior | Practical note |
|---|---|---|
| Target | A published version or an alias | Cannot be applied to the unpublished latest code |
| Configured amount | Number of pre-initialized environments | Counts against the account concurrency limit |
| Allocation time | Environments prepared after configuration | Takes minutes, not seconds |
| Spillover | Excess requests use on-demand capacity | Those requests can still cold start |
| Utilization metric | Share of provisioned capacity in use | Basis for automatic scaling |
Cost model and scaling options
Provisioned concurrency introduces a standing charge for the configured capacity, measured by memory size and time, in addition to the charge for each invocation. Requests served by provisioned environments are usually billed at a lower duration rate than on-demand requests, so high, steady utilization can make it cost-neutral or even cheaper, while low utilization makes it clearly more expensive.
Because traffic rarely stays flat, the configured amount is normally managed by Application Auto Scaling rather than fixed by hand. Two approaches are common, and they can be combined.
| Approach | How it works | Best suited for |
|---|---|---|
| Fixed value | Constant number of environments | Small, steady latency-critical APIs |
| Scheduled scaling | Raises and lowers capacity at set times | Known business hours or planned events |
| Target tracking | Keeps utilization near a target such as 70 percent | Gradual, organic traffic changes |
| Schedule plus tracking | Schedule sets the floor, tracking adds more | Daily peaks with unpredictable bursts |
Target tracking reacts within minutes, not milliseconds. A sudden spike still lands mostly on on-demand capacity, so for launches or marketing campaigns a scheduled increase before the event is more reliable.
Comparison with related controls and platforms
Provisioned concurrency is often confused with reserved concurrency, which is a different control. Reserved concurrency guarantees and caps the maximum number of concurrent executions for a function but does not pre-warm anything. Other platforms offer similar warm-capacity features under different names.
| Feature | Platform | What it guarantees |
|---|---|---|
| Provisioned concurrency | AWS Lambda | Pre-initialized environments per version or alias |
| Reserved concurrency | AWS Lambda | A concurrency quota and ceiling, no warm-up |
| SnapStart | AWS Lambda | Faster starts by restoring a memory snapshot |
| Always ready instances | Azure Functions | Instances kept running on Premium and Flex plans |
| Minimum instances | Google Cloud Run | Containers kept warm, each serving many requests |
A key difference is the concurrency model. A Lambda environment serves one request at a time, so warm capacity must match peak parallelism. A Cloud Run instance can serve many requests simultaneously, so a handful of minimum instances often covers a whole service. Edge platforms such as Cloudflare Workers use lightweight isolates with very short starts and generally do not need this feature.
When to use it and how to size it
Provisioned concurrency is justified when cold start latency is visible to users or breaks a contract, for example a synchronous API with a strict latency target, a payment step or a voice interface. It is rarely worth it for queue consumers, batch jobs or asynchronous event processing, where a delay of a second goes unnoticed.
Sizing starts from observed peak concurrent executions, which roughly equals requests per second multiplied by average duration in seconds. A function that receives 200 requests per second at 150 milliseconds needs about 30 concurrent environments at that peak, plus headroom.
| Situation | Recommendation | Reason |
|---|---|---|
| User-facing API with tight latency target | Use it, with scheduling | Removes the slowest first requests |
| Java or .NET with heavy initialization | Use it or try SnapStart | Cold starts can last seconds |
| Background or queue processing | Do not use it | Latency rarely matters, cost does |
| Very spiky, unpredictable traffic | Small floor plus optimization | Capacity cannot follow sudden bursts |
Pitfalls and misconceptions
- Invoking the wrong target: calls to the unqualified function name bypass the alias with provisioned capacity and still cold start.
- Paying for idle capacity at night or on weekends when no schedule lowers the amount.
- Assuming it eliminates all cold starts: spillover traffic and new deployments still create fresh environments.
- Forgetting that initialization code runs at allocation time, so stale credentials or cached configuration may need refreshing inside the handler.
- Exhausting the account concurrency limit, which leaves other functions unable to scale.
Before buying warm capacity, it is worth reducing cold start cost directly: smaller deployment packages, fewer dependencies loaded at start-up and lighter runtimes often shrink the problem enough that provisioned concurrency becomes unnecessary.
Put simply
Serverless functions usually start only when someone needs them. The first start takes extra time, a bit like a car engine on a cold morning. Provisioned concurrency keeps a few engines running and ready. The first customers do not have to wait.
The catch is that a running engine costs money even when nobody drives. So it makes sense only where waiting would really annoy people, and only at the times when they actually show up.
In practice
A ticketing company runs its checkout API on AWS Lambda with a Java runtime. Cold starts take about three seconds, and during evening sales windows users abandon purchases when the first click hangs. Average checkout duration is 200 milliseconds and peak traffic reaches roughly 150 requests per second, which means about 30 concurrent executions.
The team publishes an alias, sets 40 environments of provisioned concurrency through a schedule from 17:00 to 23:00, and adds target tracking at 70 percent utilization for unexpected peaks. Outside that window the amount drops to five. Checkout start-up delays disappear during sales, and the extra cost stays limited because warm capacity exists only during the evening hours.