Written and maintained by CASRAI Editorial Board
Last updated
When healthcare software engineers and clinical informaticists compare HL7 v2 vs. FHIR (or ask “Is HL7 and FHIR the same?”), the core distinction is between the standards organization and two generations of its technical specifications. Health Level Seven International (HL7) is the ANSI-accredited standards development organization that created both HL7 Version 2 (v2.x)—an event-driven, pipe-delimited (`|^~&`) messaging protocol transmitted over persistent TCP/MLLP sockets—and HL7 FHIR (Fast Healthcare Interoperability Resources)—a modern, resource-oriented RESTful API specification using JSON, XML, or RDF/Turtle over HTTPS with OAuth 2.0 / SMART on FHIR authorization.
What Is the Difference Between HL7 v2, HL7 v3, and FHIR?
To understand why both standards run across nearly every U.S. health system simultaneously, it helps to trace the architectural evolution across HL7’s three primary interoperability frameworks:
- HL7 Version 2 (v2.1 through v2.8, dominated by v2.3.1 and v2.5.1): First published in 1987, HL7 v2 is a point-to-point, event-driven messaging standard encoded in ER7 (Encoding Rules 7)—commonly called “pipe-and-hat” syntax—and framed on hospital local area networks using the Minimal Lower Layer Protocol (MLLP) (`0x0B` start byte, `0x1C 0x0D` trailer bytes). When a clinical event occurs (such as a patient admission or a completed lab panel), the source system pushes a flat sequence of three-letter segments (`MSH`, `PID`, `PV1`, `OBR`, `OBX`) to downstream subscribers. HL7 v2 is deliberately permissive and allows site-specific custom Z-segments (e.g., `ZPD`, `ZIN`), which makes initial hospital interface setup fast but requires custom HL7 parser and interface engine translation for every hospital connection.
- HL7 Version 3 (v3) and the Reference Information Model (RIM): Introduced in the late 1990s and 2000s to eliminate v2’s site-by-site ambiguity, HL7 v3 mandated a strict top-down object-oriented Reference Information Model (RIM) serialized in deeply nested XML. While v3 messaging proved too complex and verbose for widespread real-time point-to-point adoption, its document architecture—HL7 CDA (Clinical Document Architecture) and Consolidated CDA (C-CDA R2.1)—became the national standard for clinical summary document exchange.
- HL7 FHIR (Release 4 [R4], R4B, and R5): Designed from the ground up for the web and cloud era, FHIR replaces monolithic message streams and RIM XML trees with modular, addressable data units called Resources (such as
Patient,Encounter,Observation, andDiagnosticReport) built on an 80/20 design rule: base resource elements cover the 80% of data elements used by most healthcare systems, while a formal, machine-readable `extension` mechanism handles the remaining 20% without breaking standard parsers.
| Dimension | HL7 Version 2 (v2.x) | HL7 Version 3 (v3 / C-CDA) | HL7 FHIR (R4 / R5) |
|---|---|---|---|
| Architectural Paradigm | Event-driven point-to-point messaging (push) | RIM-derived object model & persistent clinical documents | Resource-oriented RESTful APIs (CRUD + search + Bulk `$export` + Subscriptions) |
| Wire Serialization Format | ER7 pipe-and-hat (`|^~&`) ASCII/UTF-8 text | Verbose RIM-conformant XML | JSON, XML, or RDF/Turtle (with JSON-LD support) |
| Network Transport Layer | MLLP over persistent TCP/IP sockets (or LLP/VPN) | SOAP web services, IHE XDS.b/XCA, or Direct S/MIME | HTTPS (TLS 1.2/1.3) using standard HTTP verbs (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`) |
| Fundamental Data Unit | 3-character segments (`MSH`, `PID`, `PV1`, `OBR`, `OBX`) | RIM Classes (`Act`, `Entity`, `Role`, `Participation`) | Granular, URL-addressable Resources (`/Patient/123`, `/Observation/456`) |
| Extensibility Model | Unstandardized local Z-segments (breaks plug-and-play) | Rigid HL7 RIM derivation and template OIDs | Structured `extension[]` arrays with canonical `StructureDefinition` URLs |
| Security & Authorization | Network-level IP whitelisting, VPN tunnels, or TLS MLLP | WS-Security, SAML assertions, and X.509 certificates | OAuth 2.0, OpenID Connect, and SMART on FHIR granular scopes (`patient/Observation.read`) |
| U.S. Regulatory Mandate | Public health immunization (`VXU`), ELR (`ORU`), and syndromic (`ADT`) reporting | ONC C-CDA R2.1 transitions of care (`45 CFR § 170.315(b)(1)`) | ONC Cures Act API (`45 CFR § 170.315(g)(10)`) with US Core + CMS-0057-F APIs |
How Do You Map HL7 v2 Segments (PID, OBR, OBX) to FHIR Resources?
In HL7 v2 to FHIR conversion workflows—standardized by the official HL7 Version 2 to FHIR Implementation Guide (v2-to-FHIR IG)—a single flat HL7 v2 message (such as an `ADT^A01` admission or an ORU^R01 observation result) does not map to a single FHIR resource. Instead, an integration engine decomposes the v2 segments into a graph of interlinked FHIR resources packaged inside a FHIR Bundle (typically with `Bundle.type = “transaction”` or `”message”`):
| HL7 v2 Segment & Key Fields | Target FHIR R4 Resource | Core Field-to-Element Mapping Rules (HL7 v2-to-FHIR IG) |
|---|---|---|
MSH (Message Header)`MSH-3..6`, `MSH-7`, `MSH-9`, `MSH-10` |
Bundle & MessageHeader (plus Provenance) |
`MSH-7` (Date/Time) maps to `Bundle.timestamp`; `MSH-9` (Message Type, e.g., `ORU^R01`) maps to `MessageHeader.eventCoding`; `MSH-10` (Control ID) maps to `Bundle.identifier`; sending/receiving applications (`MSH-3..6`) map to `MessageHeader.source` and `destination`. |
PID (Patient Identification)`PID-3`, `PID-5`, `PID-7`, `PID-8`, `PID-11`, `PID-13` |
Patient |
Repeating PID-3 (CX identifier list) maps to `Patient.identifier[]` with `v2-0203` type codes (`MR`, `SS`, `PI`); `PID-5` (XPN) maps to `Patient.name[]` (`family`, `given[]`); `PID-7` maps to `Patient.birthDate` (`YYYY-MM-DD`); `PID-8` (`M/F/O/U`) maps via ConceptMap to `Patient.gender` (`male | female | other | unknown`); `PID-11` maps to `Patient.address[]`. |
PV1 (Patient Visit)`PV1-2`, `PV1-3`, `PV1-7`, `PV1-19`, `PV1-44/45` |
Encounter |
`PV1-2` (Patient Class: `I`, `O`, `E`) maps to `Encounter.class` (`IMP`, `AMB`, `EMER` from `ActEncounterCode`); `PV1-3` (Assigned Location: Point of Care/Room/Bed) maps to `Encounter.location[]`; `PV1-7` (Attending Doctor) maps to `Encounter.participant[]` (`Practitioner`); `PV1-19` (Visit Number) maps to `Encounter.identifier[]`; `PV1-44` and `PV1-45` map to `Encounter.period.start` and `end`. |
ORC & OBR (Common Order & Observation Request)`OBR-2/3`, `OBR-4`, `OBR-7`, `OBR-16`, `OBR-25` |
DiagnosticReport & ServiceRequest |
In an `ORU^R01` lab/radiology result, `OBR` maps primarily to `DiagnosticReport` (while order metadata in `ORC`/`OBR` also populates `ServiceRequest` referenced via `DiagnosticReport.basedOn`). `OBR-2` (Placer Order Number) and `OBR-3` (Filler Order Number) map to `identifier[]`; `OBR-4` (Universal Service ID, e.g., LOINC panel code) maps to `DiagnosticReport.code`; `OBR-7` maps to `effectiveDateTime`; `OBR-25` (`F`, `P`, `C`) maps to `DiagnosticReport.status` (`final`, `preliminary`, `corrected`). |
OBX (Observation / Result)`OBX-2`, `OBX-3`, `OBX-5`, `OBX-6`, `OBX-7`, `OBX-8`, `OBX-11` |
Observation (linked via `DiagnosticReport.result[]`) |
Each repeating `OBX` segment creates an individual `Observation` resource referenced in the parent `DiagnosticReport.result[]` array. `OBX-3` (Observation Identifier, LOINC) maps to `Observation.code`; `OBX-2` (Value Type) determines the polymorphic `value[x]` choice (`NM` -> `valueQuantity` paired with `OBX-6` UCUM unit; `CWE`/`CE` -> `valueCodeableConcept`; `ST`/`TX` -> `valueString`); `OBX-7` maps to `referenceRange[]`; `OBX-8` (Abnormal Flags `H`, `L`, `A`, `LL`, `HH`) maps to `interpretation[]`; `OBX-11` maps to `Observation.status`. |
NK1, AL1, DG1, IN1 |
RelatedPerson, AllergyIntolerance, Condition, Coverage |
Next of kin (`NK1`) maps to `RelatedPerson` or `Patient.contact`; allergies (`AL1`) map to `AllergyIntolerance`; diagnosis segments (`DG1`) map to `Condition` (linked via `Encounter.diagnosis[]`); insurance segments (`IN1`/`IN2`) map to `Coverage`. |
How Do Hospitals Run HL7 v2 and FHIR Side by Side?
Rather than ripping and replacing thousands of working HL7 v2 interfaces connecting laboratory analyzers, radiology PACS, bedside infusion pumps, and dietary systems, hospitals operate a hybrid coexistence architecture mediated by an enterprise healthcare integration engine (such as Mirth Connect / NextGen Connect, Rhapsody, Corepoint, or Infor Cloverleaf) and a clinical FHIR server (such as HAPI FHIR, Smile CDR, or cloud-hosted FHIR repositories):
- Intra-Hospital Real-Time Backbone (HL7 v2 over MLLP): High-throughput internal hospital sub-systems—including Admission/Discharge/Transfer (`ADT`), laboratory order/result interfaces (`ORM` / `ORU`), pharmacy medication orders (`RDE` / `RDS`), and surgical scheduling (`SIU`)—continue to communicate over low-latency MLLP/TCP connections using HL7 v2.
- Integration Engine Translation & FHIR Facade / CDR Ingestion: As HL7 v2 messages pass through the hospital interface engine, a parallel routing channel parses the ER7 segments, applies HL7 v2-to-FHIR terminology normalization (mapping local hospital lab codes to LOINC and local problem codes to SNOMED CT), resolves resource identities via conditional updates (`PUT /Patient?identifier=…`), and posts a transaction `Bundle` to the enterprise FHIR server.
- External Interoperability, SMART on FHIR Apps, and Research Queries (HL7 FHIR R4): Patient-facing mobile apps, third-party clinical decision support tools (via CDS Hooks and SMART on FHIR), payer prior authorization APIs (Da Vinci CRD/DTR/PAS), and clinical research cohort engines query the clean RESTful FHIR API (`GET /Observation?patient=123&category=laboratory`) or extract population datasets via the FHIR Bulk Data Access (`$export`) API in NDJSON format—without ever touching raw MLLP sockets or hospital Z-segments.
Frequently Asked Questions
What is the difference between HL7 v2 and FHIR?
HL7 v2 is an event-driven, pipe-delimited (`|^~&`) messaging protocol sent over persistent TCP/MLLP network sockets whenever a hospital trigger event occurs, whereas HL7 FHIR is a web-based RESTful API standard that exposes discrete, URL-addressable JSON or XML resources (`Patient`, `Encounter`, `Observation`) over HTTPS using standard HTTP verbs (`GET`, `POST`, `PUT`, `DELETE`) and OAuth 2.0 security.
How do you map HL7 v2 segments (PID, OBR, OBX) to FHIR resources?
Following the HL7 v2-to-FHIR Implementation Guide, an integration engine maps `PID` (Patient Identification) to a FHIR `Patient` resource, `PV1` (Patient Visit) to an `Encounter` resource, `OBR` (Observation Request) to a `DiagnosticReport` (and/or `ServiceRequest`) resource, and each repeating `OBX` (Observation/Result) segment to an individual `Observation` resource linked inside the `DiagnosticReport.result[]` array, packaging them into a FHIR transaction `Bundle`.
How do hospitals run HL7 v2 and FHIR side by side?
Hospitals keep HL7 v2 over MLLP as their high-speed internal messaging bus for ancillary lab, radiology, pharmacy, and ADT feeds, while using an interface engine (such as Mirth Connect or Rhapsody) or EHR FHIR facade to translate those v2 streams into FHIR R4 resources for SMART on FHIR clinician apps, patient portal APIs, payer data exchange, and clinical research analytics.







