sql 112 lines · 3 tabs

Idempotency keys for “create” endpoints

Shared by codesnips Jan 2026
3 tabs
CREATE TABLE idempotency_keys (
    request_key         text        NOT NULL,
    endpoint            text        NOT NULL,
    request_fingerprint text        NOT NULL,
    status              text        NOT NULL DEFAULT 'in_progress'
                                    CHECK (status IN ('in_progress', 'completed')),
    response_code       integer,
    response_body       jsonb,
    resource_id         bigint,
    created_at          timestamptz NOT NULL DEFAULT now(),
    completed_at        timestamptz,
    PRIMARY KEY (request_key, endpoint)
);

-- Cheap lookup of in-flight attempts for the TTL sweeper.
CREATE INDEX idempotency_keys_in_progress_idx
    ON idempotency_keys (created_at)
    WHERE status = 'in_progress';
3 files · sql Explain with highlit

Create endpoints are the classic place where retries hurt: a client sends POST /orders, the network times out, the client retries, and now two orders exist. An idempotency key fixes this by letting the client attach a unique token to a logical operation, so the server can recognize a retry and return the original result instead of doing the work twice. This snippet shows the storage and locking machinery in raw SQL.

The idempotency schema tab defines idempotency_keys as a durable record of each attempt. The primary key is (request_key, endpoint) so the same token can be reused across different routes without colliding. A request_fingerprint column stores a hash of the request body; this guards against a client accidentally reusing a key for a different payload, which should be rejected rather than silently returning a stale response. The status column tracks the lifecycle (in_progress, completed), and response_code/response_body cache the final result so a retry can be replayed byte-for-byte. The partial index on status = 'in_progress' keeps lookups of in-flight work cheap.

The claim_idempotency_key tab is the heart of the pattern. It takes a transaction-scoped advisory lock keyed by a hash of the token with pg_advisory_xact_lock, which serializes concurrent requests that share a key without locking the whole table. Under that lock it does an INSERT ... ON CONFLICT DO NOTHING: the first caller inserts an in_progress row and gets the green light to run the business logic, while a concurrent duplicate finds the existing row. The function returns a did_claim boolean plus any cached response, so the caller knows whether to proceed or short-circuit.

The create_order flow tab ties it together in one transaction. It calls claim_idempotency_key; on a fresh claim it inserts the order and calls complete_idempotency_key to persist the cached response, and on a duplicate it simply returns the stored body. The fingerprint mismatch path raises so misused keys fail loudly. The trade-offs worth noting: advisory locks are per-connection and released at commit, so everything must live in one transaction; and stale in_progress rows from crashed requests need a sweeper job with a TTL. Used carefully, this turns non-idempotent creates into safely retryable operations.


Related snips

Share this code

Here's the card — post it anywhere.

Idempotency keys for “create” endpoints — share card
Link copied