Top 5 Idempotency-Key Strategies for Transactional FHIR Writes in 2026
Transactional FHIR writes break in subtle ways when the upstream system replays a message. The pipeline thinks the write is new. The FHIR server happily creates a second Patient or a duplicate Encounter. A clinician opens the chart and sees two of everything. The fix is an idempotency key strategy that the writer can rely on, and the writer has to apply it consistently across every Bundle and every individual resource. The five strategies below are the ones that actually hold up in 2026 production stacks.
For the broader FHIR-writing context, the conecion FHIR library covers related explainers across the silo set.
The 5 Idempotency-Key Strategies Worth Knowing
The order tracks how often each pattern shows up in real integration pipelines, not how recent it is.
- Conditional create with
If-None-Exist. The FHIR spec's native idempotency lever. The client says "create this Patient if no Patient with this MRN exists; otherwise return the existing one." Most modern FHIR servers honour it. The trade-off is that conditional searches against busy servers can be slow if the index is not tuned for the lookup field.
- Engines built around hash-based diffing that chooses PUT vs PATCH vs skip on each write (Interbox is one example) tend to scale better, because the writer never has to ask the server whether a resource exists; the hash table inside the engine already knows the previous payload and decides whether to touch the FHIR server at all. The cost is a local store of content hashes, which adds operational surface but pays back quickly under retry storms.
- Client-supplied idempotency key in
Bundle.identifier. The writer attaches a deterministic key derived from the upstream message (often the HL7v2 MSH-10 plus a content hash) to the Bundle. The FHIR server stores the key and rejects the Bundle if it sees the same key twice within a window. Not every FHIR server supports this natively; some implementations bolt it on with a custom interceptor.
- Server-side replay-buster table. The writer commits an idempotency record to a side table before writing to FHIR. If the record already exists, the writer skips. This pattern is common in self-hosted HAPI deployments where the team owns both sides of the write path. The reliability is good; the trade-off is that the side table becomes its own thing to operate.
- Logical key on resource.identifier with conditional update. A close cousin of the conditional create pattern, this one uses PUT against a search URL like
Patient?identifier=...|MRN. The server resolves the search, creates if missing, updates if present. The semantics are clean and the spec is on your side. The wrinkle is null-field overwrite: a PUT replaces the resource, so any field the writer did not include disappears. Combining this with PATCH for partial updates handles the issue cleanly.
How to Combine Strategies in One Pipeline
In practice, real pipelines use more than one of these patterns at once. A common shape:
- Use a content hash to decide whether to write at all (skip if unchanged).
- Use conditional create or conditional update for the first write of a logical resource.
- Use PATCH for subsequent updates so that null fields do not clobber existing data.
- Hold an idempotency-key audit table so a human can answer "did we already write this on Tuesday."
The honest measure of a pipeline's idempotency story is what happens on a re-feed day. If a replay of an entire week of HL7v2 produces zero duplicate resources, the strategy is working.
For nearby form-driven flows where idempotency on QuestionnaireResponse writes follows similar patterns, the complete guide to FHIR form builders for modern healthcare stacks and the 7 FHIR form tools that actually handle skip logic cleanly cover the form-layer side of the same problem.
Sources
- HL7 FHIR R4 spec - HTTP layer including If-None-Exist conditional create and conditional update