Explainstuff.mebeta
All concepts
Basicsbeginner7 min

Idempotency

Make an operation safe to repeat: running it twice leaves the system in the exact same state as running it once.

Imagine pressing the elevator call button. You press it once, then press it three more times because the car is slow — but the elevator still arrives exactly once. The extra presses change nothing. That property, where repeating an action gives the same result as doing it a single time, is called idempotency, and it turns out to be one of the most important ideas for building systems that behave correctly when things go wrong.

The problem

Out in the real world, the network is unreliable. A client sends a request, the server processes it, and then the response gets lost on the way back. The client never hears 'success', so it does the sensible thing and retries — and now the same request has arrived twice. The same thing happens with messaging systems that promise at-least-once delivery: to guarantee a message is never lost, they may deliver it more than once.

For a read this is harmless, but for an action that changes something it can be a disaster. Picture an operation like 'charge the customer's card $50'. Run it once and you bill them correctly; run it twice because of a retry and you've double-charged them. The duplicate wasn't a bug in your logic — it was a duplicate delivery — but the customer is angry all the same.

How it works

An operation is idempotent if performing it any number of times has the same effect as performing it exactly once. The trick is in how the operation describes its change. Compare two ways to update a counter: x = 5 simply sets the value, so no matter how many times you run it, x ends up at 5. But x += 1 increments, so each run pushes the value higher — run it twice and you get 7 where you wanted 6.

The animation below makes this concrete. Watch the same request get sent twice to a server that stores a single value. On the first call, the stored state moves from 0 to 1. When the retry arrives, the server recognizes it and the value stays at 1 — the second delivery changes nothing, exactly as if it had never happened.

The same request, twice
request
Client
API
Database
value
0
An idempotent request, sent twice, changes the result only once.
Note

Idempotent is not the same as 'no side effects'. An idempotent operation is allowed to do something — write to a database, send a confirmation — it just has to be safe to repeat. The promise is about the end state being identical, not about the operation doing nothing.

Idempotency in HTTP

The web's design leans on this idea, and the HTTP methods are a great cheat sheet. GET just reads data, so calling it repeatedly is naturally idempotent. PUT replaces a resource with a given value — like setting x = 5 — so two identical PUTs leave the resource in the same place. DELETE is idempotent too: deleting something that's already gone still leaves it gone.

POST is the odd one out. It usually means 'create a new thing', so each call creates another one — submit a form twice and you may get two orders. That's why POST is the method you most often have to protect against duplicates, which leads us to the practical tools.

Making operations idempotent

When an operation isn't naturally repeatable, you can add idempotency yourself. A few reliable techniques:

  • Idempotency keys (request IDs) — the client attaches a unique ID to the request. The server records which IDs it has already processed; if a duplicate arrives, it skips the work and returns the original result. This is exactly how payment APIs prevent double-charges on a retry.
  • Upserts — instead of a separate 'insert' that fails on the second try, use an 'insert-or-update' that converges to the same row no matter how many times it runs.
  • Prefer 'set' over 'add' — design the operation to declare the desired end state ('set the balance to 100') rather than a relative change ('add 100'). A 'set' is safe to repeat by construction.
Tip

Idempotency is what makes retries safe. Without it, a retry is a gamble between losing the request and duplicating it. With it, you can retry as aggressively as you need and trust the result — which is precisely why it pairs so well with circuit breaker retry logic.

When it matters

Idempotency matters anywhere a request can be delivered or processed more than once — which, given unreliable networks and at-least-once messaging, is almost everywhere. It is essential for safe retries, for consuming events from a queue, and for any payment, booking, or order flow where a duplicate has real-world cost.

It also fits naturally with statelessness: when a server keeps no per-client memory between calls, retries can land on any instance, and idempotency is what guarantees they all reach the same end state. Master this one habit — design changes so repeating them is harmless — and a whole class of distributed-systems bugs simply disappears.

Key takeaways

  • An operation is idempotent if performing it many times has the same effect as performing it once.
  • Networks retry and messages get delivered more than once, so any operation that can run twice eventually will — idempotency is what makes that safe.
  • A non-idempotent action like 'charge the card' double-charges on a retry; a 'set the value' action does not, because the second run changes nothing.
  • HTTP GET, PUT, and DELETE are designed to be idempotent; POST usually is not, because it creates something new each time.
  • Make operations idempotent with idempotency keys to dedupe retries, upserts, and 'set' semantics instead of 'add' semantics.

Keep going