In large-scale systems, APIs must be reliable, predictable, and resilient — even when network retries, timeouts, or client errors occur. That’s where idempotency comes in. It’s a foundational concept in REST API design that ensures repeated requests don’t cause unintended side effects.
In this post, we’ll break down what idempotency means, how it applies to HTTP methods, and how real-world systems — like payment platforms — handle operations that aren’t naturally idempotent.
An operation is idempotent if performing it multiple times produces the same result as performing it once.
In other words:
Repeating the same request should not change the system state beyond the first execution.
Why this matters:
Networks are unreliable — clients may retry requests automatically
Users may refresh a page or press submit twice
Distributed systems may re-send messages after failures
Without idempotency, retries could cause:
Duplicate records
Double charges
Data corruption
Inconsistent system states
Idempotency allows APIs to be safe to retry.
REST APIs use HTTP methods not just for functionality — but also for behavioural guarantees. Some methods are idempotent by definition, others are not.
Retrieves data without modifying it
Multiple calls return the same resource
Example:
No matter how many times it’s called, the product does not change.
Replaces a resource with a new version
Re-sending the same payload results in the same state
Example:
If you send the same request twice, the result is still
product 1 has that description
Deleting a resource multiple times still results in
resource does not exist
Example:
A second delete does nothing — the state remains the same.
Depends on implementation
If it applies incremental changes, repeated attempts may stack
Example of non-idempotent PATCH:
Each retry adds another item — not idempotent.
POST usually creates resources or triggers actions.
Example:
Sending the same payload twice may create two separate orders.
But — POST can be made idempotent using techniques like idempotency keys, especially for financial and transactional systems.
Some operations are naturally non-idempotent — for example:
Placing an order
Submitting a form
Creating a resource
Processing a payment
If a client retries these requests and the backend processes them again, you could get:
Duplicate orders
Multiple database writes
Double-charged payments
To prevent this, systems implement idempotency guarantees at the application layer.
Imagine a user presses “Pay Now,” but the network drops and the client retries the request. Without idempotency, the user may be charged twice.
The client generates a unique key per operation, for example:
The server:
Stores the request and result against that key
If the same key is received again, it returns the original result
The payment is processed only once
This ensures:
One payment
Safe retries
Predictable behavior
Most major payment APIs (Stripe, PayPal, Square) use this approach.
Database unique constraints
Prevent duplicate rows (e.g., same transaction ID)
Transactional locks
Ensure only one request updates a resource at a time
Idempotent business logic
Example: marking something paid instead of adding a payment record each time
The goal is to make the system semantically idempotent, even when the underlying action is not.
Idempotency is a core principle in reliable REST API design. It ensures that retries don’t lead to unintended changes or duplicate operations.
Key takeaways:
Idempotency means repeated calls produce the same result
HTTP methods like GET, PUT, DELETE are naturally idempotent
POST is usually non-idempotent, but can be made idempotent with design strategies
Real-world systems — especially payments — rely on techniques like idempotency keys to prevent duplicate actions
Designing idempotent APIs leads to safer, more resilient, and more predictable distributed systems — a necessity at modern scale.