Mirth Connect on Google Cloud Platform is the integration architecture of choice for US healthtech startups already on the Google stack. Cloud Run gives you containerized Mirth without managing persistent VMs. Cloud SQL PostgreSQL handles the backend with Regional HA and automatic failover. Secret Manager keeps credentials out of container images. And GCP's HIPAA BAA covers all of it.
But the gap between "Mirth running in GCP" and "Mirth running correctly in GCP" is wider than most teams expect. Cloud Run's scale-to-zero behavior breaks MLLP channels. Cloud SQL needs specific tuning for Mirth's connection patterns. And HIPAA compliance on GCP isn't automatic — it requires CMEK, VPC Service Controls, and Cloud Audit Logs configured correctly before you touch PHI.
This guide covers the complete production architecture: Dockerfile, Cloud SQL setup, Secret Manager integration, Cloud Run deployment flags, HIPAA configuration, and where GCP Healthcare API fits alongside Mirth — not instead of it.
GCP vs AWS vs Azure for Mirth Connect: What Actually Differs
All three major clouds run Mirth Connect. The choice usually comes down to what your team already uses. But there are real architectural differences worth knowing before you design the deployment.
AWS defaults to persistent compute. EC2 or ECS Fargate keeps a container warm at all times — simple for MLLP channels, predictable cost, no scale-to-zero surprises. ELB handles HTTP load balancing. RDS PostgreSQL handles the backend. Most Mirth-on-AWS deployments follow this pattern and it works well.
Azure fits organizations in the Microsoft ecosystem. AKS or Container Apps with Azure Database for PostgreSQL Flexible Server (zone-redundant). Azure Health Data Services provides a managed FHIR store that Mirth can write to directly. Teams already using Azure AD, Teams, and Microsoft 365 get unified identity management across their Mirth deployment.
GCP's differentiator is Cloud Run's serverless model. Pay only for compute you actually use. Variable-load environments — busy during clinic hours, quiet overnight — can see 30–40% cost reduction compared to always-on EC2 instances. The catch is the MLLP constraint described below. GCP also has the strongest managed analytics story: BigQuery integration from the Healthcare API makes GCP the natural home if your clinical data pipeline ends in population health analytics or ML models.
For a full three-way comparison with cost modeling, see the AWS vs Azure vs GCP healthcare architecture guide.
The MLLP Problem with Cloud Run (And How to Solve It)
This is the issue that burns teams who move Mirth to Cloud Run without reading the docs carefully.
Cloud Run scales to zero by default — when there's no incoming HTTP traffic, GCP terminates all running instances to save cost. For Mirth channels that receive HL7 v2 over MLLP (persistent TCP connections on port 6661), a scaled-to-zero Cloud Run service cannot accept an incoming connection. The ADT feed from the hospital's EHR tries to connect, gets a TCP reset, and the message is lost or errors.
The fix is one deployment flag:
--min-instances 1 This keeps at least one instance warm at all times and accepts persistent MLLP connections. You pay for the idle compute, but it's a small fraction of a comparable EC2 instance.
HTTP-only Mirth channels — FHIR endpoints, REST APIs, webhook receivers — are fine with scale-to-zero. Only channels with MLLP listeners need --min-instances 1.
Containerizing Mirth Connect for Cloud Run
Mirth Connect runs on Java 17. The base image should be Eclipse Temurin JRE on a minimal Linux distro — not a full JDK, and not alpine if you hit Glibc compatibility issues with JDBC drivers.
FROM eclipse-temurin:17-jre-jammy
WORKDIR /opt/connect
# Copy Mirth installation (or OIE / BridgeLink fork)
COPY connect/ /opt/connect/
COPY custom-libs/ /opt/connect/custom-lib/
# Expose admin console, HTTPS, and MLLP
EXPOSE 8080 8443 6661
# Inject credentials via environment at runtime — never bake in image
ENV DATABASE_URL="" DATABASE_USER="" DATABASE_PASSWORD=""
CMD ["./mcserver", "-console"] Build and push to Artifact Registry — not Docker Hub, which is outside your VPC perimeter:
gcloud auth configure-docker us-central1-docker.pkg.dev
docker build -t us-central1-docker.pkg.dev/PROJECT/healthcare/mirth:latest .
docker push us-central1-docker.pkg.dev/PROJECT/healthcare/mirth:latest Tag images with the Mirth version number, not just latest. Cloud Run's revision history lets you roll back to a prior image, but only if you can identify which revision ran which version.
Cloud SQL PostgreSQL: HA Configuration for Production
Never use Mirth's embedded Derby database in production. It corrupts under concurrent load and has no backup capability worth using. Cloud SQL PostgreSQL 15 with Regional HA is the correct backend for any GCP Mirth deployment.
Regional HA gives you a primary instance and a standby in a different zone within the same region. Automatic failover happens within 60 seconds if the primary becomes unavailable. For a healthcare integration engine where message loss equals missed clinical events, that matters.
gcloud sql instances create mirth-db --database-version=POSTGRES_15 --tier=db-custom-2-7680 --region=us-central1 --availability-type=REGIONAL --backup-start-time=03:00 --enable-point-in-time-recovery --network=projects/PROJECT/global/networks/healthcare-vpc --no-assign-ip --no-assign-ip is important — this gives the instance a private IP only. No public endpoint, no public exposure of your PHI database. Cloud Run connects via Cloud SQL Auth Proxy, which handles IAM authentication and encrypted tunneling automatically.
Sizing guidance: db-custom-2-7680 (2 vCPU, 7.5GB RAM) handles most mid-volume deployments up to a few hundred messages per second. If your channel count is high or you're processing large document payloads (MDM messages with Base64 PDFs), size up before go-live and check Cloud SQL's query insights for slow queries after the first week of production traffic.
Connection Pool Tuning
Mirth's default database connection pool is often too small for production. In mirth.properties, set:
database.max-connections=20 And on the Cloud SQL side, set max_connections to at least 2× your Mirth thread count. A Cloud Run instance with 2 vCPUs should not be hitting more than 10–15 concurrent database connections — if it is, something in your channel design is holding connections open longer than needed.
Secret Manager: Credentials Without Hardcoding
Database passwords, API keys, and keystore passwords should never be baked into a container image or stored in plain environment variables in the Cloud Run service definition. GCP Secret Manager solves this cleanly.
# Create the secret
echo -n 'your-db-password' | gcloud secrets create mirth-db-password --data-file=-
# Grant the Mirth service account access
gcloud secrets add-iam-policy-binding mirth-db-password --member='serviceAccount:mirth-sa@PROJECT.iam.gserviceaccount.com' --role='roles/secretmanager.secretAccessor' Then reference secrets as environment variables in the Cloud Run deployment — GCP injects them at startup, and they never appear in deployment logs or service configurations visible to other team members.
Cloud Run Deployment: Full Production Command
gcloud run deploy mirth-connect --image us-central1-docker.pkg.dev/PROJECT/healthcare/mirth:latest --platform managed --region us-central1 --min-instances 1 --max-instances 4 --memory 4Gi --cpu 2 --concurrency 80 --timeout 300 --vpc-connector healthcare-connector --vpc-egress all-traffic --service-account mirth-sa@PROJECT.iam.gserviceaccount.com --set-secrets DATABASE_PASSWORD=mirth-db-password:latest --set-secrets DB_URL=mirth-db-url:latest --no-allow-unauthenticated Key flags explained:
--min-instances 1— keeps one instance warm for MLLP connections--max-instances 4— caps horizontal scaling; Mirth's shared database state means aggressive scaling can cause contention--memory 4Gi— Mirth needs headroom for message processing; 2Gi is the minimum, 4Gi is comfortable for most workloads--vpc-connector— routes traffic through your VPC so Mirth can reach Cloud SQL private IP and on-prem systems over VPN--vpc-egress all-traffic— ensures all outbound traffic (including Cloud SQL Auth Proxy) goes through the VPC--no-allow-unauthenticated— blocks unauthenticated requests to the Mirth admin console
HIPAA Configuration on GCP: What's Required
GCP's HIPAA BAA covers the services this architecture uses: Cloud Run, Cloud SQL, Secret Manager, Cloud KMS, Cloud Storage, Artifact Registry, and Cloud Audit Logs. Signing the BAA is step one. Configuration is what actually makes the deployment HIPAA-eligible.
CMEK — Customer-Managed Encryption Keys
By default, GCP encrypts data at rest using Google-managed keys. HIPAA doesn't require CMEK, but it gives you control: you can revoke a key, rotate on your schedule, and provide evidence of key management to auditors. Enable CMEK for Cloud SQL and any Cloud Storage buckets used for message archiving.
VPC Service Controls
VPC Service Controls creates a security perimeter around your healthcare resources. Data can't be exfiltrated from Cloud SQL or Cloud Storage to resources outside the perimeter, even by a compromised service account. Configure the perimeter to include Cloud Run, Cloud SQL, Secret Manager, and Cloud Healthcare API if you're using it. This is the GCP equivalent of a network-level data loss prevention layer.
Cloud Audit Logs
Enable Admin Activity logs and Data Access logs on every service that touches PHI. Cloud Audit Logs are how you answer the HIPAA question "who accessed what, when" during an audit or breach investigation. Ship logs to a Cloud Logging sink with a long-term retention bucket in Cloud Storage — default log retention in Cloud Logging is 30 days, which is insufficient for HIPAA's 6-year retention requirement.
TLS on Every Channel
Cloud Run enforces HTTPS on its public endpoint. For MLLP channels connecting to on-prem systems via VPN, configure TLS 1.2+ in Mirth's TCP listener settings. No unencrypted HL7 in transit — this is a HIPAA Security Rule requirement, not a recommendation. See the Mirth Connect security hardening guide for the full configuration checklist.
Where GCP Healthcare API Fits Alongside Mirth Connect
A common misconception: GCP Healthcare API and Mirth Connect are alternatives. They're not. They cover different parts of the integration stack.
GCP Healthcare API provides managed storage for FHIR R4, DICOM, and HL7 v2 data — with built-in HIPAA controls, Pub/Sub notifications for event-driven architectures, and direct BigQuery export for analytics. What it doesn't do is transform data. It won't parse a non-standard HL7 message from a legacy lab system, apply business routing rules, or handle the kind of conditional logic that real-world EHR integrations require.
Mirth Connect handles the transformation layer. A typical GCP architecture looks like this:
- Hospital ADT feed → MLLP → Mirth (Cloud Run) → transform HL7 v2 to FHIR R4 → write to GCP Healthcare API FHIR store
- GCP Healthcare API fires Pub/Sub notification on new Patient resource → Cloud Function → downstream analytics pipeline → BigQuery
- FHIR store → SMART on FHIR app → patient-facing portal
Mirth does the heavy transformation. GCP Healthcare API does managed storage, search, and event emission. Both earn their place in the architecture.
Monitoring and Alerting
Cloud Run emits metrics to Cloud Monitoring automatically: request count, latency, instance count, memory utilization, and container startup latency. Set alerts on:
- Instance count dropping to zero (means MLLP channels are unreachable)
- Memory utilization above 80% (Mirth heap pressure approaching limit)
- Cloud SQL connection count approaching
max_connections - Cloud SQL failover events (zone-level failure occurred)
For Mirth-level monitoring — channel errors, message queue depth, dead-letter messages — integrate with Cloud Logging via Mirth's log4j appender. Ship Mirth application logs to Cloud Logging and build log-based alerts on error patterns. For production-grade Mirth observability patterns, see the Mirth Connect OpenTelemetry guide.



