Eliminate Lambda Cold Starts with Provisioned Concurrency: A Practical Guide
Provisioned concurrency lets you reserve warm Lambda environments, eliminating cold starts for latency‑sensitive workloads. This guide walks you through the concept, when to use it, a concrete CLI example, and cost‑vs‑performance trade‑offs.
01 Sept 2025, 23:31 UTC

Cold starts are the Achilles’ heel of serverless APIs
When a Lambda function is invoked after a period of inactivity, the platform must download the deployment package, spin up a container, and start the runtime. For user‑facing services that expect sub‑second responses, this “warm‑up” latency can be unacceptable. The obvious question is: how do we keep the function ready to go?
Enter Provisioned Concurrency
Provisioned concurrency lets you reserve a fixed number of execution environments that are always initialized and ready to serve requests. Once configured, the first invocation after a hibernation period no longer incurs the typical cold‑start delay.
Key points:
- The feature is available for both ZIP deployments and container images.
- Only published function versions or aliases can be configured; the $LATEST version cannot.
- You pay for the reserved environments on a per‑GB‑second basis, in addition to normal request charges.
- Provisioned environments count toward the account’s regional concurrency limit.
When to use it – a quick decision checklist
Provisioned concurrency shines in scenarios where predictable, low latency is critical and traffic can be forecasted:
- User‑facing REST APIs or GraphQL endpoints that must respond in < 200 ms.
If traffic is highly bursty or unpredictable, consider using On‑Demand concurrency and a Reserved Concurrency setting to bound the maximum number of simultaneous executions.
Step‑by‑step example: from function to warm execution
Below is a worked example using the AWS CLI. Replace the placeholders with your own values.
1. Create a simple Lambda function
# Create a Python 3.12 function that returns "Hello, world!"
aws lambda create-function \
--function-name MyHelloFunc \
--runtime python3.12 \
--role arn:aws:iam::123456789012:role/lambda-ex \
--handler index.handler \
--zip-file fileb://function.zip \
--region us-east-1 \
--timeout 10 \
--memory-size 128
Ensure the IAM role has the lambda:InvokeFunction and lambda:GetFunctionConfiguration permissions.
2. Publish a version
aws lambda publish-version \
--function-name MyHelloFunc \
--region us-east-1
This command returns a Version number (e.g., 1). You must use this version when configuring provisioned concurrency.
3. Reserve five execution environments
aws lambda put-provisioned-concurrency-config \
--function-name MyHelloFunc \
--qualifier 1 \
--provisioned-concurrent-executions 5 \
--region us-east-1
Permissions required: lambda:PutProvisionedConcurrencyConfig. The qualifier is the version number.
4. Invoke the function and watch CloudWatch
Run a few invocations:
aws lambda invoke \
--function-name MyHelloFunc \
--qualifier 1 \
--payload '{}' \
output.txt \
--region us-east-1
Check the Duration field in output.txt. The first few invocations should show low latency (e.g., < 200 ms). Compare with an on‑demand invocation (omit the --qualifier) to see the cold‑start spike.
5. Verify metrics
Open the CloudWatch console or query via CLI:
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name ProvisionedConcurrencyInvocations \
--dimensions Name=FunctionName,Value=MyHelloFunc Name=Resource,Value=MyHelloFunc:1 \
--statistics Sum \
--period 60 \
--start-time $(date -u -d '15 minutes ago' +%FT%TZ) \
--end-time $(date -u +%FT%TZ) \
--region us-east-1
Expect ProvisionedConcurrencyInvocations to increase with each call and ProvisionedConcurrencySpilloverInvocations to remain zero as long as traffic stays below the reserved limit.
Trade‑offs, limits, and best practices
- Cost: You pay for every reserved environment per GB‑second, even if idle. Use the AWS Pricing Calculator to estimate monthly charges.
- Over‑provisioning: Setting a higher value than needed wastes money. Monitor
ProvisionedConcurrencySpilloverInvocationsto detect under‑provisioning. - Account limits: Provisioned concurrency counts toward the regional
ConcurrentExecutionslimit. If you hit it, request an increase from AWS Support. - Version requirement: You cannot apply provisioned concurrency to the
$LATESTversion. Publish a stable version or use an alias pointing to that version. - Cold starts on spillover: Invocations that exceed the provisioned count will fall back to on‑demand, incurring the usual cold‑start latency.
Actionable checklist for production
- Identify functions that need sub‑second latency.
- Publish a dedicated version or alias for each.
- Reserve an initial concurrency value based on expected peak traffic.
- Set up CloudWatch alarms on
ProvisionedConcurrencySpilloverInvocationsandProvisionedConcurrencyInvocationsto detect mis‑configuration. - Periodically review usage and adjust the provisioned count to balance cost and performance.
- If traffic becomes unpredictable, consider a hybrid approach: provisioned concurrency for baseline traffic, with a higher
ReservedConcurrencylimit to absorb spikes.
By following these steps, you can reliably eliminate Lambda cold starts for latency‑sensitive workloads while keeping costs predictable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.