Healthcare/Definitions
Glossary

HL7 vs FHIR vs MLLP - definitions

The vocabulary of healthcare integration, defined directly - what HL7 v2 is, what FHIR is, what MLLP is, how they relate and what each looks like in Python.

1987HL7 v2 first released
R4most widely deployed FHIR version
MLLPthe v2 transport
both_worlds.py
# -*- coding: utf-8 -*-

# Zato
from zato.hl7v2 import parse_hl7
from zato.server.service import Service

class BothWorlds(Service):
    name = 'demo.glossary.both-worlds'

    def handle(self) -> 'None':

        # HL7 v2 - pipe-delimited segments
        msg = self.request.input
        family_name = msg.pid.patient_name.family_name

        # FHIR - JSON resources over REST
        client = self.fhir['FHIR.Sample']

        patient = client.resources('Patient').search(
            family = family_name,
        ).first()

        self.logger.info('Found %s', patient['id'])

What is HL7 v2?

HL7 v2 is the messaging standard hospital systems have exchanged clinical events in since 1987 - a patient is admitted, a lab result is ready, an order is placed, and a message goes out. Messages are plain text in the ER7 encoding - segments separated by carriage returns, fields separated by pipes - a format that has remained stable across versions.

Each line is a segment - MSH is the header, PID the patient, PV1 the visit, OBX a result - and each segment is a sequence of fields with positions defined by the standard. Message types like ADT^A01 (admission) or ORU^R01 (results) say which segments to expect.

adt_a01.hl7
MSH|^~\&|SENDER|FACILITY|RECEIVER|FAC|20260315||ADT^A01^ADT_A01|CTL001|P|2.9
EVN|A01|20260315
PID|1||12345^^^HOSP^MR||SMITH^JOHN^A||19800115|M
PV1|1|I|WARD^101^BED1

In Python, parse_hl7(raw) turns that text into a typed object where message.pid.patient_name.family_name is 'SMITH' - the receiving HL7 v2 guide shows the full flow.

What is FHIR?

FHIR - Fast Healthcare Interoperability Resources - is the modern HL7 standard, built on REST and JSON instead of custom encodings. Data is modeled as resources - Patient, Observation, Encounter, MedicationRequest - each a JSON document with a defined structure, exchanged over regular HTTP with searches, reads and writes.

FHIR R4, released in 2019, is the most widely deployed version in production - US and European regulation references it, EHR vendors expose it and the national programs described across this site build on it. R5 has seen little adoption to date, with many vendors waiting for a future R6.

patient.json
{
    "resourceType": "Patient",
    "id": "example",
    "identifier": [
        {"system": "urn:mrn", "value": "12345"}
    ],
    "name": [
        {"family": "SMITH", "given": ["JOHN"]}
    ],
    "birthDate": "1980-01-15",
    "gender": "male"
}

In Python, a FHIR server is a connection - client = self.fhir['FHIR.Sample'] - and resources are searched, read and saved through it, as the FHIR documentation covers.

What is MLLP?

MLLP - the Minimal Lower Layer Protocol - is the transport HL7 v2 messages travel over. It is a thin framing on top of TCP - a start byte (0x0B), the message, an end pair (0x1C 0x0D) - so receivers know where one message ends and the next begins on a long-lived connection.

MLLP is not a message format - it delivers ER7 text - and it has no security of its own, which is why production deployments wrap it in TLS. Every message is answered with an acknowledgment, an ACK, and senders retransmit when none arrives.

In Zato, inbound MLLP is a channel - framing, parsing and ACKs handled for you - and outbound MLLP is self.mllp['connection-name'].send(data).

How do HL7 v2, FHIR and MLLP relate?

The three answer different questions. HL7 v2 and FHIR are data standards - two generations of an answer to "how is clinical information represented?". MLLP is a transport - an answer to "how do the bytes move?" - and it pairs with HL7 v2 the way HTTP pairs with FHIR.

TermKindPairs withOne-line definition
HL7 v2Data standardMLLPPipe-delimited clinical event messages, 1987 onward
FHIRData standardHTTP and RESTJSON resources exchanged over web APIs
MLLPTransportHL7 v2TCP framing that v2 messages travel over
ER7EncodingHL7 v2The pipe-and-caret text encoding of v2 messages
Segmentv2 structureHL7 v2One line of a v2 message - MSH, PID, OBX
ResourceFHIR structureFHIROne JSON document - Patient, Observation
ACKv2 messageMLLPThe acknowledgment every v2 message is answered with
CDADocument standardHL7 v3XML clinical documents, predecessor generation to FHIR

"HL7 vs FHIR" is therefore not a comparison between two competing products - FHIR is an HL7 standard too - and most production systems run both - v2 feeds inside the hospital, FHIR at the edges - which is what the v2 to FHIR mapping reference and the FHIR facade pattern are for.

Frequently asked questions

At the edges, yes - new regulatory programs and patient-facing APIs are FHIR. Inside hospitals, v2 feeds remain in production and the systems emitting them are expected to stay in service for years, so integration layers support both for the foreseeable future.

It saw limited adoption outside national programs built during its era - Finland's Kanta being the largest example - and HL7 moved on to FHIR. Its document format, CDA, remains widespread and is being superseded by FHIR documents.

No - plain MLLP is cleartext TCP. Production traffic between organizations runs MLLP over TLS, or inside VPNs when both ends are within one network boundary.

No port is reserved for it - 2575 is a common convention and every deployment chooses its own per channel.

Ready to put the vocabulary to work?

Get started with Zato and connect HL7 v2 and FHIR systems in minutes.

Open source In Python