MLLP stands for Minimal Lower-Layer Protocol, and it is the wire format that carries HL7v2 messages between systems. It was designed for TCP transport in the 1990s, and every serious HL7v2 integration still uses it today. FHIR REST endpoints have not replaced MLLP; they have added a second transport for a different set of use cases. Both live in production, and integration engineers meet MLLP first.
Naming the framing is the discipline. For related walkthroughs, FHIR background reading collects the surrounding material.
What MLLP Actually Does
MLLP wraps an HL7v2 message with three control characters:
- SB (start block,
,0x0B) at the beginning. - EB (end block,
,0x1C) at the end. - CR (carriage return,
0x0D) after EB.
The wrapper delimits the message boundaries so the receiver knows where each message starts and ends. A pass through the site's HL7 v2 segment → FHIR mapping tool surfaces the HL7v2 payload that MLLP frames.
Why the Wrapper Matters
TCP is a streaming protocol; it does not preserve message boundaries. Two v2 messages sent back-to-back arrive as a single byte stream. Without MLLP's SB and EB markers, the receiver would have no way to know where one message ends and the next begins.
The wrapper is small and cheap. It is also the difference between a receiver that parses messages correctly and one that produces garbage when two messages arrive close together.
The Connection Model
MLLP typically uses a persistent TCP connection between sender and receiver. The sender opens the connection, sends messages, waits for ACKs, and eventually closes. Some deployments use per-message connections; most use long-lived ones.
Persistent connections carry state that per-message connections do not. Reconnect logic matters; keepalive intervals matter; TLS session reuse matters. For the ACK-side story, acknowledgment codes: AA vs AE vs AR in production covers what travels back over the same connection.
The Retry Behavior
When a message send fails (connection drop, timeout, error), the sender retries per its policy. MLLP itself does not specify retry semantics; that is a sender-side decision.
Common retry policies use exponential backoff with a cap. Every deployment should name its retry policy explicitly. Silent retry policies produce inconsistent behavior across incidents.
TLS Everywhere in Modern Deployments
MLLP originally ran on plain TCP. Modern deployments run MLLP over TLS (sometimes called MLLPS or MLLP/TLS). The wrapper stays the same; the transport is encrypted.
TLS certificates matter for peer authentication. Bidirectional certificate validation (mTLS) is common in high-security environments. Deployments that skip mTLS accept a lower security posture; deployments that use it face certificate rotation as an operational task.
Encoding Gotchas
MLLP does not specify a text encoding. HL7v2 messages are almost always ASCII or UTF-8, but some legacy systems use ISO-8859-1 or code pages. The MSH-18 field declares the character set; parsers should honor it.
For the MSH-side detail, MSH segment: the header that decides how the rest is parsed covers the fields that shape parsing.
The FHIR Interop Story
Every FHIR-first shop eventually connects to a v2-first partner. MLLP is the connection point. The pattern is: MLLP ingress → v2 parser → v2-to-FHIR mapping → FHIR storage. For the shape of the messages that flow through, reading an HL7v2 message when you only know FHIR is the accompanying reference.
MLLP is not going away. Every integration engineer should be able to write a working MLLP client and server.

Sources
- HL7 canonical product overview referencing MLLP transport - HL7 canonical product overview referencing MLLP transport for v2 messaging
