Idempotency-Key for Job Creation
so1 intermediate 4 min read
ELI5
You write a unique receipt number on your envelope. If the post office sees the same number twice within a day, they don’t open a new file — they hand back the original tracking id. Lost-in-transit retries are safe.
Technical Deep Dive
Header Contract
Per ADR-003, clients generate a UUID v4 and pass it as Idempotency-Key: <uuid> on POST /api/jobs. The BFF stores the mapping Idempotency-Key → Job ID for 24 hours. Within that window, a re-submission returns the same Job ID without re-running.
Sequence
sequenceDiagram participant C as Client participant B as BFF participant Store as Idempotency Store C->>B: POST /api/jobs (Idempotency-Key=K1) B->>Store: lookup K1 Store-->>B: miss B->>B: create Job J1 (state=pending) B->>Store: put K1 -> J1 (TTL 24h) B-->>C: 202 { requestId, job: J1 } Note over C: network blip, retry C->>B: POST /api/jobs (Idempotency-Key=K1) B->>Store: lookup K1 Store-->>B: hit (J1) B-->>C: 202 { requestId, job: J1 }The second requestId is fresh (per-request); only the job.id is replayed.
Conflict Handling
ADR-004 defines CONFLICT (HTTP 409) for “Idempotency key mismatch”. Practical interpretation: if the same key is reused with a meaningfully different request body, the BFF rejects the second call with CONFLICT rather than silently returning the original — protecting against client bugs that recycle keys across distinct intents.
Why 24 Hours
Long enough to absorb realistic retry windows (network outages, cron backoffs) without unbounded storage growth. ADR-003 names the value but defers the store implementation choice (Redis, DB row with TTL, etc.).
Key Terms
- Idempotent → the operation’s effect is the same whether applied once or many times with the same key.
- Idempotency store → time-bounded mapping
key → job id, typically in fast KV. - CONFLICT (409) → reused key with different intent; see so1-011.
Q&A
Q: Is the key required?
A: ADR-003 phrases it as “Idempotent: Idempotency-Key header prevents duplicate creation” — recommended, not strictly mandatory; missing keys behave as fresh creates.
Q: Does a second submission cancel/retry the first job if it’s failed?
A: No. The mapping replays the original Job ID regardless of its state. To re-run, the client uses a new Idempotency-Key.
Q: Where is the 24-hour TTL specified? A: ADR-003 implementation notes; the concrete store and TTL enforcement are deferred to TASKSET 5.
Examples
A flaky network drops the response of POST /api/jobs with Idempotency-Key: 8c1e…. The client retries with the same key and receives 202 with the same job.id it would have seen on the first call — no duplicate workflow trigger.
neighbors on the map
- Tier-Based Rate Limiting debugging 429 errors for specific users
- In-Process Rate-Limit Bucket investigating ingest 429s
- FNP CRDT Conflict-Free Merge Semantics understanding CRDT properties and guarantees