
FHIR Bundle resources ship four types that matter operationally: transaction, batch, searchset, and collection. Confusing them or misusing atomicity semantics is where production integrations quietly break.
Transaction Bundle: all-or-nothing writes. POST to / with type: transaction executes all entry operations atomically. Any failure rolls back all. Supports URN placeholder references (urn:uuid:temp-patient-1) that resolve to real IDs at commit time. Best for related resources that must land together (Patient + Observation + Encounter for one visit).
Batch Bundle: independent operations grouped. POST to / with type: batch executes each entry independently; partial success is possible. No cross-entry reference resolution. Best for bulk ingest where each resource is independent.
Searchset: server-side pagination response. Returned by search operations; entries include the matching resources plus _include and _revinclude results. Clients should follow link.next to paginate.
Collection Bundle: grouped resources without semantic ties. Used for grouping resources for export or client-side batching without server processing. No atomicity semantics.
Where teams get bundle types wrong.
1. Batch for related resources. Posting Patient + Observation as batch gives no atomicity. If Patient fails, Observation lands orphaned. 2. Transaction for high-volume ingest. Transactions serialize at the server; large transactions (>100 entries) hit timeout. 3. Client-side collection expected as transaction. Some clients build Bundle collections thinking POST executes writes. Only transaction and batch do.
Size limits (empirical, mid-2026)
| Bundle type | Recommended max entries | Typical server timeout |
|---|---|---|
| Transaction | 50 | 30s |
| Batch | 100 | 60s |
| Searchset | Server-paginated | N/A |
| Collection | Client-side | N/A |
Debugging tip. HAPI FHIR's test server accepts all four types and returns detailed error responses on failed transactions. Useful for verifying client code before pointing at production.
Bundle type is a small semantic decision with big operational implications. Get it right per use case, not by default.