Skip to content
Low Level Design Mastery Logo
LowLevelDesign Mastery

Idempotency & Exactly-Once Processing

Making operations safe to retry

In distributed systems, messages/requests can be duplicated:

Diagram

Problem: Without idempotency, retries create duplicates!

Solution: Idempotency - Make operations safe to retry!


An idempotent operation is one that produces the same result when executed multiple times with the same input. In other words, calling it once has the same effect as calling it N times.

In distributed systems, operations can be retried due to network failures, timeouts, or system crashes. Without idempotency, retries can cause:

  • Duplicate operations (creating the same order twice)
  • Incorrect state (adding balance multiple times)
  • Side effects (sending multiple emails)

Idempotency makes operations safe to retry - if a request is retried, it produces the same result as the first attempt, preventing duplicates and ensuring consistency.

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

Calling the function twice = calling once.

Idempotent Operations:

  • GET /users/123 - Always returns same user
  • PUT /users/123 - Replaces user (same result)
  • DELETE /users/123 - Deletes user (same result if already deleted)
  • SET balance = 100 - Sets to 100 (same result)

Non-Idempotent Operations:

  • POST /orders - Creates new order each time
  • balance = balance + 50 - Adds 50 each time
  • send_email() - Sends email each time

Client provides unique key. Server checks if seen before.

Diagram

How it works:

  1. Client generates unique idempotency key
  2. Server checks if key exists
  3. If new → Execute operation, store result with key
  4. If exists → Return cached result (don’t execute)

Ensures message processed exactly once.

  1. Idempotent Operations - Safe to retry
  2. Deduplication - Track processed messages
  3. Distributed Coordination - Handle duplicates across servers

For multiple servers, use shared storage (Redis/Database):


Always provide idempotency keys for mutating operations:

POST /orders
Idempotency-Key: abc123-xyz789
Content-Type: application/json
{ "user_id": 456, "amount": 99.99 }

Client generates unique key:

  • UUID
  • Timestamp + random
  • Hash of request content

Cache results with keys:

  • Store successful results
  • Don’t store failed results (allow retry)
  • Set TTL (e.g., 24 hours)

Always check key before processing:

  • If exists → Return cached result
  • If new → Process and cache

Design operations to be idempotent:

  • Use “set” instead of “add”
  • Check state before modifying
  • Use conditional updates

Idempotency is Critical

Make operations safe to retry. Essential for distributed systems, retries, at-least-once delivery.

Idempotency Keys

Use unique keys to detect duplicates. Check before processing. Cache results. Return cached on duplicate.

Exactly-Once

Exactly-once requires idempotency + deduplication. Track processed messages. Use distributed storage for multiple servers.

Store Results

Cache successful results with keys. Don’t cache failures. Set TTL. Check before processing.