Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A unique index prevents concurrent requests from creating multiple rows for the same indexed identity. But it does not, by itself, make an entire endpoint retry-safe: your application must handle the conflict, and often must store and replay the original response for requests using the same stable idempotency key.

What a unique index does—and what it does not

A unique index makes the database enforce a rule such as “there can be only one operation row for this caller and request key.” It is the backstop that prevents two concurrent inserts from both creating a row with that identity. PostgreSQL documents that uniqueness checks account for concurrent transactions, including cases where one transaction must wait for another to finish (PostgreSQL: Index Uniqueness Checks).

That protection is narrower than endpoint idempotency. The index can prevent a duplicate row, but it cannot automatically prevent a repeated email, payment, remote API call, or other effect outside the indexed write. Nor does the index automatically return the first request’s HTTP status and body. Those behaviors require application logic and, when callers need a consistent answer, a persisted result associated with the request key.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Design the identity and stored result

For a create endpoint, define what counts as the same logical operation before choosing the index. A common design uses a client-supplied idempotency key, scoped to the caller and sometimes to the operation type. The key must remain the same across retries; generating a new key after a timeout makes the retry look like a new operation.

Persist the key under a database uniqueness rule along with the operation’s state and enough response data to answer a duplicate request. If the local business effect and this record are in the same database, write them in one transaction. When a request conflicts with an existing key, load that operation and return its saved result, or report its current state, rather than blindly repeating the effect. This is a design pattern built from database uniqueness and API idempotency behavior; it is not a schema automatically supplied by every database or API provider.

Handle the conflict in the write path

A “check then insert” sequence is not sufficient protection. Two requests can both check that a key is absent before either one inserts. Put the identity rule in the database and treat a uniqueness conflict as expected control flow.

In PostgreSQL, a unique constraint creates a unique B-tree index. INSERT ... ON CONFLICT lets the write specify what happens when the unique identity already exists:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • DO NOTHING skips the proposed insert. The application can then read the row for that key and decide what response to return.
  • DO UPDATE performs an atomic insert-or-update outcome under concurrency, barring an independent error. Use it only when updating the existing row is the correct business behavior; an upsert is not automatically equivalent to replaying the original response.

PostgreSQL documents conflict-target index inference and the atomicity of the insert-or-update path in its INSERT documentation. That URL is for PostgreSQL 19 documentation; check the documentation for the PostgreSQL version you actually run before relying on version-specific behavior. Index inference can be more resilient than naming one constraint when an index is being replaced with an overlapping index.

Choose the database identity precisely

The index must match the business rule, not merely a convenient column. A single nullable field, a partial index, a composite key, or a partitioned table can change which rows the database considers duplicates. Define the identity explicitly—for example, caller plus operation key—and verify how your database version and schema treat nulls, predicates, and partitions. PostgreSQL’s CREATE INDEX documentation describes unique indexes and concurrent index builds.

For an existing PostgreSQL table that must continue accepting writes while a unique index is built, CREATE UNIQUE INDEX CONCURRENTLY avoids locking out writes for the full build. It requires multiple scans, and a failed build can leave an invalid index. Confirm that the migration completed successfully and inspect and recover any failed build according to PostgreSQL’s documented procedure.

Keep retries safe across external services

A local transaction cannot atomically include an external payment service or another independent system. If the endpoint writes locally and then calls a remote service, a timeout can leave it unclear whether the remote effect happened. Use the remote service’s idempotency mechanism when available, generate the external key once, and reuse exactly that key for every attempt. Define how the application reconciles operations left in an unfinished or ambiguous state. AWS likewise recommends stable idempotency tokens for retryable work in its idempotency and retries guidance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Provider-specific retry windows and limits

Idempotency is bounded by each provider’s rules. A key that is forgotten or pruned can be treated as new, so a client must not assume that deduplication lasts forever.

System Identity and conflict behavior Window or transaction boundary Retry consideration
PostgreSQL A unique constraint or index enforces the chosen row identity; ON CONFLICT can skip or update on conflict. No idempotency-key retention window is specified by the cited PostgreSQL index and INSERT documentation. Store and return an operation result if clients need the original response; the unique index alone does not provide response replay.
Stripe Stripe saves the first result once endpoint execution begins; reuse of a key with different parameters is rejected. Validation failures and certain concurrent conflicts are not saved and may be retried. Stripe’s documentation says keys may be pruned after they are at least 24 hours old; this is a minimum age before pruning, not a promise of indefinite retention. Reuse the same key and parameters. After a key has been pruned, a request with it may be treated as new. See Stripe’s idempotent requests documentation.
DynamoDB TransactWriteItems A client token makes an identical transaction request idempotent within its validity window. AWS documents a 10-minute window after the request finishes. Transactions are limited to 100 distinct items and 4 MB, and their ACID guarantees apply in the originating Region. Reuse the token only with identical parameters during the window; after it expires, the same token is treated as a new request. See DynamoDB transaction documentation and DynamoDB constraints.

Recover from ambiguous outcomes

A timeout or server error does not always mean a write failed. AWS warns that a single-item DynamoDB write returning HTTP 500 may have succeeded or failed. Before retrying such a write, read the resulting state or use a conditional expression to avoid applying the operation twice. AWS identifies transactional writes as supporting idempotent retries; see its DynamoDB error-handling guidance.

For an endpoint you control, treat a lost response as an unknown outcome, not proof of failure. On a repeated request, look up the durable operation identity and return the recorded result when available. If work is still in progress, return a defined pending response or status rather than launching a second side effect.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.