Idempotency Design Patterns

Idempotency means performing an operation multiple times has the same effect as performing it once. In distributed systems, retries, and duplicate message consumption, idempotency prevents duplicate charges, duplicate orders, etc. This article covers implementations: unique key, state machine, token, deduplication table, with examples and a summary table.

Overview

  • Unique key: Business-unique identifier (order id, payment id). Check before insert/update; if exists, ignore or return existing. Use DB unique index for enforcement.
  • State machine: Operations have states (e.g. pending → paid → shipped). Execute only if the current state allows the operation; state transitions are idempotent. "Pay" when already paid returns success.
  • Token: Client gets an idempotency token first; request carries it. Server checks if the token was used; if used, reject; if not, execute and mark used. Prevents duplicate submission.
  • Deduplication table: Table keyed by request id (or business unique key). Check before insert; if exists, treat as duplicate. Add TTL or periodic cleanup.

Example

Example 1: Unique key

SQL
CREATE UNIQUE INDEX uk_order_id ON orders(order_id);
INSERT INTO orders (order_id, ...) VALUES (?, ...);
-- Duplicate order_id violates unique constraint; treat as duplicate, return existing order

Example 2: State machine

Java
if (order.getStatus() != OrderStatus.PENDING_PAYMENT) {
    return order;  // Already paid/cancelled; idempotent
}
order.setStatus(OrderStatus.PAID);
orderRepository.save(order);

Example 3: Token

Java
String idempotencyKey = request.getHeader("Idempotency-Key");
if (idempotencyKey == null) return error("missing key");
if (processedKeys.contains(idempotencyKey)) return cachedResult;
Result r = doProcess(request);
processedKeys.put(idempotencyKey, r);
return r;

Example 4: Pattern comparison

PatternBest forNotes
Unique keyNatural business identifierUnique index; distinguish duplicate vs concurrent
State machineClear state flowComplete states, atomic transitions
TokenFrontend duplicate submit, APIStorage and expiry policy
Deduplication tableGeneric, no natural unique keyPeriodic cleanup or TTL

Core Mechanism / Behavior

  • Unique key: DB unique constraint enforces at insert/update. On conflict, return existing or error; business treats as duplicate.
  • State machine: Idempotency by state: only certain transitions allowed; repeat transitions are no-op.
  • Token: One-time use; store token → result; reuse returns cached result.
  • Atomicity: Use unique constraint + insert, or SELECT FOR UPDATE + state check + update to avoid concurrent duplicates.

Key Rules

  • Writes and operations with side effects must be idempotent; reads are naturally idempotent.
  • Prefer business unique keys (order id, payment id) when available; otherwise use token or deduplication table.
  • Idempotency logic must be atomic to avoid duplicate execution under concurrency.

What's Next

See Message Idempotency and Payment Idempotency. See Distributed Transactions and Retry/Backoff for retry scenarios.