lambda-timeout-budget-reference
Pure-reference catalog of AWS Lambda timeout + billing semantics. Covers Lambda's hard 15-minute (900s) wall-clock limit, the timeout-vs-deadline relationship (Lambda Context.getRemainingTimeInMillis), per-invocation billing (rounded to 1ms; per-invocation + duration × memory), the memory-vs-CPU relationship (CPU scales linearly with memory), the integration-timeout cascade (API Gateway 29s → Lambda 15min; SQS visibility-timeout vs Lambda timeout), and per-runtime nuances. Use when designing a Lambda's timeout config, debugging timeout-vs-billing surprises, or sizing memory for compute-bound workloads.
Install with skills.sh (any agent)
npx skills add testland/qa --skill lambda-timeout-budget-referencelambda-timeout-budget-reference
Overview
AWS Lambda's wall-clock limit is 15 minutes (900 seconds) per invocation. Per docs.aws.amazon.com/lambda (opens in new window): "The default value for this setting is 3 seconds, but you can adjust this in increments of 1 second up to a maximum value of 900 seconds (15 minutes)."
When to use
The 15-minute limit
Per AWS Lambda docs: 900 seconds (15 minutes) absolute maximum. For longer work, use:
Don't try to architect around the 15-minute limit; pick the right service.
Timeout vs deadline at runtime
Per docs.aws.amazon.com/lambda (opens in new window): the Lambda Context object exposes get_remaining_time_in_millis() (Python), getRemainingTimeInMillis() (Node/JVM). Use it to break out of work proactively:
def handler(event, context):
while not_done:
if context.get_remaining_time_in_millis() < 5000:
# Save progress, return early
save_checkpoint()
return {"status": "partial", "checkpoint": ...}
do_work_chunk()
return {"status": "complete"}The 5-second cushion lets the handler return cleanly. Without it, the Lambda is force-killed at timeout and the caller gets a 504-equivalent.
Billing semantics
Per docs.aws.amazon.com/lambda (opens in new window):
| Cost component | Detail |
|---|---|
| Request charge | $0.20 per 1M requests (us-east-1) |
| Compute charge | Memory-class × GB-seconds (per ms) |
| Init duration | Free; not billed (per AWS) |
GB-second formula: memory_GB * duration_seconds.
A 512MB Lambda running 1000ms costs: 0.5 GB * 1.0 sec * $0.0000166667/GB-s = $0.00000833
Per million invocations at 1s, 512MB: $8.34 (+ $0.20 request) = $8.54.
Init duration billing was free as of 2023; this skill cites current docs.
Memory ↔ CPU relationship
Per docs.aws.amazon.com/lambda (opens in new window): "The amount of CPU available to a function is proportional to the memory you allocate to it. At 1,769 MB, a function has the equivalent of one vCPU."
Up to ~1769MB, you're paying for "memory" but getting "CPU." Compute-bound workloads should size memory by CPU need, not memory need.
A 256MB Lambda has ~14% of one vCPU. A 1.769GB Lambda has 1 full vCPU. A 3.5GB Lambda has 2 vCPUs.
The cost-vs-performance sweet spot is usually at the memory class where wall-clock time stops dropping (often 1024-2048MB for typical workloads).
Integration cascade
Lambda is rarely invoked directly; the integration's timeout is often the operational ceiling:
| Integration | Timeout | Lambda config |
|---|---|---|
| API Gateway (REST + HTTP API) | 29 seconds (hard) | Lambda timeout MUST be < 29s |
| Application Load Balancer | 4 seconds default; configurable to 4000s | Configurable both sides |
| CloudFront (Lambda@Edge viewer-request/response) | 5s for viewer functions; 30s for origin | Tight viewer limit |
| SQS (event source) | Configured per queue; default 30s visibility | Lambda timeout < visibility timeout |
| DynamoDB Streams | 6 hours batch window | Lambda timeout per-batch limit |
| EventBridge (async) | Async; retries on timeout | Idempotency required |
| Step Functions | Each task has its own timeout; default 60s | Per-task tuning |
The API Gateway 29-second hard limit is the most-encountered surprise: a Lambda configured for 60s still times out at 29s because API Gateway gives up first.
Testable behaviours
| Behaviour | Test |
|---|---|
| Lambda completes within timeout under prod load | Run k6 / Lambda Test against deployed function |
| Graceful return via remaining-time check | Inject artificial slowness; verify handler returns "partial" not 504 |
| API Gateway 29s budget honoured | Test long-running endpoint via API GW URL; assert ≤ 29s |
| SQS visibility-timeout > Lambda timeout | Force a timeout; observe re-delivery from SQS |
| Memory tuning sweet spot found | Run at 256/512/1024/2048 MB; chart duration |
| Cost at p99 within budget | Latency × memory × invocations × price-per-GB-s |
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Lambda timeout = max (900s) for "safety" | Stuck Lambdas burn 15min before failing; concurrent-execution limits hit | Match timeout to actual p99 + buffer |
| Lambda timeout > API Gateway timeout | API GW kills first; Lambda runs unused | Timeout < 29s for API GW |
| SQS visibility-timeout < Lambda timeout | Message re-delivered while in-flight → duplicate processing | Visibility > Lambda timeout × 6 (AWS recommendation) |
No get_remaining_time_in_millis() check | Force-kill at timeout; no progress saved | Always check + early-return |
| Sizing memory by RAM need only | Compute-bound work wastes time | Tune by p95 duration |
| Treating init time as billed | Out of date | Per current AWS docs, init is free |
| Cost calculation ignoring p99 | "It's $5/million on average" but p99 spikes blow budget | Calculate against p99 not avg |
Limitations
References
Related skills
aws-sam-local-testing
Wraps AWS SAM (Serverless Application Model) Local CLI for testing Lambda functions locally: `sam local invoke` (single invocation with event payload), `sam local start-api` (local API Gateway emulator), `sam local start-lambda` (local Lambda invoke endpoint for AWS SDK clients), and event-payload generation (`sam local generate-event`). Use when testing Lambda + API Gateway + integrated AWS services locally.
azure-functions-tests
Runs Azure Functions locally using Azure Functions Core Tools v4 (`func start`), Azurite storage emulation, and framework-native unit tests for handler code (.NET isolated worker model, Node.js v4, Python v2). Covers HTTP, queue, and timer trigger testing, admin-endpoint invocation for non-HTTP triggers, and binding verification via local.settings.json. Use when testing Azure Functions before deployment, reproducing trigger behaviour without live Azure services, or gating function handler logic in CI.
cloudflare-workers-miniflare
Wraps Miniflare 3 (the official Cloudflare Workers simulator) and Wrangler dev for testing Workers locally. Covers Miniflare's getMiniflare() programmatic API (workerd-backed simulation matching prod), the wrangler dev local-mode (live-reload during dev), KV / Durable Objects / R2 / D1 bindings emulation, and Vitest + @cloudflare/vitest-pool-workers for in-process tests. Use when testing Cloudflare Workers code locally.
cold-start-budget-reference
Pure-reference catalog of cold-start budgets across serverless runtimes. Covers AWS Lambda's three-phase cold start (Init: download+unzip+runtime-bootstrap; Init code: imports + module load; Invoke: handler execution), Cloudflare Workers' isolate model (sub-millisecond cold starts via V8 isolates per developers.cloudflare.com), Vercel Edge Runtime, Lambda SnapStart for JVM (snapshot-restore for Java), and provisioned-concurrency trade-offs. Includes per-runtime typical cold-start ranges and the testable behaviours each model creates. Use when designing latency budgets, choosing a runtime, or auditing cold-start variance in production.
lambda-test-tools-net
Wraps Amazon.Lambda.TestTool (the canonical .NET Lambda local-testing toolkit from github.com/aws/aws-lambda-dotnet) for invoking Lambda handlers from xUnit / NUnit tests with simulated AWS Lambda contexts (ILambdaContext, ILambdaSerializer). Covers handler-direct invocation, mock context fixtures, the dotnet-lambda CLI, and integration with the .NET LambdaSerializer for JSON. Use when testing AWS Lambda functions written in C#/.NET.
netlify-functions-tests
Wraps Netlify Functions testing patterns: Netlify Dev (`netlify dev`) for local routing emulation, the @netlify/functions handler API testing pattern, Netlify Edge Functions (Deno runtime) vs Background Functions (Lambda under the hood) distinction, and scheduled-function (cron) test patterns. Use when testing Netlify Functions or Edge Functions.
serverless-framework-test-plugin
Wraps the Serverless Framework (serverless.com) test ecosystem: serverless-offline (local HTTP emulator), serverless-jest-plugin / serverless-mocha-plugin (per-runtime test runners), and the `serverless invoke local` CLI for one-off invocations. Use when testing Lambda functions deployed via the Serverless Framework.
serverless-integration-test-builder
Workflow-driven skill that builds the integration-test suite for a serverless application from its IaC definition (SAM template / serverless.yml / Wrangler config / Vercel functions / Netlify functions). Walks through: identifying the function inventory + event sources, picking the right local-emulator per function (sam local / Miniflare / netlify dev / vercel dev / serverless-offline), generating test events per event source, asserting on cold-start + timeout budgets, and emitting the test directory + CI config. Use when introducing integration tests to a serverless project.
vercel-edge-runtime-testing
Wraps Vercel Edge Runtime testing patterns: the @edge-runtime/jest-environment + edge-runtime CLI for executing Web-Standard APIs (Request / Response / fetch) in jest tests, the `vercel dev` local emulator for full route testing, and the Edge vs Node Function divergence (no fs, no Buffer; Request / Response only). Covers the 30s Edge function timeout per vercel.com/docs. Use when testing Vercel Edge Functions or middleware.