🔥 Firehook

Blog · api rest

Idempotency and retries in REST APIs

Avoid duplicate actions with idempotency keys, safe retries, and clear client/server rules.

API gateway with looping path, symbolizing idempotent retries

Why idempotency matters

Networks are unreliable. Timeouts and retries happen even in well-designed systems. Without idempotency, a retry can duplicate actions like payments or orders.

Idempotency means repeating a request produces the same effect. It is the safety mechanism for modern APIs.

HTTP methods and semantics

GET is idempotent because it does not change state. PUT and DELETE are defined as idempotent, meaning repeated calls lead to the same final state.

POST is not idempotent by default. If you want safe retries for POST, you must design for it explicitly.

Idempotency keys

Idempotency keys are unique tokens sent with a request. The server stores the first response and replays it for subsequent requests with the same key.

This prevents accidental double charges or duplicate records when clients retry.

Safe retry rules

Clients should retry only when the operation is safe. If a request can cause side effects, require an idempotency key or avoid automatic retries.

Servers should return clear errors so clients know whether a retry is appropriate.

Timeout ambiguity

Timeouts are tricky because the client does not know whether the server processed the request. Idempotency keys remove that ambiguity.

If keys are not possible, provide a status endpoint so clients can check whether the operation completed.

Storage and expiration

Idempotency requires storage. Define a retention window that balances safety and cost.

Expiring too early risks duplicates; storing too long increases storage usage.

Concurrency and race conditions

Two identical requests can arrive simultaneously. Your implementation must ensure only one side effect occurs.

Use locks, unique constraints, or transactional checks to guarantee correctness.

FAQ

Which HTTP methods are idempotent by default?
GET, PUT, and DELETE are considered idempotent. POST is not, unless you design it to be.
When should I use idempotency keys?
Use them for actions that create or charge resources where duplicate requests are dangerous.
How long should idempotency keys be stored?
Long enough to cover typical retry windows, often hours to days depending on your system.
Should clients retry on 500 errors?
Only if the operation is safe or idempotent. Otherwise, clients risk duplicating side effects.
Do I need idempotency for PATCH?
Not always, but for financial or critical actions, idempotency is valuable.