Self-Host Mautic: Open Source Marketing Automation 2026
How to Self-Host Mautic: Open Source Marketing Automation in 2026
TL;DR
HubSpot Marketing Professional costs €880/month and locks your contacts in a proprietary system. Mautic is the open source alternative — the world's largest open source marketing automation platform, with 9,300+ GitHub stars, Apache 2.0 license, and unlimited contacts for the price of a VPS. It does email campaigns, contact scoring, visual campaign builder, landing pages, multi-channel automation, and CRM integration — all self-hosted, data on your servers. The break-even vs HubSpot happens around 40,000 contacts. If you're technically capable, this guide has a production Mautic instance running in 30 minutes.
Key Takeaways
- Open source marketing automation: email, SMS, social, push notifications — all in one self-hosted platform
- 9,300+ GitHub stars: the most-starred open source marketing automation project, 1,000+ contributors
- Unlimited contacts: Mautic doesn't meter contacts — you pay for infrastructure, not databases
- Visual campaign builder: drag-and-drop automation workflows with conditional branching, delays, and multi-channel actions
- PHP/Symfony stack: mature, battle-tested — version 7.x in active development as of 2026
- GDPR-friendly by design: host in EU, no third-party tracking, full data portability
- 3-year cost vs HubSpot: ~€58,000 vs €135,000 — a 57% reduction for mid-market teams
Why Teams Choose Mautic Over HubSpot
HubSpot is a well-engineered product. It's also a pricing trap that gets more expensive as you grow — the exact moment you need it most.
HubSpot Marketing Hub Professional starts at €880/month. By the time you factor in implementation, onboarding, and scaling to 50,000+ contacts, real-world spend averages €15,000–€45,000/year. Enterprise tier starts at €3,530/month. And your contacts, email templates, workflows, and behavioral data all live in HubSpot's cloud — migration out is deliberately painful.
Mautic inverts the model. The software is free. You pay for infrastructure (a $20-50/month VPS), email delivery (AWS SES at $0.10/1,000 emails), and your own time or an agency's time to maintain it. At 10,000 contacts: Mautic costs ~$300/month, HubSpot costs $890+/month. At 100,000 contacts: Mautic costs ~$300/month, HubSpot costs thousands.
The trade-off is real: Mautic requires PHP/server administration skills, proactive maintenance, and email deliverability management. HubSpot works out of the box. But for technically capable teams or agencies managing multiple clients, the economics strongly favor self-hosting.
| Feature | Mautic (Self-hosted) | HubSpot Professional | ActiveCampaign |
|---|---|---|---|
| Monthly cost (10k contacts) | ~$100-300 (infra) | $890 | $149 |
| Monthly cost (100k contacts) | ~$300 (infra) | $3,500+ | $499 |
| Contact limit | Unlimited | Per-tier limit | Per-tier limit |
| Data ownership | ✅ Your servers | ❌ HubSpot cloud | ❌ AC cloud |
| Visual campaign builder | ✅ | ✅ | ✅ |
| Email A/B testing | ✅ | ✅ | ✅ |
| Contact scoring | ✅ | ✅ Professional+ | ✅ Plus+ |
| Landing pages | ✅ | ✅ | ✅ |
| SMS/push notifications | ✅ (plugins) | ✅ Enterprise | ✅ |
| CRM integration | ✅ Salesforce, Sugar | ✅ Native | ✅ Native |
| GDPR/EU hosting | ✅ Full control | ⚠️ US-based | ⚠️ US-based |
| Open source | ✅ Apache 2.0 | ❌ | ❌ |
System Requirements
Mautic is a PHP application backed by MySQL/MariaDB. Resource needs scale with your contact list size and email volume.
Minimum for small lists (< 50,000 contacts):
- CPU: 2 vCPU
- RAM: 2GB (4GB recommended)
- Storage: 20GB SSD
- PHP: 8.1+
- MySQL: 8.0+ or MariaDB 10.5+
Recommended for mid-size lists (50K–500K contacts):
- CPU: 4 vCPU
- RAM: 8GB
- Storage: 50GB+ SSD (email attachments and contact data accumulate)
- Dedicated cron worker container for queue processing
Infrastructure for production:
- Hetzner CX22: 2 vCPU, 4GB RAM, €4.35/month — small lists
- Hetzner CX32: 4 vCPU, 8GB RAM, €8.70/month — mid-size lists
- Separate transactional email service: AWS SES, Mailgun, SendGrid, Postmark
Ports to open: 80, 443
Self-Hosting with Docker Compose
The Stack
Mautic 5+ with Docker Compose runs four containers:
mauticdb— MySQL databasemautic_web— PHP-FPM + Mautic applicationmautic_worker— background job processor (handles queued emails)mautic_cron— scheduled task runner (contact scoring, campaign triggers)
docker-compose.yml
version: "3.8"
services:
mauticdb:
image: mysql:8.0
container_name: mauticdb
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: mautic
MYSQL_USER: mautic
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "mautic", "-p${MYSQL_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
mautic_web:
image: mautic/mautic:5-apache
container_name: mautic_web
volumes:
- mautic_data:/var/www/html
environment:
MAUTIC_DB_HOST: mauticdb
MAUTIC_DB_PORT: 3306
MAUTIC_DB_DATABASE: mautic
MAUTIC_DB_USER: mautic
MAUTIC_DB_PASSWORD: ${MYSQL_PASSWORD}
MAUTIC_RUN_CRON_JOBS: "false" # Handled by dedicated cron container
MAUTIC_TRUSTED_PROXIES: "0.0.0.0/0" # Adjust for your reverse proxy
ports:
- "80:80"
depends_on:
mauticdb:
condition: service_healthy
restart: unless-stopped
mautic_worker:
image: mautic/mautic:5-apache
container_name: mautic_worker
volumes:
- mautic_data:/var/www/html
environment:
MAUTIC_DB_HOST: mauticdb
MAUTIC_DB_PORT: 3306
MAUTIC_DB_DATABASE: mautic
MAUTIC_DB_USER: mautic
MAUTIC_DB_PASSWORD: ${MYSQL_PASSWORD}
MAUTIC_MESSENGER_CONSUMER_ENABLED: "true"
command: php /var/www/html/bin/console messenger:consume email --time-limit=3600
depends_on:
- mauticdb
- mautic_web
restart: unless-stopped
mautic_cron:
image: mautic/mautic:5-apache
container_name: mautic_cron
volumes:
- mautic_data:/var/www/html
environment:
MAUTIC_DB_HOST: mauticdb
MAUTIC_DB_PORT: 3306
MAUTIC_DB_DATABASE: mautic
MAUTIC_DB_USER: mautic
MAUTIC_DB_PASSWORD: ${MYSQL_PASSWORD}
command: >
sh -c "while true; do
php /var/www/html/bin/console mautic:segments:update
php /var/www/html/bin/console mautic:campaigns:trigger
php /var/www/html/bin/console mautic:emails:send
php /var/www/html/bin/console mautic:social:monitoring
sleep 300
done"
depends_on:
- mauticdb
- mautic_web
restart: unless-stopped
volumes:
mysql_data:
mautic_data:
.env File
# .env — copy and customize before first launch
MYSQL_ROOT_PASSWORD=change-this-root-password
MYSQL_PASSWORD=change-this-mautic-password
Generate strong passwords:
openssl rand -hex 24 # Run twice for both passwords
Launch
mkdir -p ~/mautic && cd ~/mautic
# Create docker-compose.yml and .env from above
docker compose up -d
# Watch startup
docker compose logs -f mautic_web
First startup takes 2-4 minutes while Mautic initializes the database schema. Then open http://your-server-ip in your browser.
First-Run Setup Wizard
Mautic's web installer walks through four steps:
Step 1: Environment Checks
The installer validates PHP version, extensions, and directory permissions. All items should show green. Common issue: if var/cache or var/logs show as not writable, fix with:
docker exec mautic_web chown -R www-data:www-data /var/www/html/var
Step 2: Database Configuration
Database Driver: MySQL PDO
Host: mauticdb ← the container name
Port: 3306
Name: mautic
Username: mautic
Password: [your MYSQL_PASSWORD]
Table Prefix: (leave empty or set 'mautic_')
Click Next — Mautic creates all tables (takes ~30 seconds).
Step 3: Admin Account
First Name: Your Name
Last Name: Your Last Name
Email: admin@yourcompany.com ← this becomes your default sender address
Password: [strong password]
Important: The email you enter here becomes your default From address. Use a real deliverable address — ideally one on your sending domain.
Step 4: Email Configuration
Configure your transactional email provider immediately — Mautic without SMTP can't send anything.
AWS SES (recommended — $0.10/1,000 emails):
Mailer Transport: SMTP
Host: email-smtp.us-east-1.amazonaws.com
Port: 587
Encryption: TLS
Username: [SES SMTP username from IAM]
Password: [SES SMTP password]
From Name: Your Company
From Email: marketing@yourcompany.com
SendGrid:
Host: smtp.sendgrid.net
Port: 587
Encryption: TLS
Username: apikey
Password: [your SendGrid API key]
Mailgun:
Host: smtp.mailgun.org
Port: 587
Encryption: TLS
Username: postmaster@mg.yourcompany.com
Password: [Mailgun SMTP password]
Click Finish to complete setup.
Core Features: What Mautic Can Do
Contact Management
Mautic's contact database is the foundation of everything. Contacts are enriched automatically:
Contacts → Import CSV → Map fields
Name, Email, Company, Phone → Standard fields
Any custom fields you've defined → Custom fields
Or capture automatically via:
→ Mautic forms embedded on your website
→ API (push contacts from your app)
→ CRM sync (Salesforce, SugarCRM, Dynamics)
Contact timeline shows every touchpoint: emails opened, links clicked, pages visited, forms submitted, and campaign steps completed. This is the data HubSpot charges thousands to collect — it's all yours.
Segments
Segments are dynamic contact lists that update automatically based on rules:
Contacts → Segments → New Segment
Name: "Enterprise Leads - Not Yet Contacted"
Rules:
Company Size → is → Enterprise (1000+)
AND Lead Status → is not → Contacted
AND Last Active → is greater than → 7 days ago
AND Email → is valid → true
Segments rebuild automatically every time the cron job runs (every 5 minutes in our Docker setup). All campaigns target segments, not individual contacts.
Email Builder
Mautic's drag-and-drop email builder creates responsive HTML emails:
Channels → Emails → New Email
Type: Template Email (for campaigns) or Segment Email (one-time broadcast)
Builder:
→ Drag in text blocks, images, buttons, dividers
→ Personalization tokens: {contactfield=firstname} {contactfield=company}
→ Dynamic content: show different content blocks based on contact fields
→ A/B testing: split by subject line, content, or send time
Subject: Your {contactfield=company} trial is about to expire
Preview text: Don't lose access to [feature] — here's what you need to know
Campaign Builder (Visual Automation)
This is Mautic's flagship feature — a visual, event-driven campaign builder that rivals HubSpot's workflow tool:
Campaigns → New Campaign → Canvas
Start:
→ Contact joins segment: "Trial Users - Day 7"
Step 1 (immediately):
→ Send email: "Day 7 trial check-in"
Decision point:
→ Did they open the email?
YES branch:
→ Wait: 2 days
→ Send email: "Upgrade now — 15% off"
→ Modify contact field: "Campaign = Trial Nurtured"
NO branch:
→ Wait: 1 day
→ Send email: "Did this get lost in your inbox?"
→ Decision: Did they open the retry?
YES → Continue to upgrade offer
NO → Add tag: "Low Engagement" → Remove from segment
End actions:
→ Notify sales owner
→ Push to CRM
→ Update lead score
The campaign canvas supports unlimited branches, delays (minutes, hours, days, specific dates), conditional logic based on any contact field or behavior, and multi-channel actions (email, SMS, push notifications, webhooks to external systems).
Contact Scoring
Assign points to behaviors to automatically identify hot leads:
Settings → Scoring → Points
Email opened: +1 point
Link clicked: +5 points
Form submitted: +10 points
Pricing page visit: +15 points
Demo requested: +25 points
Email bounced: -5 points
Unsubscribed: -20 points
Combine scoring with campaign triggers: "When contact reaches 50 points, notify sales and start the sales outreach campaign."
Landing Pages
Build GDPR-compliant lead capture pages within Mautic:
Landing Pages → New Landing Page
Builder: Same drag-and-drop as email builder
Forms: Embed Mautic forms that auto-capture leads into contact database
Tracking: Built-in page view and conversion tracking
A/B testing: Split test two page variants
Publish to a subdomain: landing.yourcompany.com/offer-name
Custom Domain and TLS
DNS Setup
# DNS A record:
marketing.yourcompany.com → your.server.ip.address
Caddy Reverse Proxy (Recommended)
Add Caddy to your Docker Compose for automatic TLS:
# Add to docker-compose.yml
caddy:
image: caddy:2-alpine
container_name: mautic_caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- mautic_web
restart: unless-stopped
# Update mautic_web: remove ports: - "80:80" (Caddy handles ingress)
# Add to volumes:
volumes:
caddy_data:
caddy_config:
# Caddyfile
marketing.yourcompany.com {
reverse_proxy mautic_web:80
}
Caddy automatically fetches and renews Let's Encrypt certificates. No certbot needed.
Update Mautic's site URL:
Settings → System Settings → Site URL
→ https://marketing.yourcompany.com
Email Deliverability: The Critical Step Most Guides Skip
Self-hosted email is only as good as your deliverability. Without proper setup, your campaigns land in spam.
DNS Records to Configure
Set these in your domain registrar for your sending domain (e.g., yourcompany.com):
SPF record — authorize your email provider to send on your behalf:
Type: TXT
Name: @
Value: v=spf1 include:amazonses.com ~all
# Replace with your provider's include string
DKIM — cryptographic signature on all outgoing email:
# AWS SES: Go to SES console → Verified identities → DKIM
# Copy the three CNAME records and add them to your DNS
# Example:
# xxxxxxxxxxxx._domainkey.yourcompany.com → CNAME → xxxx.dkim.amazonses.com
DMARC — policy for email authentication failures:
Type: TXT
Name: _dmarc
Value: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourcompany.com; pct=100
Configure Tracking Domain
Mautic tracks email opens with pixel images and link clicks via redirect. Configure a tracking subdomain:
Settings → Email Settings → Tracking Domain
→ t.yourcompany.com
DNS:
t.yourcompany.com → CNAME → marketing.yourcompany.com
This keeps tracking URLs on your domain rather than mautic.io subdomains.
Warm Up Your IP/Domain
Never blast 50,000 emails on day one from a new sending domain. ESP (Email Service Provider) reputation takes weeks to build:
Week 1: Maximum 500 emails/day → your most engaged contacts
Week 2: Maximum 2,000 emails/day
Week 3: Maximum 10,000 emails/day
Week 4+: Scale based on metrics
Monitor bounce rate, spam rate, and open rate from your ESP dashboard. Stop if bounce rate exceeds 2% — clean your list.
CRM Integration
Salesforce
Settings → Plugins → Salesforce
Client ID: [Salesforce connected app client ID]
Client Secret: [Salesforce connected app secret]
Instance URL: https://yourcompany.my.salesforce.com
Sync settings:
→ Push Mautic contacts to Salesforce leads/contacts
→ Pull Salesforce changes back to Mautic
→ Map fields: Mautic "Lead Score" → Salesforce "Lead Score"
→ Sync interval: every 15 minutes
Webhooks (any CRM or tool)
Settings → Webhooks → New Webhook
Trigger: Contact score changes above 50
URL: https://your-crm.internal/api/hot-lead
Method: POST
Headers: Authorization: Bearer your-api-token
Payload:
{
"contact_id": "{contact.id}",
"email": "{contact.email}",
"score": "{contact.points}",
"company": "{contact.company}"
}
Use webhooks to push events to your CRM, Slack, n8n workflows, or any system with an HTTP endpoint.
Production Hardening
Backups
#!/bin/bash
# backup-mautic.sh
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR="/backups/mautic"
mkdir -p $BACKUP_DIR
# Database backup
docker exec mauticdb mysqldump \
-u mautic \
-p"${MYSQL_PASSWORD}" \
mautic | gzip > "$BACKUP_DIR/mautic_db_$DATE.sql.gz"
# Mautic files (media, config, custom assets)
tar -czf "$BACKUP_DIR/mautic_files_$DATE.tar.gz" \
~/mautic/mautic_data/
# Upload to S3
rclone copy "$BACKUP_DIR/" s3remote:backups/mautic/
# Retain 30 days
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
echo "Backup complete"
Updates
cd ~/mautic
# Pull latest images
docker compose pull
# Restart (Mautic runs DB migrations automatically on startup)
docker compose up -d
# Verify migration completed
docker compose logs mautic_web | grep -E "migration|Migrating|error"
Check Mautic releases before major version upgrades. The 5.x → 6.x and 6.x → 7.x upgrades require following the official migration guide.
Rate Limiting and Security
# docker-compose.yml — add to mautic_web environment
environment:
MAUTIC_TRACK_PRIVATE_IP_RANGES: "false" # Don't track internal IPs
MAUTIC_CORS_VALID_HOSTS: "yourcompany.com, *.yourcompany.com"
# Caddyfile — rate limit the API
marketing.yourcompany.com {
rate_limit {
zone api {
key {remote_host}
events 100
window 1m
}
match path /api/*
}
reverse_proxy mautic_web:80
}
Scaling Mautic
The default setup handles up to ~200,000 contacts and moderate email volumes. For larger lists:
Queue-Based Email Sending
Enable asynchronous email processing (recommended for any production setup):
Settings → System Settings → Queue Emails
→ Enable: Yes
→ Message Limit Per Batch: 100
→ Pause Between Batches: 1 second
With the worker container running, emails queue and process asynchronously. The web container stays responsive even during large sends.
Redis for Caching
For higher traffic:
redis:
image: redis:7-alpine
container_name: mautic_redis
restart: unless-stopped
# In mautic_web environment:
MAUTIC_REDIS_DSN: redis://redis:6379
Horizontal Scaling
For very large deployments (1M+ contacts, 100K+ daily emails):
- Run 2-4
mautic_webcontainers behind a load balancer - Run 4-8
mautic_workercontainers for parallel queue processing - Use RDS/Aurora MySQL instead of containerized MySQL
- Use ElastiCache Redis for session and cache storage
Mautic vs Listmonk vs Mailtrain: Which Tool?
| Mautic | Listmonk | Mailtrain | |
|---|---|---|---|
| Best for | Full marketing automation | Newsletter broadcasts | List management |
| Language | PHP/Symfony | Go | Node.js |
| GitHub stars | 9,300+ | 16,000+ | 4,500+ |
| Campaign builder | ✅ Visual, drag-and-drop | ❌ Sequential only | ❌ Basic |
| Contact scoring | ✅ | ❌ | ❌ |
| Landing pages | ✅ | ❌ | ❌ |
| CRM integration | ✅ Salesforce, Sugar, Dynamics | ❌ | ❌ |
| Complexity | High (full marketing suite) | Low (focused tool) | Medium |
| Resource usage | High (PHP + MySQL + workers) | Low (Go binary) | Medium |
Choose Mautic if you need the full marketing automation stack — lead scoring, multi-step campaigns, CRM sync, and behavioral tracking. Choose Listmonk if you primarily send newsletters or transactional email broadcasts and want simplicity.
3-Year Cost Analysis: Mautic vs HubSpot
| Cost Component | Mautic Self-Hosted | HubSpot Professional |
|---|---|---|
| Software license | $0 | $890/month base |
| Hosting (4 vCPU/8GB) | ~$25/month | Included |
| Email delivery (100k/month) | ~$10/month (SES) | Included |
| Implementation (one-time) | $2,000–$5,000 | $3,000–$6,000 |
| Ongoing maintenance | $200–$500/month (internal) | $0 |
| Year 1 total | ~$12,000–$18,000 | ~$18,000–$30,000 |
| Year 2 total | ~$4,000–$9,000 | ~$15,000–$20,000 |
| Year 3 total | ~$4,000–$9,000 | ~$15,000–$20,000 |
| 3-year total | ~$20,000–$36,000 | ~$48,000–$70,000 |
At scale (250K+ contacts, enterprise pricing), the HubSpot cost multiples: €3,530/month base + overage for contacts. Mautic scales linearly with infrastructure, not contact count.
Methodology
- GitHub stats from github.com/mautic/mautic, March 2026
- HubSpot pricing from hubspot.com/pricing, March 2026
- ActiveCampaign pricing from activecampaign.com/pricing, March 2026
- Docker setup based on official Mautic Docker Hub image and Mautic documentation
- Cost analysis based on HubSpot vs Mautic comparison
- Sources: Mautic.org, Sequenzy Mautic vs HubSpot, OpenTechHub Mautic guide
- Version: Mautic 7.x / Docker image
mautic/mautic:5-apache(check Docker Hub for current tag)
Find more open source HubSpot alternatives on OSSAlt — self-hosting guides, community ratings, and feature comparisons.
Related: How to Self-Host Listmonk: Mailchimp Alternative 2026 · Best Open Source Alternatives to HubSpot in 2026 · Best Open Source Email Marketing Tools in 2026