Skip to content
Back to skills

Idempotency Patterns

ASecurity

This skill should be used when the user mentions "idempotency", "idempotency key", "retries", "exactly once", "double charge", "pagination", "cursor", "offset", "rate limit", "rate limiting", "Retry-After", "safe retries", or making an unsafe HTTP method safe to retry. It provides idempotency-key store recipes, safe-retry semantics for POST/PATCH/DELETE, and cursor/offset pagination plus standard rate-limit headers.

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
ai-agentsgosqlgitapi

Works with

  • cursor
  • cli
  • api

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 19, 2026

npx -y skills add sigistry/marketplace --skill idempotency-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Idempotency Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Idempotency Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sigistry-idempotency-patterns/badge)](https://www.skillsdirectory.com/skills/sigistry-idempotency-patterns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: idempotency-patterns
description: This skill should be used when the user mentions "idempotency", "idempotency key", "retries", "exactly once", "double charge", "pagination", "cursor", "offset", "rate limit", "rate limiting", "Retry-After", "safe retries", or making an unsafe HTTP method safe to retry. It provides idempotency-key store recipes, safe-retry semantics for POST/PATCH/DELETE, and cursor/offset pagination plus standard rate-limit headers.
---

# Idempotency Patterns

## Purpose
Provide standardized recipes for the three pieces of API plumbing that clients depend on and servers get subtly wrong: **safe retries** (idempotency keys so a retried mutation applies once), **pagination** (stable, bounded traversal of collections), and **rate limiting** (standard headers so clients back off correctly). All three are static, framework-agnostic patterns, apply them at the boundary, in the handler.

## Why idempotency
HTTP defines `GET`, `HEAD`, `PUT`, and `DELETE` as **idempotent** (repeating them has the same effect as doing them once) and `GET`/`HEAD` as **safe** (no side effects). `POST` is **neither**: and networks retry. A client that times out and retries a `POST /payments` can charge twice. The fix is an **idempotency key**: the client sends a unique `Idempotency-Key` header; the server records key → outcome and, on replay, returns the stored outcome instead of re-executing.

### The idempotency-key algorithm (unsafe methods only)
1. Read the `Idempotency-Key` header. If absent on a create endpoint, either require it (`400`) or proceed without dedup, decide per endpoint.
2. Look up the key (scoped to the authenticated principal + endpoint) in a durable store.
3. **Hit, completed** → return the stored status + body verbatim. Do not re-run.
4. **Hit, in-flight** → the original is still processing: return `409` (or block briefly), never run concurrently.
5. **Miss** → atomically insert the key in an `in-flight` state (unique constraint / `SET NX`), execute the work, store the response, mark `completed`, set a TTL.
6. Guard against **key reuse with a different body**: store a hash of the request; if the same key arrives with a different payload, return `422`.

Apply idempotency **only** to unsafe, non-idempotent methods (`POST`, and non-idempotent `PATCH`). `GET`/`HEAD`/`PUT`/`DELETE` are already idempotent by contract, do not bolt a key onto them. Full store recipes and TTL/window guidance are in `references/idempotency-recipes.md`.

## Pagination in one page
- **Cursor (keyset)** is preferred: `?limit=50&cursor=<opaque>`, ordered by a stable, unique key (usually `(created_at, id)`). O(1) per page, stable under inserts, no deep-offset scan. Return the next cursor (and `hasMore`), not a total.
- **Offset** (`?limit=50&offset=100`) is fine for small, static datasets and jump-to-page UIs, but drifts when rows are inserted/deleted and gets slow at high offsets.
- Always **bound `limit`** (default + max, e.g. 20/100) and **order by a unique key** so the sort is deterministic. Details and encoding in `references/pagination-and-rate-limits.md`.

## Rate-limit headers in one page
Advertise limits with the standard `RateLimit` fields so clients self-throttle instead of hammering you:
- `RateLimit: limit=100, remaining=12, reset=30` (current window) and `RateLimit-Policy: 100;w=60` (the policy).
- On `429 Too Many Requests`, always send `Retry-After` (seconds or an HTTP-date). Use `429` for rate limiting, not `403`.
See `references/pagination-and-rate-limits.md` for the exact header syntax and the legacy `X-RateLimit-*` mapping.

## Golden rules
- Idempotency keys go on **unsafe** methods only; make them **client-supplied**, **durable**, **atomically claimed**, and **TTL-bounded**.
- Never dedup on the request body alone, bodies collide and legitimately repeat; use the explicit key, with a body hash as a mismatch guard.
- Paginate with a **stable unique sort key** and a **bounded limit**; prefer cursors for large or live data.
- Rate limits are a **contract**: publish them in headers and always pair `429` with `Retry-After`.

## Additional Resources
### Reference Files
- **`references/idempotency-recipes.md`**: idempotency-key store schemas (SQL unique-constraint and Redis `SET NX`), the atomic claim, dedup windows/TTLs, request-hash mismatch handling, safe-retry semantics for each HTTP method, and where to store keys.
- **`references/pagination-and-rate-limits.md`**: cursor vs offset design, opaque cursor encoding, stable ordering and tie-breaking, keyset SQL, and the standard `RateLimit`/`RateLimit-Policy`/`Retry-After` headers with the legacy `X-RateLimit-*` mapping.

Files in this skill

  • SKILL.md4.6 KB
  • references/idempotency-recipes.md6.5 KB
  • references/pagination-and-rate-limits.md5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.