The one-minute version: there are three Mirth-on-AWS architectures worth running. A single EC2 + RDS pattern for dev and small workloads, a Multi-AZ HA pattern behind ALB (for HTTPS) and NLB (for MLLP) for most production deployments, and an ECS Fargate pattern for container-fluent teams. Every PHI-touching service must be on the HIPAA-eligible list with a signed BAA. Set the JVM heap to 50–60% of system RAM. Use NLB for MLLP, not ALB. Move attachments to S3 with KMS. Always Multi-AZ in production. The rest of this guide is detail and rationale.
This guide pairs with our companion articles — Mirth Connect performance tuning, Mirth Connect database configuration, and Mirth Connect security and HIPAA checklist — and the broader Mirth Connect complete guide. If you'd rather hand this off, our Mirth Connect support team has run this on AWS more than 100 times.
1. Before You Start — the HIPAA-Eligible Services Question
If your Mirth Connect deployment will ever touch Protected Health Information, every AWS service you use must be on AWS's HIPAA-eligible services list, and you must have a signed Business Associate Addendum (BAA) with AWS. This is non-negotiable. Using a non-eligible service for PHI is a compliance violation regardless of how secure the configuration is.
The AWS services we'll use in this guide are all on the HIPAA-eligible list. AWS publishes the current list and reviews it regularly — verify the current status before launching.
| AWS service | What we use it for |
|---|---|
| EC2 | Mirth Connect compute (Pattern 1, 2) |
| ECS / Fargate | Containerized Mirth (Pattern 3) |
| RDS | PostgreSQL or SQL Server database |
| S3 | Attachments, channel exports, archives |
| ELB / ALB / NLB | Load balancing — ALB for HTTPS, NLB for MLLP |
| EFS | Shared persistent storage across HA nodes |
| CloudWatch | Logs, metrics, alarms |
| KMS | Encryption keys for EBS, RDS, S3 |
| Secrets Manager | Database credentials, TLS keys |
| Systems Manager | Session Manager, Parameter Store, patching |
| Route 53 | DNS, health checks, failover routing |
| VPC | Private networking, subnets, flow logs |
Sign the BAA before you provision anything that will touch PHI. AWS makes you accept it in the AWS Artifact console — it takes about 90 seconds. For the broader compliance context, see our HIPAA compliance for integration engineers primer.
2. Pattern 1 — Single Instance (Dev, Small Scale)
The simplest possible deployment. Appropriate for dev environments, proof-of-concept work, and small production deployments under 50,000 messages per day where occasional planned downtime is acceptable.
2.1 Architecture
- 1 EC2 instance running Mirth Connect
- RDS PostgreSQL (single-AZ)
- S3 for channel exports and message archives
- CloudWatch for logs and metrics
- VPC with public + private subnets
2.2 EC2 sizing
- t3.medium (2 vCPU, 4 GB RAM) — very light dev workloads
- t3.large (2 vCPU, 8 GB RAM) — typical dev/staging
- m5.large (2 vCPU, 8 GB RAM) — small production
- Always GP3 EBS, minimum 50 GB, encrypted
2.3 Install pattern
# Update and install Java 17 (Mirth 4.x requires Java 11+)
sudo dnf update -y
sudo dnf install java-17-amazon-corretto -y
# Download Mirth Connect installer
wget https://s3.amazonaws.com/.../mirthconnect-4.x.x-unix.tar.gz
tar -xzf mirthconnect-4.x.x-unix.tar.gz
# Run installer non-interactively
sudo ./mirthconnect-4.x.x-unix.sh -q
# Configure database connection
sudo nano /opt/mirthconnect/conf/mirth.properties
# Set database = postgres
# Set database.url = jdbc:postgresql://...Pros: Cheap, simple, fast to provision.
Cons: Single point of failure. Maintenance requires downtime. No horizontal scale.
This pattern is fine for dev. For production we recommend moving to Pattern 2 or 3 as soon as you have any meaningful message volume. For deeper installer detail see our Mirth Connect installation guide.
3. Pattern 2 — High Availability Behind a Load Balancer
The bread-and-butter production pattern. Suitable for organizations processing tens of thousands to low millions of messages per day, with uptime requirements that don't tolerate single-instance failure.
3.1 Architecture
- 2+ EC2 instances running Mirth Connect, in different AZs
- Application Load Balancer (ALB) for HTTP/HTTPS-based inbound channels
- Network Load Balancer (NLB) for MLLP — MLLP is TCP and ALB is HTTP/HTTPS only
- RDS PostgreSQL, Multi-AZ, with automated failover
- ElastiCache or shared EFS for shared session state (if needed)
- S3 with versioning and lifecycle policies
- CloudWatch + CloudWatch Alarms
3.2 The Mirth-and-load-balancing reality
Mirth Connect is not natively stateless across instances. By default, a channel runs on the node where it was deployed — not automatically on every node in the cluster. There are two strategies.
Strategy A — active/passive
All channels run on Node 1. Node 2 is a hot standby that takes over only if Node 1 fails. Use Route 53 health checks or an NLB target group to fail traffic over. Simpler, but you're paying for an idle node.
Strategy B — active/active with channel partitioning
Different channels run on different nodes. You decide which channels go where based on resource needs. Better resource utilization but more operational complexity, and channel state needs careful management.
For most organizations, Strategy A is the right starting point. Move to B only when message volume justifies the complexity.
3.3 EC2 sizing for production HA
- m5.xlarge (4 vCPU, 16 GB RAM) — moderate volume
- m5.2xlarge (8 vCPU, 32 GB RAM) — higher volume
- Always at least 2 instances across at least 2 AZs
3.4 Java heap sizing rule of thumb
Allocate 50–60% of system RAM to Mirth's JVM heap via the -Xmx flag in mcserver.vmoptions. Leave the other 40% for the OS, page cache, and Mirth's off-heap memory needs. We've seen heap-related production issues come from over-allocating heap more often than from under-allocating. See Mirth Connect Java heap space error for the failure modes.
4. Pattern 3 — Containerized on ECS with Auto-Scaling
For organizations comfortable with containers, this pattern offers cleaner operations, faster deployments, and easier scaling. Best fit for engineering teams that already use containers elsewhere in their stack.
4.1 Architecture
- Mirth Connect packaged in a Docker image (official image or your own)
- ECS Fargate (serverless) or ECS on EC2
- ALB for HTTPS routing, NLB for MLLP
- RDS PostgreSQL Multi-AZ
- EFS for shared persistent storage (channel exports, message attachments)
- Secrets Manager for database credentials and TLS keys
- CloudWatch Container Insights
4.2 Fargate vs. ECS-on-EC2
Fargate eliminates the need to manage EC2 hosts but costs more per CPU/RAM. It's worth it for teams that don't want to patch operating systems or manage Auto Scaling Groups. ECS on EC2 is cheaper at scale but requires you to manage the underlying hosts. For most healthcare organizations starting fresh, Fargate is the right choice. The operational simplicity pays for the premium.
4.3 Container considerations specific to Mirth
Mirth uses an embedded Jetty server and a JVM. Both behave well in containers, but watch for these:
- The JVM doesn't always detect container memory limits correctly in older Java versions. Use Java 17 (Corretto) and set
-Xmxexplicitly. - Mirth writes channel exports, attachments, and logs to the local filesystem by default. In a container, these vanish on restart unless you mount EFS or modify Mirth to write to S3.
- Mirth's clustering features assume reachability between nodes. Make sure your ECS task definitions allow nodes to discover each other (Service Discovery or AWS Cloud Map).
4.4 Dockerfile starting point
FROM amazoncorretto:17-alpine
ARG MIRTH_VERSION=4.x.x
RUN apk add --no-cache curl tar gzip \
&& curl -L https://.../mirthconnect-${MIRTH_VERSION}-unix.tar.gz \
-o /tmp/mirth.tar.gz \
&& mkdir -p /opt/mirthconnect \
&& tar -xzf /tmp/mirth.tar.gz -C /opt/mirthconnect --strip-components=1 \
&& rm /tmp/mirth.tar.gz
# Configure DB connection at runtime via env vars
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 8080 8443 6661
ENTRYPOINT ["/entrypoint.sh"]The entrypoint script reads DB credentials from Secrets Manager via the AWS SDK and writes them to mirth.properties before starting Mirth. Never bake credentials into the image.
4.5 Pattern comparison summary
| Factor | Pattern 1 (Single) | Pattern 2 (HA) | Pattern 3 (ECS) |
|---|---|---|---|
| Best fit | Dev, PoC, small prod | Most production | Container-fluent teams |
| Compute | 1× EC2 | 2+ EC2, multi-AZ | ECS Fargate or EC2 |
| Database | RDS single-AZ | RDS Multi-AZ | RDS Multi-AZ |
| MLLP load balancing | Direct EIP | NLB | NLB |
| HTTP load balancing | Direct EIP | ALB | ALB |
| Shared storage | Local EBS | S3 + EFS | EFS + S3 |
| Failover | Manual | Automatic (Multi-AZ + LB) | Automatic (ECS + Multi-AZ) |
| Ops complexity | Low | Moderate | Moderate-high |
5. Database — RDS PostgreSQL vs SQL Server vs Self-Managed
Mirth Connect supports several database backends. For AWS deployments specifically:
5.1 RDS PostgreSQL
Our default recommendation. HIPAA-eligible, fully managed, automated backups, Multi-AZ failover. Free Tier eligible for dev. Mirth runs well against it.
5.2 RDS for SQL Server
Works fine. Mirth supports it. Slightly more expensive than PostgreSQL due to Microsoft licensing pass-through. Choose only if your organization already standardizes on SQL Server.
5.3 RDS for MySQL or MariaDB
Works but we've seen more performance variability under high message-volume than with PostgreSQL. Not our first choice.
5.4 Self-managed on EC2
Don't. The operational burden outweighs any cost savings. Unless your team has specific reasons (custom extensions, audit requirements), use RDS.
5.5 RDS sizing rule of thumb
Start at db.t3.medium for dev, db.m5.large for small production, db.m5.xlarge or above for high volume. Storage starts at 100 GB GP3, encrypted, with auto-scaling enabled.
5.6 Critical RDS configurations for Mirth
max_connections— Mirth opens many concurrent connections. Default may be too low.shared_buffers— Increase from default if you have memory headroom.- Enable Performance Insights for query-level visibility.
- Enable Enhanced Monitoring at 60-second granularity.
- Set automated backups retention to at least 7 days (HIPAA typically requires 30).
For full database tuning detail, see our Mirth Connect database configuration guide.
6. Networking and Security Groups
The security group rules below assume Pattern 2. Adjust for your architecture.
6.1 Mirth instance security group
- Inbound: 8443 from ALB SG only (Mirth admin console)
- Inbound: 8080 from ALB SG only (web start client)
- Inbound: 6661 from NLB SG only (MLLP, default port — change per channel)
- Inbound: 22 from bastion SG only (SSH, ideally via Systems Manager Session Manager instead)
- Outbound: all (or restrict to specific destinations like the RDS SG)
6.2 RDS security group
- Inbound: 5432 from Mirth instance SG only
- Outbound: typically none needed
6.3 ALB security group
- Inbound: 443 from 0.0.0.0/0 (or restricted to specific IP ranges)
- Outbound: to Mirth SG
6.4 Bastion host — skip it
Skip the bastion entirely if you can. Use Systems Manager Session Managerfor SSH access — it doesn't require open SSH ports, integrates with IAM, and logs all sessions to CloudTrail. We strongly recommend this for HIPAA environments.
7. Storage — Message Attachments and Channel Exports
Mirth Connect can store message attachments in three places.
7.1 Database BLOBs
The default. Easy but bloats the database fast. Don't use this in production at any meaningful scale.
7.2 Local filesystem
Faster than DB but doesn't survive instance replacement and doesn't share across HA nodes.
7.3 S3 (or EFS) — recommended
Our recommendation. Set up an S3 bucket with encryption (SSE-KMS), versioning, and lifecycle policies. Configure Mirth's attachment handler to write to S3.
S3 lifecycle policies let you tier older message archives to S3 Glacier for compliance retention without paying full S3 storage costs. A typical pattern: standard storage for 90 days, then Glacier Instant Retrieval for 7 years.
Important: when attachments contain PHI, enable bucket-level KMS encryption with a customer-managed key (CMK), not just SSE-S3. CMK gives you key rotation control and access auditing via CloudTrail.
8. Logging and Monitoring with CloudWatch
A production Mirth deployment without proper observability is a deployment that will fail in unobservable ways. The minimum CloudWatch setup:
8.1 Logs to ship
- Mirth's own server logs (
mirth.log) - Mirth's access logs
- Channel error logs (configure error-handling channels to write to a dedicated log group)
- Operating system logs (
/var/log/messages, security logs)
Use the CloudWatch Agent on EC2 or the awslogs driver on ECS to ship logs.
8.2 Metrics to track
- CPU and memory at the instance/container level
- JVM heap usage (via CloudWatch custom metrics or a JMX-to-CloudWatch bridge)
- Channel queue depth per channel
- Channel message throughput (sent/received/error per minute)
- RDS connection count, CPU, disk IOPS, replication lag
8.3 Alarms to configure on day one
| Metric | Threshold | Why it matters |
|---|---|---|
| CPU utilization | > 80% for 5 min | Predicts overload before message queues back up |
| Memory utilization | > 85% for 5 min | JVM OOM is the most common production incident |
| JVM heap usage | > 85% for 3 min | Heap pressure causes GC pauses and channel hangs |
| RDS CPU | > 75% for 5 min | DB saturation cascades to Mirth latency |
| Channel error rate | > 1% for 5 min | Catches silent channel failures users won't report |
| Channel queue depth | Volume-based for 10 min | Backlog indicates downstream slowness |
| ALB target health | Any unhealthy | Detects instance failure before failover lag matters |
The most common production incidents — channel hangs, message backups, JVM OOM — all surface in metrics before users complain. The alarms above will catch 90% of issues hours before they become outages.
9. Backups and Disaster Recovery
9.1 Database backups
RDS automated backups, 30-day retention for HIPAA. Plus periodic manual snapshots for major changes. Test restore quarterly. A backup you've never restored is not a backup.
9.2 Channel configuration backups
Export every channel to S3 nightly via a scheduled task. This is your “infrastructure as code” for Mirth — if everything else burns down, you can rebuild from these exports. Use S3 versioning so you have point-in-time recovery.
9.3 Message store backups
Backed up via RDS automated backups. For long-term archival (7-year retention), copy completed messages to S3 with lifecycle policies that move them to Glacier.
9.4 RTO / RPO targets to design for
- RPO (recovery point objective): 5 minutes — achievable with RDS Multi-AZ and continuous backups
- RTO (recovery time objective): 1 hour for full DR — achievable with infrastructure-as-code (CloudFormation or Terraform) plus automated channel restore
If your business needs tighter targets, you're looking at cross-region replication, which is meaningful additional cost and complexity. Don't pay for it unless you actually need it.
10. TLS, Certificates, and Encryption in Transit
Every external connection to Mirth Connect must use TLS. No exceptions. HIPAA effectively requires it and there's no scenario where unencrypted PHI in transit is acceptable.
10.1 Configuration to enforce
- Disable TLS 1.0 and TLS 1.1 in Mirth's configuration (
server.propertiesor the equivalent for your version) - Enable only TLS 1.2 and TLS 1.3
- Disable weak cipher suites — start with the Mozilla “intermediate” recommended cipher list and remove anything CBC-based
10.2 Certificate management
- Use AWS Certificate Manager (ACM) for certificates that terminate at the ALB/NLB
- For certificates needed inside Mirth (e.g., for MLLP-S to external partners), use ACM Private CA or a certificate authority your partners trust
- Rotate certificates before expiration — AWS sends notifications via Personal Health Dashboard
- Never commit private keys to source control. Use Secrets Manager.
10.3 MLLP-S specifically
MLLP-S is MLLP over TLS. Most healthcare partners require it. In Mirth, you configure it via the MLLP Listener with SSL enabled. The certificates go into Mirth's keystore — managed via the Mirth admin console or via the keystore configuration in mirth.properties. See our Mirth Connect SSL/TLS hardening guide for full detail.
11. HIPAA Hardening Checklist
A condensed version of what every Mirth-on-AWS deployment needs to pass a HIPAA security review.
11.1 Identity and access
- IAM users do not exist except for break-glass; all access via IAM roles
- MFA enforced for all IAM users with console access
- Mirth admin console uses non-default admin credentials (never
admin/admin) - Strong password policy in Mirth user management
- Mirth user accounts use named individuals, not shared accounts
- Audit logging enabled in Mirth (audit logger channel)
11.2 Network
- All EC2/ECS in private subnets
- No SSH ports open to the public internet; access via Session Manager
- Security groups follow least-privilege (no
0.0.0.0/0except where business-required) - VPC Flow Logs enabled and shipped to CloudWatch or S3
- AWS Network Firewall or NACLs for additional defense in depth
11.3 Encryption
- EBS volumes encrypted with KMS
- RDS storage encrypted with KMS
- S3 buckets encrypted with KMS (customer-managed key)
- TLS 1.2+ enforced everywhere
- Mirth's database connection uses TLS to RDS
11.4 Logging and audit
- CloudTrail enabled in all regions, logs to a dedicated S3 bucket with MFA delete
- VPC Flow Logs enabled
- RDS audit logging enabled
- Mirth audit logger configured to capture user actions, channel deploys, configuration changes
- All logs retained for at least 6 years (HIPAA requirement)
11.5 Operational
- Patching process documented and executed monthly minimum
- Backup restore tested at least quarterly
- Incident response playbook exists and has been tabletop-tested
- BAA in place with AWS and any other vendors handling PHI
For the broader compliance baseline, see our Mirth Connect security and HIPAA checklist.
12. Common Pitfalls We've Hit in Production
These are real failures from real deployments. Save yourself the pain.
Pitfall 1 — Underestimating Java heap requirements
Default Mirth installations come with a 1 GB heap. Production deployments with even modest channel counts (5–10 channels at 10k+ messages/day) will OOM regularly. Set -Xmx to 4 GB minimum, scale up from there based on your monitoring.
Pitfall 2 — Storing message attachments in the database
Works fine until the database is 500 GB and queries are slow. Move attachments to S3 from day one, not “when it becomes a problem.”
Pitfall 3 — Single-AZ RDS in production
“We'll add Multi-AZ later” leads to a 30-minute outage during an AZ event two months later, which leads to an emergency Multi-AZ migration during business hours. Start Multi-AZ.
Pitfall 4 — Forgetting MLLP needs NLB, not ALB
ALB is HTTP/HTTPS only. MLLP is raw TCP. We've seen teams spend a day debugging why their MLLP listener won't receive messages through an ALB. NLB or direct EIP routing only. For the broader MLLP failure surface see Mirth Connect MLLP connection refused.
Pitfall 5 — Not testing the backup restore
Backups that haven't been restored aren't backups. Schedule quarterly restore drills to a staging environment. Almost every team that does this drill finds something wrong the first time.
Pitfall 6 — Putting credentials in mirth.properties
Database passwords, API keys, third-party credentials — these end up in plaintext config files and then in git. Use AWS Secrets Manager or Systems Manager Parameter Store with KMS encryption.
Pitfall 7 — Channel exports only on local disk
When you replace the EC2 instance, channel exports vanish. Schedule nightly channel export to S3 from day one.
Pitfall 8 — Default admin/admin credentials never changed
This is the most common audit finding in the world. Change them on first login. Force MFA if possible.
Pitfall 9 — No alarms on channel error rates
Channels fail silently and you find out from users. Alarm on error rate, queue depth, and channel state changes from day one. See Mirth Connect channel not starting for the deploy-error surface.
Pitfall 10 — Ignoring TLS cipher hardening
The default Java cipher list includes weak suites. OCR auditors check this. Configure explicit allow-lists.
13. Frequently Asked Questions
Is Mirth Connect on AWS HIPAA-compliant out of the box?
No. AWS gives you HIPAA-eligible services and a signed BAA, but compliance comes from how you configure them. You must encrypt data at rest and in transit, restrict network access, use IAM least-privilege, enable audit logging, and run on the HIPAA-eligible subset of AWS services. The hardening checklist in this guide covers the minimum bar.
Which AWS deployment pattern should I start with?
For dev and proof-of-concept, Pattern 1 (single EC2 + single-AZ RDS) is fine. For any production deployment touching PHI, start with Pattern 2 (HA across two AZs, Multi-AZ RDS, NLB for MLLP). Move to Pattern 3 (ECS Fargate) only if your team already operates containers elsewhere — it's a step up in operational sophistication, not a starting point.
Can I load balance MLLP traffic to Mirth on AWS?
Yes, but you need a Network Load Balancer (NLB), not an Application Load Balancer (ALB). MLLP is raw TCP, and ALB is HTTP/HTTPS only. Use ALB for the Mirth admin console and web start client, and NLB for MLLP listeners. This is the single most common configuration mistake we see in AWS Mirth deployments.
Should I run Mirth Connect on EC2 or ECS Fargate?
EC2 is the simpler starting point and what most healthcare clients run today. ECS Fargate is cleaner operationally — no host patching, easier auto-scaling, faster deployments — but it assumes container fluency on your team. If your team is already deploying other services on Fargate, use Fargate. Otherwise, EC2 with a well-built AMI gets you to production faster.
What database should I use for Mirth Connect on AWS?
RDS PostgreSQL, Multi-AZ, encrypted with KMS. It's HIPAA-eligible, fully managed, and Mirth runs against it well. RDS for SQL Server works fine but costs more due to Microsoft licensing. Avoid self-managing your database on EC2 — the operational burden isn't worth the marginal cost savings.
How do I size the EC2 instance for Mirth Connect?
For dev: t3.large (2 vCPU, 8 GB RAM). For small production: m5.large. For moderate volume: m5.xlarge (4 vCPU, 16 GB RAM). For higher volume: m5.2xlarge or larger. Set the JVM heap (-Xmx) to 50–60% of system RAM. Heap sizing matters more than CPU for most Mirth workloads — under-allocating heap is the single most common cause of OOM in production.
Where should Mirth Connect store message attachments on AWS?
S3 with SSE-KMS encryption using a customer-managed key. Configure Mirth's attachment handler to write to S3 rather than the database or local disk. Database storage bloats the DB; local disk doesn't survive instance replacement or share across HA nodes. Apply S3 lifecycle policies to tier older attachments to Glacier for long-term compliance retention.
Do I need a bastion host for SSH access to Mirth on AWS?
No, and you shouldn't run one. Use AWS Systems Manager Session Manager — it gives you shell access without exposing SSH ports, integrates with IAM, logs every session to CloudTrail, and removes a whole class of bastion-host vulnerability. We strongly recommend Session Manager for any HIPAA environment.
How do I back up Mirth on AWS?
Three layers. (1) RDS automated backups with 30-day retention for HIPAA, plus periodic manual snapshots. (2) Nightly channel exports written to a versioned S3 bucket — this is your infrastructure-as-code for Mirth. (3) Long-term message archive to S3 Glacier via lifecycle policies, typically 7-year retention. Test the restore quarterly — a backup you've never restored is not a backup.
What's the most expensive mistake teams make deploying Mirth on AWS?
Two compete for the title. The first is storing message attachments in the database — works fine until the DB is 500 GB and slow. The second is single-AZ RDS in production — saves a few hundred dollars a month, costs you a 30-minute outage during the next AZ event. Both are easy to fix on day one and painful to fix later.
Next Steps
Building Mirth on AWS is one of those problems where the official documentation gets you to a working installation but not to a production-ready system. The gap between those two states is where most of the real work happens.
If you'd rather not figure out heap tuning, MLLP load balancing, and S3 attachment offload from scratch, we've done this enough times to have it dialed in. Run our pricing calculator to estimate what a managed AWS deployment of Mirth would cost, or book a 30-minute scoping call.
If you'd like an outside set of eyes on a Mirth Connect deployment you've already built, our free Mirth health check covers exactly this — AWS configuration review, security posture, and HIPAA readiness.
Related Reading
- Mirth Connect: The Complete Guide
- Mirth Connect Database Configuration
- Mirth Connect Performance Tuning
- Mirth Connect Java Heap Space Error
- Mirth Connect SSL/TLS Hardening
- Mirth Connect Security and HIPAA Checklist
- Mirth Connect MLLP Connection Refused
- Mirth Connect Channel Not Starting
- Mirth Connect Installation Guide
- Healthcare Interoperability & Compliance Guide