Learn
Idempotency · Software systemsgrowing

Idempotency

Idempotency

Last updated
Jul 16, 2026
Relationships
6

Mental model

The same intent may be delivered many times; the system creates the business effect once and replays that outcome to retries.

Visual memory card

The pattern, in one image.

A compact visual makes the pattern easier to recognize when it appears in a different example.

Download full-resolution card
Three paper receipts with the same order ID converge into one completed receipt, illustrating repeated attempts producing one business effect.

01 · Unknown-outcome lab

The charge succeeded. The response disappeared.

The client has no proof of success or failure. Step through its retry with and without a stable identity for the business intent.

1 / 4 · Ready
CLIENT

A $42 payment is ready to send.

SERVICE

No request has arrived.

LEDGER

No payment record.

One intent is waiting to begin.

02 · Key contract

A key is useful only when the uncomfortable cases have rules.

Choose a case. The important design work happens around identity, atomic ownership, concurrency, and time.

REQUESTSame caller · same key · same parameters
DECISIONLook up the completed record and do not run the effect again.
RESULTReplay the original or a semantically equivalent result.

A retry is recognized by intent, not by arrival count.

03 · Operation judgment

First ask whether the operation can converge by itself.

Natural idempotency is simpler than a ledger. Relative changes and external effects need an explicit protocol.

SET status = PAIDNaturally idempotent

Every repetition converges to the same named state.

DELETE document 42Naturally idempotent

Responses may differ, but the resource remains absent.

POST create paymentNeeds an intent key

A repeated creation is a new charge unless retries share identity.

balance = balance + 10Not naturally idempotent

Every execution changes the state again.

04 · Concept neighborhood

Do not confuse recovery, detection, delivery, and effect.

They work together, but each answers a different question. The relationship type is the useful part.

Retryrecovery policy
Retry

When should another attempt be made, and with what backoff?

Idempotency Keyrequest identity
Idempotency Key

Which attempts express the same business intent?

Deduplicationdetection mechanism
Deduplication

How are repeated deliveries detected or suppressed?

At-least-oncedelivery guarantee
At-least-once Delivery

May a message arrive more than once so it is less likely to be lost?

Outboxconsistency pattern
Transactional Outbox

How is a database change coupled to eventual message publication?

Exactly-oncestronger guarantee
Exactly-once Processing

Can a scoped effect appear once even when delivery and execution repeat?

Idempotency

Idempotency solves the hardest kind of distributed-system failure: not a clear success or failure, but an unknown outcome.

A client sends a payment request. The server charges the card, but the response disappears on the network. The client sees a timeout. If it gives up, a payment that should complete may look failed. If it retries blindly, the customer may be charged twice.

An idempotent contract separates recovery from duplication: the request may be attempted again, but the same business intent does not create the business effect again.

A restaurant ticket

Imagine handing ticket A-842 to a kitchen and hearing no confirmation. You hand over the same ticket again.

  • Without an order number, the kitchen may cook two meals.
  • With a stable order number, it finds A-842 and returns the existing order status.
  • A genuinely new meal needs a new number.
  • Reusing A-842 with a different dish should be rejected, not guessed.

The ticket is only an identifier. The kitchen still needs a reliable ledger, and recording the number cannot be separated from accepting the order by an unsafe gap.

Mathematical and system meaning

An idempotent function satisfies:

f(f(x)) = f(x)

In software systems, the useful definition is semantic: making the same request multiple times has the same intended effect as making it once. It does not require byte-identical responses or forbid extra logs, metrics, and timestamps.

For example, the first DELETE /documents/42 might return 204 and the second 404. The responses differ, but the intended state — document 42 is absent — has converged.

Two ways to get idempotency

Make the operation naturally idempotent

State assignment tends to converge:

SET order.status = "PAID"     repeated → still PAID
DELETE document 42            repeated → still absent
PUT /profile { name: "Li" }   repeated → same representation

Relative changes usually do not:

balance = balance + 10
toggle subscription
send welcome email
create a new charge

This gives a practical first question: can “change it again” be rewritten as “make it equal to this state”?

Add an Idempotency Key

Creating a payment, booking, or cloud resource cannot always be reduced to a simple assignment. The client can instead generate one stable key for one business intent and reuse it for every retry.

Idempotency-Key: order-842-payment
POST /payments { amount: 42, currency: "CAD" }

A complete protocol normally needs to:

  1. use one key for one intent, and a new key for a new intent;
  2. scope the key by caller, account, and operation;
  3. reserve it atomically with a unique constraint or transaction;
  4. bind it to a request fingerprint so changed parameters are rejected;
  5. record whether the operation is processing, complete, or failed;
  6. replay the stored or semantically equivalent result to a completed duplicate;
  7. define what a concurrent duplicate sees; and
  8. declare the TTL (Time to Live) after which the key may be treated as new.

The atomicity gap is the real danger

This implementation has a race:

if key does not exist:
  charge_card()
  save(key, result)

Two concurrent requests can both observe a missing key and both charge. The service can also crash after charging but before saving the record, leaving a retry indistinguishable from a new request.

Key reservation, business state transition, and result recording should share one atomic boundary where possible. If the effect crosses a database, queue, email provider, or external payment service, each boundary needs its own idempotency strategy — often a state machine, Transactional Outbox, or consumer Inbox.

A header without an atomic state machine is decoration, not a guarantee.

Four cases the contract must name

A completed duplicate

Return the first recorded result or a semantically equivalent current result. Do not execute the business action again.

The same key with different parameters

Reject it. Otherwise the service cannot know whether it received a retry or a mistakenly reused key. Stripe and Amazon Elastic Compute Cloud (Amazon EC2) both treat parameter mismatch as an error.

A concurrent duplicate

The second request must not also begin the effect. It can wait, receive an in progress response, or get a conflict; the API (Application Programming Interface) contract must choose.

An expired key

Idempotency memory is usually bounded. Once the record is pruned, the same key may execute again. The server's guarantee window must cover the client's maximum retry horizon.

HTTP: safe is not the same as idempotent

HTTP (Hypertext Transfer Protocol) distinguishes safe methods from idempotent methods.

MethodSafe?Idempotent by semantics?Meaning
GETyesyesRequests a read and should not ask for a state change.
PUTnoyesReplaces the target with a representation; repeats converge.
DELETEnoyesChanges state once, but repeated deletion has the same intent.
POSTnono, by defaultOften means “create another”; needs a business-level contract.

An operation can therefore be state-changing and idempotent. Idempotent does not mean harmless or read-only.

Know the neighboring concepts

  • Retry is a recovery policy. It controls timeouts, attempt limits, exponential backoff, and jitter. Idempotency makes those attempts safe for the business effect.
  • Deduplication is a detection mechanism. It may be used to implement idempotency, but the semantic contract is broader than dropping duplicates.
  • At-least-once delivery is a delivery guarantee. It can repeat messages, so consumers need idempotent handling.
  • Exactly-once is a stronger and often misleading claim. Idempotency does not prevent repeated delivery or execution; it makes a scoped effect converge as if it happened once.
  • Optimistic Concurrency Control (OCC) protects against stale writes. OCC distinguishes competing intentions; idempotency recognizes another delivery of the same intention.
  • Transactional Outbox closes a cross-system consistency gap. It still expects duplicate publication and therefore an idempotent consumer.

What it does not solve

  • It does not prevent retry storms; use bounded attempts, backoff, jitter, rate limits, and circuit breaking.
  • It does not automatically cross databases, queues, emails, and third-party APIs.
  • It does not prevent two different keys from racing for the same inventory.
  • It does not decide whether an API should cache and replay a first 500 response.
  • It does not create global exactly-once processing.

Remember these five things

  1. Idempotency is a response to unknown outcomes: retry the attempt without repeating the intent's effect.
  2. Prefer naturally idempotent state assignment when the domain permits it.
  3. One intent gets one key; retries reuse it; a new intent gets a new key.
  4. Reject the same key with changed parameters, and define concurrent and expired-key behavior.
  5. The most dangerous bug lives in the non-atomic gap between the side effect and its idempotency record.

Self-test

  1. If the payment committed but its response vanished, what evidence makes a retry safe?
  2. Does your key identify a business intent, or only hash a payload?
  3. What happens when the same key carries a different amount?
  4. Which request wins when two duplicates arrive concurrently?
  5. Does the key's lifetime cover the client's longest retry horizon?

Further reading

Relationships

Concept neighbors

Retry

recovery policy

Retry

Decides when and how another attempt is made; idempotency decides whether that attempt can repeat the business effect.

Idempotency Key

request identity mechanism

Idempotency Key

Names one business intent so every retry can be recognized as the same operation.

Deduplication

duplicate detection mechanism

Deduplication

Detects or suppresses repeats; one possible mechanism for delivering idempotent behavior.

At-least-once Delivery

delivery guarantee

At-least-once Delivery

May deliver a message repeatedly, requiring an idempotent consumer to absorb duplicates safely.

Transactional Outbox

consistency pattern

Transactional Outbox

Bridges a database change and message publication without an unsafe gap, while consumers still handle duplicates.

Exactly-once

stronger guarantee

Exactly-once Processing

A frequently overclaimed end-to-end guarantee; idempotency usually converges the effect rather than preventing repeated delivery or execution.

Evidence trail

Primary sources

Subscribe to my newsletter

I build with AI and write about what works. Subscribe to get new posts delivered.

No tracking. No spam. Pure content.

© 2020-2026 Aaron Guo