All posts
Internet Fundamentals

Timeouts, Retries and Idempotency: The HTTP Habits That Stop Double Charges

By

October 26, 2026

6 min read

Every network call ends in success, failure or "we don't know". The third causes duplicate orders, double charges and stuck jobs. How status codes, timeouts, retries with backoff and idempotency keys fit together, with the limits on API Gateway and Lambda.

Internet Fundamentals
HTTP
APIs
Reliability
Idempotency

When a request times out, you do not know whether the server did the work. Retrying might do it twice; not retrying might never do it. Each habit below exists to make that third outcome safe.

Status codes, briefly

Response

Meaning

Retry?

2xx

It worked

No

4xx

The request is wrong: bad input (400), not signed in (401), not allowed (403), not found (404)

No, except 408 and 429

429 Too Many Requests (RFC 6585)

Rate limited; Retry-After may say when to try again

Yes, after waiting

5xx

The server or something behind it failed

Usually, if the request is safe to repeat

Timeout or reset connection

Unknown

Only if the request is safe to repeat

Which requests are safe to repeat

HTTP defines GET, PUT and DELETE as idempotent: sending one twice has the same effect as once (RFC 9110). POST is not, and POST is what creates orders, sends messages and charges cards. To make a POST safe to retry, give it an idempotency key.

Want a second opinion on this for your system?

Book a free 30-minute call. You'll leave knowing what we'd do first and roughly what it costs, whether or not you hire us.

Idempotency keys

  1. The client generates a unique key, such as a UUID, per operation (one checkout, not one HTTP attempt) and sends it in a header, conventionally Idempotency-Key.

  2. The server stores the key with the result the first time it does the work.

  3. A retry with the same key gets the stored result instead of doing the work again.

Stripe works this way: every POST accepts an Idempotency-Key of up to 255 characters, retries get the saved response, keys may be pruned after 24 hours, and reusing a key with different parameters is an error. Do the same on your own endpoints that create things, and pass keys through to every provider that accepts them.

Timeouts

Set one on every outbound call; many HTTP clients will wait far longer than your user. In JavaScript, pass AbortSignal.timeout(ms) to fetch. Each layer's timeout should be shorter than the one above it, or the outer layer gives up while the inner one is still working.

Layer

Limit

API Gateway REST API

29 seconds by default; Regional and private APIs can raise it, possibly at the cost of a lower account throttle quota

API Gateway HTTP API

30 seconds maximum

API Gateway WebSocket API

29 seconds per integration call

Lambda

15 minutes per invocation

Retries

  • Retry only idempotent requests or ones carrying an idempotency key.

  • Back off exponentially with random jitter, so thousands of clients do not retry in lockstep and flatten a recovering service.

  • Cap attempts, and retry at one layer only. Three layers of three attempts is 27 calls.

  • Honour Retry-After on 429 and 503.

hoolco Monthly Review

Once a month: what changed in tech that month and what it means for you, from cloud and AI to security and the tools you build with. Every item links to its source. No sales pitch, unsubscribe in one click.

As of October 26, 2026. Provided as is, for general information, and accurate to the best of our knowledge on the date shown. Not legal, compliance, tax, financial or other professional advice. Prices, limits and vendor services change; check current vendor documentation before relying on anything here. Terms of use.