
Every FHIR server ships as "R4-conformant" and "US Core"-ready. Production distinguishes the ones that ship from the ones that struggle across seven concrete capabilities.
1. Batch/transaction Bundle handling. FHIR Bundle transactions require atomic all-or-nothing writes with placeholder URN resolution. Servers that quietly downgrade to per-resource writes break downstream integrations that assumed atomicity.
2. Chained and reverse-chained search. Patient?general-practitioner.name=Smith (chained) and Patient?_has:Observation:subject:code=8480-6 (reverse chained) are FHIR core. Some servers ship them incomplete or slow.
3. _include and _revinclude with iteration. Multi-hop joins via _include:iterate support real query patterns (Patient → Observation → PractitionerRef). Servers that skip iteration force client-side joins.
4. History and versioning. GET Patient/{id}/_history and If-Match: W/"1" on updates is FHIR core. Some servers cap history depth aggressively.
5. Async operations. Bulk Data IG $export, $validate, $expand — all need async execution for large payloads. Sync-only servers don't scale.
6. Terminology $validate-code inline. Write-time terminology validation via terminology module prevents bad data from landing. Skip this and terminology drift corrupts downstream analytics.
7. Metrics per resource type. Prometheus-style metrics that separate Patient throughput from Observation throughput are what operations teams actually need.
Vendor scorecard, mid-2026
| Server | Bundle transaction | Chained search | Async ops | Per-type metrics |
|---|---|---|---|---|
| HAPI JPA 7.x | Full | Full | Full | JMX |
| Aidbox 2409 | Full | Full | Full | Prometheus |
| Medplum 3.x | Full | Full | Full | OpenTelemetry |
| Microsoft FHIR Server | Full | Full | Partial | Azure Monitor |
All top four servers pass the seven above; second-tier ships with gaps. Verify the specific capabilities against your intended workload, not against marketing claims.

