Designing Idempotent APIs and Global ID Strategies
This article explains the concept of API idempotency, why it is needed for reliable retries, and presents practical designs using global unique identifiers such as UUID and Snowflake, including their advantages, drawbacks, and implementation considerations for backend services.
Today we discuss the design of idempotent interfaces. Idempotency means that executing an operation any number of times has the same effect as executing it once. An idempotent API can be called repeatedly with the same parameters and always produce the same result.
Why do APIs need idempotency? When a client calls an API, the result can be success, failure, or timeout. In case of timeout the client cannot know whether the request succeeded, so it typically retries, which may lead to multiple executions of the same operation.
For example, when creating an order you need to decrement inventory. If the inventory‑decrement request times out, the client may call it again; the system must ensure that inventory is not deducted twice.
There are two common ways to guarantee this:
The service provider offers a query interface so the client can check after a timeout whether the operation succeeded. This puts the responsibility on the client and can be risky for third‑party APIs.
The service itself supports idempotency, keeping the guarantee on the provider side.
Global ID
To make an API idempotent you can add a globally unique parameter (a global ID). The database table should have a unique index on this field; duplicate inserts will cause a uniqueness error, indicating the operation has already succeeded.
Who should generate this global ID?
1. Central allocation service
Pros: ID allocation is decoupled from business clusters.
Cons: Requires a separate high‑availability service, increasing maintenance cost.
2. Integrated into the business service cluster
Pros: The business cluster is already highly available, no extra guarantees needed.
Cons: ID generation is coupled with business logic, but this is usually acceptable.
Generally the second approach is preferred; you only need an algorithm that can generate globally unique IDs across the cluster.
Beyond global uniqueness, desirable (but not mandatory) properties are:
Monotonically increasing on each machine (helps database performance).
Clear bit‑level rules for easier tracing.
Common Global ID Algorithms
UUID
UUIDs are designed so that every element in a distributed system can have a unique identifier without a central coordinator. Most programming languages provide built‑in libraries for generating them.
Advantages: simple to implement, generated locally, good performance, highly scalable, no coordination needed.
Disadvantages: not sequential (can hurt database performance), long string consumes more storage.
UUIDs are a good choice for small‑to‑medium projects with low concurrency where database performance is not a bottleneck.
Snowflake
Snowflake, an open‑source project from Twitter, generates 64‑bit positive integers with the following structure:
1 bit: fixed 0 (sign bit).
41 bits: timestamp in milliseconds (covers about 69 years).
10 bits: machine identifier (5 bits data‑center ID + 5 bits worker ID), supporting up to 1,024 instances.
12 bits: sequence number, allowing up to 4,096 IDs per millisecond per machine.
Advantages: IDs are increasing and time‑ordered, high performance, and bit allocation can be customized.
Disadvantages: depends on synchronized clocks; clock drift across machines can cause duplicate IDs.
Under high concurrency, Snowflake IDs have better storage and retrieval performance than UUIDs. Many Chinese companies have their own Snowflake‑based implementations, such as Baidu’s UidGenerator.
Using Redis or MongoDB for ID generation introduces additional dependencies and maintenance overhead, so they are not discussed here.
Business Logic
When the database reports a uniqueness violation, it indicates the request has already succeeded, so the service can simply return the previous result without re‑executing the business logic.
HTTP Idempotency
HTTP methods have specific idempotency requirements. For POST requests, repeated submissions can occur due to network issues or user actions. A common solution is to include a hidden global ID in the submitted form, obtained from the backend beforehand. The backend processes the request using this ID, and after a successful response the client redirects to a GET request to display the result.
Conclusion
This article covered the key points of idempotent design, presented practical solutions such as using global unique IDs, and compared UUID and Snowflake algorithms, enabling developers to choose the most suitable approach for their specific scenarios.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.