A resolver that issues one GET per external reference is a resolver that will hit the network more than any other cost in its budget. Batching those reads into a single request per target server changes the shape of the round-trip cost from linear to bounded. FHIR has first-class support for the pattern through batch Bundles, and using them cuts an order of magnitude off resolution time for graph-heavy workloads. The site's Bundle reference walker surfaces which references would batch. For the wider FHIR framing, the FHIR architecture knowledge base has more.
Why Round Trips Dominate
- Each external reference is a network hop
- Latency per hop is measured in tens of milliseconds
- A payload with fifty external references and no batching is fifty round trips
- Even at 20ms per hop that is a full second before the resolver starts computing
Batching turns that fifty-hop cost into two or three hops. The compute time stays the same; the wall clock changes dramatically.
What A Batch Bundle Looks Like
A batch Bundle is a POST to the server root with Bundle.type = "batch" and entries that each carry a request.method = GET and a request.url. The server executes each entry independently and returns a response Bundle with per-entry status and body.
That is the FHIR-native batching mechanism. It exists specifically for the "I need many resources from one server" use case that a resolver has.
Group References By Target Server
The first step in batching is grouping. Every external reference points at a server — inferred from the base URL or from context. Group references by target, and each group becomes a batch. A payload that spans three FHIR servers produces three batches.
The Bundle reference walker does this grouping when it inspects a paste-in Bundle — it clusters external references by likely target and reports the fan-out.
Deduplicate Within A Batch
References to the same resource appear more than once in real payloads. A Patient referenced from ten Observations is one Patient, not ten. Deduplicate before batching — the batch carries each unique reference once, and the results get distributed back to the requesters at merge time.
For the base pattern, resolving FHIR references without a full database walk is the entry.
Handle Partial Failures
Every batch entry can succeed or fail independently. A batch of fifty entries may return forty-nine 200s and one 404. The resolver has to distribute the outcomes back to the reference sites, and callers have to handle the mixed result.
Do not fail the whole resolution because one entry failed. Do not silently drop the failed one — mark the reference as unresolved and surface it. For the outage-robust design, designing a reference resolver that survives partial outages covers the pattern.
What About _include and _revinclude?
FHIR search has _include and _revinclude parameters that let the server resolve references server-side and return the graph in one call. That is the other batching mechanism, and it is often cheaper than a client-side batch Bundle when the query naturally starts with a search.
GET /Observation?patient=42&_include=Observation:subject returns the Observations and the referenced Patient in one round trip. Whether to use search-with-include or batch-Bundle depends on the query shape; both are legitimate.
Bulk Data Is Different
For bulk-export workloads, the resolver strategy shifts. Ndjson files carry references between them, and the resolver has to work on the whole file set rather than per-request. For the specifics, reference resolution in Bulk Data: what the spec allows is the entry.
The Short Version
Group references by target server. Deduplicate within a batch. Use batch Bundles or search-with-include depending on query shape. Handle partial failures explicitly. The client's wall clock drops by an order of magnitude, and the resolver stays cheap to run.

Sources
- HL7 canonical section on batch and transaction Bundle - HL7 canonical section on batch and transaction Bundle interactions