manus-skills/.kortix/opencode/skills/coding/aws-serverless/references/concurrency.md
zhukang 1c7abd81d1 All 310 Manus skill-hub community skills as a Kortix marketplace registry
- 310 registry:skill items, 1528 files, 7 categories (hub tags)
- registry.json generated by @kortix/registry buildRegistry
- nested SKILL.md in sn-da-* renamed SUBSKILL.md (no phantom skills)
- provenance + licenses: SOURCES.md
2026-09-15 13:37:20 +08:00

5.6 KiB
Raw Permalink Blame History

Lambda Concurrency Controls

Four concurrency controls operate at different levels with non-obvious interactions. The exact numbers and mutual-exclusivity rules below are the part that's easy to get wrong.

The 4 concurrency types

  1. Reserved Concurrency (scope: function) — sets the max concurrent instances AND reserves that capacity from the account pool. Setting to 0 fully throttles the function (emergency shutoff). Use to protect critical functions, cap to protect downstream, or kill-switch.

  2. Provisioned Concurrency (scope: published version or alias — NOT $LATEST) — pre-initializes environments so they're ready before requests arrive. Spills to on-demand (with cold starts) beyond the provisioned count. Combine with Application Auto Scaling (~70% target). Paid even when idle.

  3. Maximum Concurrency (scope: per SQS ESM, range 2–1,000) — caps how many concurrent instances one SQS ESM can invoke. Does not reserve anything; other triggers can still consume function concurrency.

  4. Provisioned Mode — ESM (SQS and Kafka/MSK) — allocates dedicated event pollers for an SQS/Kafka ESM with configurable min/max. Per-poller capacity is an OR envelope and differs by source: SQS = 1 MB/s or 10 concurrent invokes; Kafka/MSK = 5 MB/s or 5 concurrent invokes. Use for high-throughput or spiky traffic where standard ramp-up (5 → +300/min) is too slow.

Key numbers and interactions

  • Account RPS quota = 10 × account concurrency (e.g. 1,000 concurrency → 10,000 RPS, across all functions). This is an account quota, not a per-instance cap. Per-instance throughput = 1 / function duration.
  • Max reservable = account limit − 100. Lambda always keeps 100 unreserved.
  • Scaling rate: 1,000 new environments / 10s, per function
  • Provisioned ≤ Reserved when both are set (reserved is the ceiling).
  • Provisioned counts against the account limit even when idle — monitor ClaimedAccountConcurrency.
Combination OK? Notes
Reserved + Provisioned Yes Provisioned ≤ Reserved
Reserved + Maximum Concurrency (ESM) Yes Reserved ≥ Σ(Maximum Concurrency across ESMs)
Provisioned + Maximum Concurrency / Provisioned Mode (ESM) Yes Different layers
Maximum Concurrency + Provisioned Mode (same ESM) No Mutually exclusive
Provisioned Concurrency + SnapStart No Mutually exclusive

At the limit: Sync → 429. Async → retries up to 6h then DLQ. Streams → polling throttled, messages stay in source.

RPS gotcha: a 50ms function at 20,000 RPS needs only 1,000 concurrency, but the RPS limit (10×1,000 = 10,000) throttles it. Request account concurrency = 2,000.

aws service-quotas request-service-quota-increase \
  --service-code lambda --quota-code L-B99A9384 --desired-value 5000

Decision scenarios

Scenario Reserved Provisioned Maximum Concurrency (ESM) Prov Mode (ESM)
Protect critical API / cap downstream Yes — — —
Eliminate cold starts (user-facing API) Optional Yes — —
Multiple SQS queues, prevent hogging Yes — Yes —
High-throughput SQS, low-latency Optional Optional — Yes
Kafka/SQS ESM with spiky traffic — — — Yes
Predictable daily traffic — Yes + AutoScale — —
Emergency shutoff Yes (=0) — — —

Common mistakes

  1. Reserved = 0 left over from an incident — blocks ALL invocations (429). If a function throttles at low traffic, check this first.
  2. Reserved too low — reserve 50, need 80 → throttled at 51 even with spare account capacity.
  3. Starving other functions — reserved is subtracted even when unused; be conservative.
  4. Provisioned without auto scaling — paying for idle off-peak, spilling on-peak.
  5. Provisioned on $LATEST — doesn't work; publish a version, create an alias.
  6. Maximum Concurrency > reserved — ESM tries 100, function caps at 50. Ensure reserved ≥ Σ(Maximum Concurrency).
  7. Confusing ESM Maximum Concurrency with reserved — Maximum Concurrency reserves nothing; API Gateway can still consume all concurrency.
  8. Forgetting the 100-unit buffer — max reservable = account limit − 100.

SnapStart vs Provisioned Concurrency

Mutually exclusive on the same function.

Runtime Java 11+ / Python 3.12+ / .NET 8+
├─ No  → Provisioned Concurrency
└─ Yes
   ├─ Need guaranteed <50ms on EVERY request? → Provisioned Concurrency
   ├─ Need EFS or >512MB ephemeral storage?   → Provisioned Concurrency
   └─ Otherwise → SnapStart first; if P99 still too high, switch (they cannot coexist)

SAM/CDK property reference

Type SAM CDK
Reserved ReservedConcurrentExecutions reservedConcurrentExecutions
Provisioned AutoPublishAlias + ProvisionedConcurrencyConfig.ProvisionedConcurrentExecutions new lambda.Alias({ provisionedConcurrentExecutions }) (alias, not $LATEST)
Maximum Concurrency (ESM) ScalingConfig.MaximumConcurrency maxConcurrency on EventSourceMapping
Provisioned Mode (ESM) ProvisionedPollerConfig.MinimumPollers / MaximumPollers provisionedPollerConfig: { minimumPollers, maximumPollers }
SnapStart SnapStart.ApplyOn: PublishedVersions + AutoPublishAlias snapStart: lambda.SnapStartConf.ON_PUBLISHED_VERSIONS

Auto scaling: alias.addAutoScaling({ minCapacity, maxCapacity }) then scaling.scaleOnUtilization({ utilizationTarget: 0.7 }).