Every hospital IT team has one: the interface backlog. A spreadsheet, a Jira board, or a stack of requests from clinical departments, all waiting for HL7 connections between systems that need to talk to each other. The lab needs results flowing to the EHR. Radiology wants orders from the HIS. The billing system needs ADT events. The pharmacy needs medication orders. And every one of these interfaces is "urgent."
The typical health system has 20-50 pending interface requests at any given time. Each custom-built interface takes 8-12 weeks with traditional development. At that rate, the backlog grows faster than you can clear it. New system purchases, vendor upgrades, regulatory requirements, and clinical workflow changes generate new interface requests faster than a team of 2-3 integration engineers can deliver them.
Mirth Connect (now NextGen Connect Integration Engine) changes this math fundamentally. With the right approach, a single interface engineer can build, test, and deploy an HL7v2 interface in 2-5 days instead of 8-12 weeks. This guide covers the specific channel configurations, message type templates, and the 90-day playbook we use to eliminate interface backlogs for healthcare organizations.
Why Interface Backlogs Exist (And Why Custom Code Makes Them Worse)
Interface backlogs are not a staffing problem. They are an architecture problem. When every HL7 interface is built as custom code, each interface becomes a unique snowflake:
- Custom socket handlers for TCP/MLLP connections
- Custom parsers for each HL7 message type and version
- Custom mapping logic hard-coded for specific source and destination systems
- Custom error handling and retry logic
- Custom logging that may or may not be sufficient for troubleshooting
Every "custom" in that list multiplies development time, testing effort, and maintenance burden. When the lab vendor upgrades their system and changes the OBX segment structure, somebody has to find the custom code, understand it, modify it, and test it. If that person has left the organization, you are reverse-engineering a codebase you did not write.
Mirth Connect replaces all of this with a standardized architecture where every interface follows the same pattern: source connector, transformer, destination connector. The custom work is reduced to field mapping and business rules. Everything else is handled by the platform.
The 8 HL7v2 Message Types That Cover 90% of Hospital Interfaces
Before diving into Mirth configurations, you need to understand which message types drive the backlog. In our experience across dozens of healthcare integration projects, eight HL7v2 message types account for approximately 90% of all interface requests:
ADT (Admit/Discharge/Transfer) — The Foundation
ADT messages are the backbone of hospital integration. Every system needs to know when a patient is admitted (A01), transferred (A02), discharged (A03), registered (A04), or updated (A08). If you can only build one interface template, make it ADT.
Common ADT events: A01 (Admit), A02 (Transfer), A03 (Discharge), A04 (Register), A05 (Pre-Admit), A08 (Update Patient Info), A11 (Cancel Admit), A13 (Cancel Discharge), A28 (Add Person), A31 (Update Person)
// Sample ADT^A01 message structure
MSH|^~\&|HIS|HOSPITAL|LAB|HOSPITAL|202603141030||ADT^A01|MSG00001|P|2.5
EVN|A01|202603141030
PID|1||MRN12345^^^HOSP^MR||SHARMA^RAJESH||19750315|M|||123 MG ROAD^^MUMBAI^MH^400001
PV1|1|I|ICU^301^1^^^HOSP||||DOC001^PATEL^ANITA|||MED||||ADM|A0||VN123456 ORM (Order Message) — Lab and Radiology Orders
ORM messages trigger lab tests, radiology exams, and procedure orders. The HIS sends an ORM to the lab system when a doctor orders a CBC. The lab system sends an ORM to the radiology department when a CT scan is ordered.
ORU (Observation Result) — Results Delivery
ORU messages deliver lab results, radiology reports, and clinical observations back to the ordering system. This is typically the highest-volume interface in a hospital. A busy lab produces hundreds of ORU messages per day. These messages carry the OBX (Observation) segments with actual result values, units, reference ranges, and abnormal flags.
MDM (Medical Document Management) — Clinical Documents
MDM messages transmit clinical documents: discharge summaries, operative notes, consultation reports. The document content is typically embedded as base64-encoded text in the OBX segment or referenced as a URL to the document management system.
SIU (Scheduling Information) — Appointments
SIU messages manage appointment scheduling between the HIS scheduling module and departmental systems (radiology, outpatient clinics, procedure rooms). Events include S12 (New Appointment), S13 (Rescheduled), S14 (Modified), S15 (Cancelled).
DFT (Detailed Financial Transaction) — Charges
DFT messages transmit charge events from clinical systems to the billing system. Every lab test, radiology exam, procedure, and medication dispensed generates a charge that must flow to billing.
Anatomy of a Mirth Connect Channel
Every Mirth channel follows the same architecture, regardless of the interface type:
Source Connector
Receives the incoming message. For HL7v2, this is almost always a TCP/MLLP Listener on a specific port. Configuration is minimal:
Source Connector: TCP Listener
Mode: MLLP (Minimal Lower Layer Protocol)
Address: 0.0.0.0 (listen on all interfaces)
Port: 6661 (unique per channel)
Receive Timeout: 0 (no timeout)
Max Connections: 10
Response: Auto-generate ACK Source Transformer
Processes the incoming message before routing. This is where you:
- Validate the message structure (reject malformed messages with a NAK)
- Extract routing fields (message type, sending facility, patient class)
- Apply global transformations (date format standardization, code table lookups)
- Set channel variables for use in destinations
// Source transformer: Extract routing info and validate
var msgType = msg['MSH']['MSH.9']['MSH.9.1'].toString();
var triggerEvent = msg['MSH']['MSH.9']['MSH.9.2'].toString();
var sendingFacility = msg['MSH']['MSH.4']['MSH.4.1'].toString();
// Set channel variables for routing
channelMap.put('messageType', msgType);
channelMap.put('triggerEvent', triggerEvent);
channelMap.put('facility', sendingFacility);
// Validate required fields
if (!msg['PID']['PID.3']['PID.3.1'].toString()) {
throw new Error('Missing patient MRN in PID.3');
} Destination Connector
Sends the transformed message to the target system. Common destination types:
- TCP Sender (MLLP): Send HL7v2 to another HL7 listener
- HTTP Sender: POST to a REST API (useful for HL7v2-to-FHIR conversion)
- Database Writer: Insert directly into a database table
- File Writer: Write to a file system (for batch processing systems)
- JavaScript Writer: Execute custom logic for complex integrations
Destination Transformer
Transforms the message for the specific destination. This is where the actual field mapping lives. Each destination can have its own transformer, allowing a single source message to be routed to multiple destinations with different transformations.
// Destination transformer: Map fields for target system
// The target system uses a different patient ID field
tmp['PID']['PID.3']['PID.3.1'] = msg['PID']['PID.3']['PID.3.1'].toString();
tmp['PID']['PID.3']['PID.3.4'] = 'TARGET_MRN';
// Map location code
var sourceLocation = msg['PV1']['PV1.3']['PV1.3.1'].toString();
var targetLocation = lookupLocationCode(sourceLocation);
tmp['PV1']['PV1.3']['PV1.3.1'] = targetLocation;
// Add custom Z-segment if target system requires it
createSegment('ZPI', tmp);
tmp['ZPI']['ZPI.1'] = 'CUSTOM_FIELD_VALUE'; Building Your First Interface Template: ADT
The ADT interface template is the foundation. Once you have this working, every other message type follows the same pattern with different field mappings.
Step 1: Create the Channel
Channel Name: ADT_HIS_TO_LAB
Channel Description: ADT events from Hospital Information System to Laboratory System
Source Connector: TCP Listener, Port 6661
Destination: TCP Sender to Lab System at 10.0.1.50:7001
Message Storage: Production (stores message metadata, not raw content)
Queue: Enabled (destination queue for delivery assurance) Step 2: Configure the Source Filter
Not every ADT event needs to go to the lab. Filter to only pass relevant events:
// Source filter: Only pass ADT events the lab cares about
var triggerEvent = msg['MSH']['MSH.9']['MSH.9.2'].toString();
var relevantEvents = ['A01', 'A02', 'A03', 'A04', 'A08'];
// Return true to process, false to filter out
return relevantEvents.indexOf(triggerEvent) !== -1; Step 3: Build the Field Mapping
This is where you map fields from the source format to the destination format. Create a mapping document first:
Field Mapping: HIS ADT -> Lab System
-----------------------------------------
Source | Destination | Notes
MSH.3 (Sending App) | MSH.3 = 'HIS' | Static value
MSH.5 (Receiving App) | MSH.5 = 'LAB_SYS' | Static value
PID.3 (Patient ID) | PID.3 (MRN) | Direct map
PID.5 (Patient Name) | PID.5 | Direct map
PID.7 (DOB) | PID.7 | Reformat: YYYYMMDD -> YYYY-MM-DD
PID.8 (Gender) | PID.8 | Map: M/F -> MALE/FEMALE
PV1.2 (Patient Class) | PV1.2 | Map: I->INPATIENT, O->OUTPATIENT
PV1.3 (Location) | PV1.3 | Lookup: source code -> lab location code
PV1.7 (Attending Dr) | PV1.7 | Direct map
PV1.19 (Visit Number) | PV1.19 | Direct map Step 4: Error Handling
Every channel needs an error handling strategy. Configure the destination queue for retry and set up an error channel:
Destination Queue Settings:
Queue Enabled: Yes
Retry on Error: Yes
Retry Count: 5
Retry Interval: 30000 ms (30 seconds)
Rotate Queue: Yes (try next message if current one fails)
Error Channel Configuration:
Route errors to a dedicated error handling channel
Error channel writes to: Database table (for monitoring dashboard)
Error alerts: Email notification after 3 consecutive failures
Include: Original message, error description, timestamp, channel name Template-Based Scaling: Building 5 Interfaces per Week
Once your ADT template is proven, building additional interfaces becomes formulaic:
- Clone the ADT channel as a starting point for each new interface
- Change the source/destination connectors (ports, IP addresses)
- Update the field mapping for the specific message type
- Adjust the source filter for relevant events
- Test with sample messages from the source system
- Deploy to production with monitoring
An experienced Mirth engineer can build a standard interface (ADT, ORM, ORU) in 4-8 hours using templates. Complex interfaces with custom business logic (DFT with charge calculation, MDM with document formatting) take 2-3 days. At this rate, a team of 2 engineers can deliver 5-10 interfaces per week, clearing a 37-interface backlog in under 8 weeks.
The 90-Day Backlog Elimination Playbook
Weeks 1-2: Foundation
- Day 1-2: Install Mirth Connect, configure database (PostgreSQL recommended for production), set up monitoring and alerting
- Day 3-5: Build the ADT template channel. Test with sample messages from your HIS. Validate ACK/NAK handling
- Day 6-8: Build ORM and ORU template channels. These three cover the majority of interface types
- Day 9-10: Deploy first 2-3 production interfaces using templates. Validate end-to-end message flow
Weeks 3-6: Rapid Build
- Prioritize remaining backlog by clinical impact: patient safety first, then operational efficiency, then nice-to-have
- Clone templates and customize for each interface. Target 3-5 new interfaces per week
- Run parallel testing: new Mirth channel alongside existing interface (if any) to validate results match
- Weekly deployments to production after testing sign-off
- Build a shared code library for common transformations: date format converters, code table lookups, patient identifier mapping
Weeks 7-12: Scale and Optimize
- Complete remaining interfaces including complex types (DFT, SIU, MDM)
- Performance tuning: optimize for throughput if message volumes are high
- Set up the monitoring dashboard showing message counts, error rates, queue depths, and processing times per channel
- Document every channel: source system, destination system, message types, field mappings, business rules
- Train the operations team on channel management, log review, and common troubleshooting procedures
Common Pitfalls and How to Avoid Them
Pitfall 1: One Giant Channel for Everything
New Mirth developers often create a single channel that receives all message types and routes internally. This becomes unmanageable quickly. Instead, use one channel per interface pair per message category. ADT from HIS to Lab is one channel. ORM from HIS to Lab is another. This isolation means a problem with one interface does not affect others.
Pitfall 2: Storing Raw Messages in Production
Mirth's message storage levels have a direct impact on performance and disk usage. In production, use the "Production" storage level (stores metadata but not raw message content) or even "Metadata Only" for high-volume channels. The "Development" level stores everything and will fill your database disk in weeks at production volumes. See our top 10 Mirth integration failures guide for more on this.
Pitfall 3: No Error Channel
Every production Mirth deployment needs a dedicated error handling channel that captures failed messages, logs them to a database, and sends notifications. Without this, messages fail silently and nobody knows until a clinician reports missing data.
Pitfall 4: Hard-Coded Values in Transformers
Do not hard-code IP addresses, port numbers, facility names, or code mappings directly in transformer JavaScript. Use Mirth's Global Map or Configuration Map for values that change between environments (dev/test/prod). Use Code Template Libraries for reusable transformation functions.
Pitfall 5: Not Testing with Real Data Volume
An interface that works with 10 test messages may fail at 10,000 messages per hour. Before deploying to production, run a load test with realistic message volumes for at least 24 hours. Check database growth, memory usage, queue depth, and processing latency under sustained load.
Connecting to the Bigger Picture
HL7v2 interfaces are not going away. Despite FHIR adoption accelerating, the installed base of HL7v2 systems in hospitals is massive. But the two standards are not mutually exclusive. Mirth Connect can transform HL7v2 messages into FHIR resources, acting as a bridge between legacy systems and modern APIs.
This is the architecture we recommend: use Mirth to receive HL7v2 from legacy systems, transform to FHIR, and expose via RESTful APIs. New systems connect via FHIR. Old systems connect via HL7v2 through Mirth. Over time, as legacy systems are replaced, the HL7v2 channels are retired. The FHIR APIs persist. Read more about this approach in our guide on healthcare integration architecture with Mirth and Kafka.
Frequently Asked Questions
Is Mirth Connect still open source?
Mirth Connect's licensing changed with version 4.6. The core engine remains available, but NextGen Healthcare now offers commercial licensing for production use. For details on migration strategies, see our Mirth Connect commercial transition guide. Alternative open-source options exist, but Mirth's installed base and community make it the pragmatic choice for most healthcare organizations.
How many interfaces can one Mirth instance handle?
A properly configured Mirth instance on a 4-core, 16GB server can handle 50-100 channels processing several thousand messages per hour. For larger deployments, use Mirth's clustering and high availability features. Most hospitals never outgrow a single instance.
Do we need a dedicated integration engineer?
Yes, for any hospital with more than 10 interfaces. Mirth dramatically reduces per-interface build time, but somebody still needs to understand HL7v2 message structures, manage the Mirth server, troubleshoot failed messages, and coordinate with vendor technical teams. A single experienced integration engineer can manage 50+ Mirth channels.
Can Mirth handle non-HL7 integrations?
Yes. Mirth supports TCP/MLLP, HTTP/REST, SOAP, JDBC (database), file system, DICOM, and email connectors. It can also process JSON, XML, delimited text, and fixed-width formats. This makes it useful for vendor integrations that do not use HL7 (many Indian HIS vendors use proprietary APIs or CSV exports).
How do we handle HL7 version differences between systems?
This is one of Mirth's core strengths. The source system sends HL7 v2.3, the destination expects v2.5. The Mirth transformer maps fields between versions, adds missing segments, and reformats data as needed. You do not need both systems on the same HL7 version because Mirth translates between them.
The Bottom Line
An HL7v2 interface backlog is a solved problem. Mirth Connect, properly implemented with channel templates and a systematic rollout plan, reduces interface build time from weeks to days. A 37-interface backlog that would take 18 months with custom development can be eliminated in 90 days with Mirth.
The key is not the technology itself but the approach: build reusable templates for ADT, ORM, and ORU first. Clone and customize for each new interface. Use consistent naming conventions, error handling patterns, and monitoring. Avoid the common pitfalls that turn a simple integration into a maintenance nightmare.
If your hospital or healthcare product has a growing interface backlog, the question is not whether to use an integration engine. It is how quickly you can get one running. Every week of backlog is a week where clinical systems are not talking to each other, data is being re-entered manually, and your IT team is writing custom code that will need to be maintained forever.



