dFlow Logo
idempotency

Why Idempotency Matters in APIs

Avatar
Zoro
9 Mar, 2026
backendapi-designreliabilitysystem-design

Introduction

Modern applications communicate through APIs. Every login request, payment, file upload, or database update usually happens through an API call.

But real-world networks are unreliable. Requests can fail, connections can drop, and clients often retry the same request automatically.

When this happens, the same request might reach the server multiple times.

Without proper safeguards, this can lead to serious problems:

  • Duplicate payments
  • Multiple orders being created
  • Duplicate database records
  • Inconsistent application state

This is where idempotency becomes important.


What Is Idempotency?

In simple terms:

An operation is idempotent if performing it multiple times produces the same result as performing it once.

This means repeating the same request does not change the final outcome.

For example:

Setting a value to true repeatedly:

1isActive = true
2isActive = true
3isActive = true

The final state remains the same.

But incrementing a value is not idempotent:

1balance += 100
2balance += 100
3balance += 100

Each execution changes the result.


Why Duplicate Requests Happen

Duplicate API requests are more common than many developers expect.

Some common reasons include:

Network Timeouts

A client sends a request but does not receive a response in time.

The client assumes the request failed and retries.

But the server may have already processed the original request.


Automatic Retries

Many systems automatically retry failed requests.

Examples include:

  • HTTP clients
  • payment gateways
  • message queues
  • distributed systems

User Actions

Users sometimes trigger duplicate requests unintentionally.

Examples:

  • Clicking a button multiple times
  • Refreshing a page during submission
  • Slow UI feedback

Distributed Systems

In distributed environments, services communicate over unreliable networks.

Retries are often necessary, which increases the likelihood of duplicate requests.


Real Example: Duplicate Order Creation

Imagine a simple order creation API.

Example API

1POST /orders

Request:

1{
2 "userId": 123,
3 "productId": 987
4}

A typical implementation might look like this.

1app.post('/orders', async (req, res) => {
2 const { userId, productId } = req.body;
3
4 const order = await db.orders.insert({
5 userId,
6 productId,
7 createdAt: new Date()
8 });
9
10 res.json(order);
11});

If the request is sent twice, two orders will be created.

This is not idempotent.


The Problem This Causes

Imagine a payment system.

A user sends a request to create a payment:

1POST /payments

If the client retries the request due to a network timeout, the payment might be processed twice.

This can lead to:

  • double charges
  • duplicate invoices
  • financial inconsistencies

This is one of the most common problems in payment systems.


Making APIs Idempotent

There are several ways to make APIs idempotent.

The most common technique is idempotency keys.


Using Idempotency Keys

An idempotency key is a unique identifier attached to a request.

If the server receives the same key again, it returns the original response instead of processing the request again.

Example request:

1POST /payments
2Idempotency-Key: 7b9f1a2c

The server stores the key along with the result.

If the request is repeated with the same key, the stored result is returned.


Example Implementation in Node.js

Below is a simplified implementation.

1const processedRequests = new Map();
2
3app.post('/payments', async (req, res) => {
4 const idempotencyKey = req.headers['idempotency-key'];
5
6 if (!idempotencyKey) {
7 return res.status(400).json({
8 error: 'Idempotency key required'
9 });
10 }
11
12 if (processedRequests.has(idempotencyKey)) {
13 return res.json(processedRequests.get(idempotencyKey));
14 }
15
16 const payment = {
17 id: crypto.randomUUID(),
18 amount: req.body.amount,
19 createdAt: new Date()
20 };
21
22 processedRequests.set(idempotencyKey, payment);
23
24 res.json(payment);
25});

In this implementation:

  1. The server checks if the idempotency key was used before
  2. If it exists, the original response is returned
  3. If not, the request is processed and stored

This ensures duplicate requests produce the same result.


HTTP Methods and Idempotency

HTTP methods are designed with idempotency in mind.

Idempotent Methods

These methods should produce the same result if repeated:

GET
PUT
DELETE

Example:

1PUT /users/123

Updating the same user multiple times with the same data does not change the final state.


Non-Idempotent Methods

These methods can produce different results when repeated:

POST

POST usually creates new resources.

This is why idempotency protection is often required for POST endpoints.


Idempotency in Real Production Systems

Large platforms rely heavily on idempotency.

Examples include:

Payment systems
Order processing systems
Webhook handlers
Event-driven systems

For example, payment APIs often require idempotency keys to prevent duplicate charges when clients retry requests.

Without idempotency, financial systems would be extremely fragile.


A Practical Rule for API Design

Whenever an API performs an operation that changes data, consider what happens if the request is executed twice.

If the result becomes inconsistent or duplicated, the API likely needs idempotency protection.

This simple question can prevent many production issues.


Conclusion

Reliable APIs must assume that requests will be retried.

Networks fail, clients retry, and distributed systems introduce uncertainty.

Idempotency ensures that repeated requests do not corrupt system state or create duplicate operations.

For developers building production systems, idempotency is not an advanced optimization.

It is a fundamental reliability principle.

Designing APIs with idempotency in mind helps ensure that systems remain consistent even when the network behaves unpredictably.