Bulk Data delivers ndjson files that carry FHIR resources by the thousand. References between resources in those files cross ndjson boundaries: a Patient in the Patient file is referenced from Observations in the Observation file. Resolving those references reliably is a different exercise from resolving references in a REST context. The spec says specific things about what a server may include and how a client should handle it. The site's Bundle reference walker is REST-shaped, but the principles carry over. For the wider FHIR framing, more on Da Vinci IGs in practice has more.
What The Spec Says About Bulk Data References
A Bulk Data export can include:
- Type-scoped resources: Patient/Observation/Condition ndjson per resource type
- Requested types: only the types the client asked for
- Referenced resources: some, but not all, referenced resources may be included
The _typeFilter and _includeAssociatedData parameters control what accompanies the primary resources. Servers implement these variably — some export every referenced resource; some export only the primary set; some support a per-request declaration.
The consequence: the client should not assume every reference resolves within the export.
The Whole-Export View
For a Bulk resolver, the input is the set of ndjson files, not a single Bundle. The right pattern is:
- Build an index across all files, keyed by ResourceType + id
- Walk references and consult the index first
- Fall through to a REST GET when a reference is not in the index
That "index across all files" is the same in-memory index the Bundle walker uses, scaled to the export. For the base pattern, resolving FHIR references without a full database walk is the entry.
References To Resources Not In The Export
The spec allows references to resources outside the export. Bulk clients have to handle:
- References to resources on the same server that were not part of the export
- References to resources on a different server entirely
- References that will never resolve because the target is out of scope
For the first case, the client can go back to the server with REST. For the second, cross-server resolution rules apply. For the third, the reference stays unresolved and the workflow decides.
For the cross-server picture, reference integrity in a distributed FHIR deployment is the entry.
Batching Still Matters
Even in a bulk resolver, the REST fallback path benefits from batching. Group the un-resolvable-from-index references by target, then hit each target with a batch. For the batching mechanic, batching resolution to reduce round trips covers it.
Version-Specific References In Bulk
Bulk exports may or may not include historical versions. A version-specific reference in a bulk-exported resource that points at a version the export did not include is not resolvable without going back to the source server. The client has to plan for that.
Servers that expose _since for incremental exports typically export only the current version. Full-history exports are the exception, not the default.
Client Design For Bulk Resolution
- Load all ndjson files into an index before walking references
- Report unresolved references as a first-class output
- Batch REST fallbacks for references outside the export
- Handle partial availability — some files may be missing or truncated
For the outage-robust design, designing a reference resolver that survives partial outages covers the mechanics.
Real-World Trade-Offs
Full-export runs return complete datasets but take longer and use more storage. Incremental runs with _since are cheaper but produce more unresolved references at the boundary. The trade is a workload decision, not a spec decision.
The Short Version
Bulk Data resolution is index-heavy and REST-fallback-augmented. Reference completeness is not guaranteed. Batch the fallbacks. Version-specific references may not resolve inside the export. Report unresolved as a first-class outcome.

Sources
- HL7 canonical Bulk Data Access IG covering export semantics - HL7 canonical Bulk Data Access IG covering export semantics