FHIR vs HL7 v2 — which one for which job?
Both standards work. The wrong one wastes six months. Here's how we choose on real engagements.

The short version
Use FHIR R4 when you control the integration end-to-end, want a modern REST/JSON API, and need to talk to EHRs via SMART on FHIR or Bulk FHIR. Use HL7 v2 when you're plugging into hospital interface engines (Mirth, Rhapsody, Cloverleaf), reading lab results (ORU^R01), or moving ADT events that already exist as v2 messages — don't force a translation if the source is v2 and the destination accepts v2.
Decision matrix
| If you need… | Pick | Why |
|---|---|---|
| EHR patient/observation reads | FHIR R4 | Native in Epic, Cerner, Athena via SMART on FHIR. |
| Bulk EHR export for a cohort | Bulk FHIR ($export) | NDJSON, async, designed for population pulls. |
| Lab result ingestion from a LIS | HL7 v2 ORU^R01 | Most LIS systems still emit v2; interface engines route it. |
| ADT events (admit/discharge/transfer) | HL7 v2 ADT | Real-time hospital messaging is overwhelmingly v2. |
| Sending eCRF data to an EHR | FHIR R4 (write) | Write-back is cleaner with FHIR Observation/DocumentReference. |
| Registry submission | Depends | Some registries take FHIR Bundles, others want CSV or v2 — check the spec. |
What people get wrong
- Treating FHIR like a magic bullet. EHRs implement FHIR differently. Epic's USCDI scope is not Cerner's. Always profile the source against the resources you actually need.
- Re-encoding v2 to FHIR for no reason. If the destination accepts v2, translating adds latency, bugs and an extra system to validate.
- Skipping the terminology layer. LOINC, SNOMED, RxNorm and ICD-10 mismatches between source and target are where most "FHIR projects" stall.
- Ignoring throughput. Bulk FHIR is async for a reason. If you need 200k patients, REST GETs at 1 RPS will take three days.
How we scope an integration
Two-week discovery: source system inventory, resource/segment profile, terminology gaps, throughput requirements, security boundary (PHI vs de-identified), and an integration architecture diagram. Output is a fixed-scope SoW with timelines.