Tacnode™
Glossary
Data Consistency

What Is Idempotency?

Idempotency is the property of an operation that can be applied multiple times without changing the result beyond the initial application. In mathematics, a function f is idempotent when f(f(x)) = f(x). In distributed systems and APIs, an idempotent operation produces the same effect on the system whether it runs once or several times, which makes it safe to retry after a timeout or network failure.

Updated

What is idempotency?

The word comes from Latin idem ("the same") and potens ("power") — literally "having the same power." The mathematician Benjamin Peirce coined it in the 1870s to describe algebraic elements that equal their own square: x · x = x. Familiar examples are the absolute value function (abs(abs(x)) = abs(x)) and projection operations, which have no further effect once applied.

Software engineering borrowed the term to solve a problem of unreliable networks. When a client sends a request and the connection drops, the client cannot tell whether the request was lost before it arrived or the response was lost after the work completed. The only safe recovery is to retry — but a blind retry of a non-idempotent operation ("charge the card $50") can execute the side effect twice. Idempotency is what makes retries safe.

Operations become idempotent in two ways. Some are naturally idempotent: setting a value (status = "shipped"), deleting a record, or acquiring a state that is absolute rather than relative. Others are made idempotent through deduplication: the caller attaches a unique identifier, and the server refuses to apply the same identifier twice. Increments, appends, and payments fall in this second group.

How idempotency works

HTTP defines idempotency at the method level (RFC 9110): GET, HEAD, PUT, DELETE, OPTIONS, and TRACE are idempotent; POST and PATCH are not. Note that idempotent refers to the effect on server state, not the response — a first DELETE may return 204 and a retry 404, yet the server ends in the same state either way.

Because payments and order creation are usually POST, payment APIs layer on idempotency keys. The client generates a unique key per logical operation and sends it with every retry of that operation:

text
POST /v1/payments
Idempotency-Key: 8f3c9d2a-1b4e-4c7a-9e6f-2d5b8a1c3e70

{ "amount": 5000, "currency": "USD", "source": "card_123" }

On first sight of the key, the server records it, executes the charge, and stores the response. Any retry carrying the same key returns the stored response without charging again. Two details matter in practice: the key must be persisted atomically with the side effect (typically via a unique constraint, so two concurrent retries cannot both pass the "have I seen this key?" check), and keys are usually retained for a bounded window — long enough to cover realistic retry horizons.

The same principle governs message processing. Brokers such as Kafka and SQS provide at-least-once delivery, so consumers will occasionally see duplicates. An idempotent consumer either deduplicates by event ID or uses idempotent writes (an upsert keyed on the event, rather than a blind increment). What vendors market as "exactly-once processing" is, in practice, at-least-once delivery combined with idempotent handling: the operation may be attempted more than once, but its observable effect lands exactly once.

Why idempotency matters in real-time systems

Retries and redelivery are not edge cases in event-driven architectures — they are the normal behavior of the delivery guarantees those systems are built on. Any pipeline that maintains derived state from an event stream (velocity counters, running exposure totals, session aggregates) inherits the duplicate problem: if a consumer increments a counter once per delivered event rather than once per unique event, redelivery silently inflates the derived value. A downstream decision that reads the counter then acts on state that never happened.

Concurrency raises the bar further. It is not enough for a handler to check "have I processed this before?" and then act, because two retries of the same request can be in flight simultaneously and both pass the check — a classic race condition. Effective idempotency is enforced atomically at the storage layer (unique keys, conditional writes), not in application logic alone. This interaction between duplicate suppression and concurrent execution is examined in context under concurrency.

Idempotency is therefore a correctness precondition for real-time decisioning: it guarantees that retries don't corrupt state. It does not, by itself, guarantee that state is fresh — a deduplicated counter can still lag the events it summarizes.

FAQ

Related terms

Further reading