knowbase

# Stripe API returns 429 Too Many Requests

Stripe returns 429 for two unrelated reasons: you exceeded a rate or concurrency limit, or you hit an object lock timeout. The Stripe-Rate-Limited-Reason header tells you which, and only one of them is fixed by slowing down.

Summary: Stripe API returns 429 Too Many Requests
Error429 Too Many Requests
Applies toStripe API all versions · Stripe SDKs all officially maintained SDKs
Primary causeAccount-wide request rate exceeded
First checkcurl -si https://api.stripe.com/v1/charges -u "$STRIPE_SECRET_KEY:" | grep -i 'stripe-rate-limited-reason\|^HTTP'
Confidencehigh3 sources, 3 primary
Verified2026-08-07fresh0d old · recheck by 2026-12-05
Domainapistripe rate-limiting http-429 retry backoff idempotency

## Error

429 Too Many Requests

Codes: 429lock_timeout

Also seen as: Stripe rate limit exceeded · Request rate limit exceeded stripe · This object cannot be accessed right now because another API request or Stripe process is currently accessing it · stripe RateLimitError

## Problem

Requests to the Stripe API intermittently fail with HTTP 429. Retrying immediately makes it worse, and the failures often cluster around batch jobs, migrations, or traffic spikes. Because Stripe overloads 429 for both rate limiting and object lock contention, integrations that treat every 429 as "send fewer requests" fix only half of their failures.

## Root Cause5 known causes, ranked

  1. 01

    Account-wide request rate exceeded

    primary

    Stripe applies a global per-account limit of 100 requests/second in live mode and 25 requests/second in a sandbox. Bulk operations breach this long before any single endpoint's limit.

    → how to tell: Response carries Stripe-Rate-Limited-Reason: global-rate

  2. 02

    Per-endpoint request rate exceeded

    common

    Individual endpoints are limited to 25 requests/second unless documented otherwise, so a loop hammering one endpoint trips this while total account traffic still looks low.

    → how to tell: Response carries Stripe-Rate-Limited-Reason: endpoint-rate

  3. 03

    Concurrency limit exceeded

    common

    Concurrency counts requests in flight at one moment rather than per second. Long-running list requests and requests using `expand` are the usual trigger.

    → how to tell: Stripe-Rate-Limited-Reason is global-concurrency or endpoint-concurrency

  4. 04

    Object lock timeout, not a rate limit

    common

    Stripe locks an object during some mutations. Concurrent writes to the same object time out waiting for that lock and return 429 with code `lock_timeout`. Throttling global throughput does not help; serialising writes per object does.

    → how to tell: 429 with error code lock_timeout and no Stripe-Rate-Limited-Reason header

  5. 05

    Resource-specific limits on a hot object

    edge

    Some resources have their own quotas, such as 1000 PaymentIntent updates per object per hour, or 10 new invoices per subscription per minute.

    → how to tell: Stripe-Rate-Limited-Reason: resource-specific

## Solution

  1. 01Read the Stripe-Rate-Limited-Reason response header before doing anything else. It names the exact limit you hit and separates true rate limiting from a lock timeout.
    $ curl -si https://api.stripe.com/v1/charges -u "$STRIPE_SECRET_KEY:" | grep -i 'stripe-rate-limited-reason\|^HTTP'

    note: A 429 with no such header and error code lock_timeout is contention on a single object, not throughput.

  2. 02For genuine rate limiting, retry on an exponential backoff schedule with randomised jitter so retrying clients do not resynchronise into a thundering herd.
    javascript
    // Retry only on rate limiting; never blind-retry a write without an idempotency key.
    async function withBackoff(fn, { attempts = 5, base = 200 } = {}) {
      for (let i = 0; i < attempts; i++) {
        try {
          return await fn();
        } catch (err) {
          const retriable = err.statusCode === 429 || err.type === 'StripeConnectionError';
          if (!retriable || i === attempts - 1) throw err;
          const delay = base * 2 ** i * (0.5 + Math.random());
          await new Promise((r) => setTimeout(r, delay));
        }
      }
    }
    
  3. 03Attach an idempotency key to every retried write so a retry after a timeout cannot create a second charge or customer.
    javascript
    await stripe.paymentIntents.create(
      { amount: 2000, currency: 'usd' },
      { idempotencyKey: `pi-${orderId}` }
    );
    
  4. 04Cap outbound throughput client-side with a token bucket rather than discovering the ceiling through 429s. Budget against 100 rps account-wide and 25 rps per endpoint.
  5. 05For lock_timeout, queue mutations so that writes to the same object run sequentially. Concurrency across distinct objects is fine.
  6. 06Do not load test against a sandbox. Sandbox limits are 25 rps versus 100 rps in live mode, so the test hits ceilings production never would.

verify · Re-run the workload and confirm 429s drop to zero while throughput stays under 100 rps; any remaining 429 should carry error code lock_timeout, pointing at object contention rather than volume.

if that fails · If legitimate payment traffic genuinely exceeds the published limits (for example a flash sale), contact Stripe Support ahead of the event rather than engineering around the limit.

## Applies To

Stripe API
all versionsLimits are per Stripe account, not per API key or API version.
Stripe SDKs
all officially maintained SDKsOfficial SDKs auto-retry 429s caused by lock timeouts, but not 429s caused by rate limiting.
Platforms
live mode, sandbox

## Not Applicable Tonear misses this page does not answer

  • 429 responses produced by your own API gateway, CDN, or reverse proxy rather than by Stripe
  • 402 card decline errors, which indicate a payment failure and must not be retried blindly
  • 403 responses caused by an API key lacking permissions

## Evidence3 sources

  1. 01official-docsStripe API rate limits

    https://docs.stripe.com/rate-limits

    Stripe · read 2026-08-07

    supports: The 100 rps live / 25 rps sandbox global limits, the 25 rps per-endpoint default, the Stripe-Rate-Limited-Reason header values, the lock_timeout distinction, and the exponential-backoff-with-jitter recommendation.

    If you exceed the limits, you get 429 Too Many Requests HTTP status responses.

  2. 02official-docsIdempotent requests

    https://docs.stripe.com/api/idempotent_requests

    Stripe · read 2026-08-07

    supports: That retried write requests must carry an idempotency key to avoid duplicate side effects.

    The API supports idempotency for safely retrying requests without accidentally performing the same operation twice.

  3. 03official-docsError handling

    https://docs.stripe.com/error-handling

    Stripe · read 2026-08-07

    supports: The error taxonomy that separates rate limit errors from card errors and invalid request errors, which determines what is safe to retry.

    You made too many API calls in too short a time.

## Confidence

highEvery numeric limit, header value, and retry recommendation comes verbatim from Stripe's own rate limit reference rather than from community write-ups. The one claim not stated as a number in the docs is the code example itself, which is illustrative.

https://knowbase.sh/k/stripe-429-rate-limit