If you’ve been sending newsletters for any length of time, you already know the pain: your list grows, your bill grows faster. Mailchimp’s pricing scales with subscriber count, and once you cross 10,000 subscribers, you’re paying hundreds of dollars per month. ConvertKit, Brevo, and most other hosted platforms follow the same pattern.
What if you could run the same kind of software — subscriber management, campaign scheduling, analytics, templates — on your own server for the cost of a $5/month VPS?
That’s exactly what Listmonk does. It’s a self-hosted newsletter and mailing list manager that’s been battle-tested at scale — the project’s own screenshots show a single instance sending 7+ million emails in one campaign while using a fraction of a CPU core and 57 MB of RAM. It has 23,000+ GitHub stars, an active maintainer, and a feature set that rivals commercial platforms.
In this guide, we’ll walk through what Listmonk does, how it compares to Mailchimp, and how to get it running with Docker in under 30 minutes.
What Listmonk Actually Does
Listmonk is a standalone application written in Go. It ships as a single binary and uses PostgreSQL as its database. That’s it — no Node.js runtime, no Python dependencies, no cluster of microservices. You run one binary and connect one database.
Here’s what you get out of the box:
| Feature | Listmonk | Mailchimp |
|---|---|---|
| Subscriber management | ✅ Unlimited | ✅ (priced per tier) |
| Single & double opt-in | ✅ | ✅ |
| Subscriber segmentation | ✅ SQL-based | ✅ Visual builder |
| Campaign scheduling | ✅ | ✅ |
| Drag-and-drop email builder | ✅ | ✅ |
| WYSIWYG & Markdown editors | ✅ | WYSIWYG only |
| Transactional emails | ✅ Via API | ✅ Add-on ($$$) |
| Analytics (opens, clicks, bounces) | ✅ | ✅ |
| SMS / WhatsApp messaging | ✅ Via webhooks | ❌ |
| SSO (OIDC) | ✅ | ✅ Enterprise |
| API access | ✅ Full REST API | ✅ |
| Subscriber limit | None | Tiers (10K = ~$100/mo) |
| Monthly cost (10K subscribers) | ~$5 (VPS) | ~$100+ |
| Data location | Your server | Vendor’s cloud |
The key difference isn’t just price. With Listmonk, your subscriber data lives on your server. You’re not handing email addresses, open rates, and click data to a third party. For businesses that take data privacy seriously — or operate under GDPR, HIPAA, or similar regulations — that matters.
Who Listmonk Is For
Listmonk fits well if you:
- Send newsletters regularly and your subscriber list is growing past the free tiers of hosted platforms
- Want data sovereignty — your subscriber list is an asset, and you want to control where it lives
- Already self-host other tools — if you’re running Plausible, Metabase, or n8n, adding Listmonk is a natural fit
- Need transactional emails alongside newsletters — Listmonk’s API handles both
- Have technical capacity — you or someone on your team can manage a Docker container and a DNS record
It’s not the right fit if you need a fully managed, no-touch solution and have no interest in running infrastructure. In that case, a hosted service makes sense — you’re paying for someone else to handle deliverability, updates, and server maintenance.
What You’ll Need
- A Linux server (VPS or dedicated) with Docker and Docker Compose installed
- A domain name or subdomain (e.g.,
news.yourcompany.com) - An SMTP server for sending emails — this can be a self-hosted Postfix setup, a transactional email service like Amazon SES, or any SMTP relay
- About 30 minutes
The SMTP piece is the one most people ask about. Listmonk doesn’t send email directly — it connects to an SMTP server, which handles delivery. You have several options:
- Amazon SES — cheapest at $0.10 per 1,000 emails. Requires AWS account setup and domain verification.
- Self-hosted Postfix — free, but you’ll need to configure SPF, DKIM, and DMARC records properly for deliverability. More work, maximum control.
- Transactional relay services (Mailgun, Postmark, SendGrid) — easier setup, paid, but handle deliverability for you.
For this guide, we’ll assume you’re using an external SMTP service. You can swap in self-hosted Postfix later.
Step 1: Download the Docker Compose File
Listmonk provides a ready-to-use docker-compose.yml that includes both Listmonk and a PostgreSQL database. Start by downloading it:
# Create a directory for Listmonk
mkdir -p ~/listmonk && cd ~/listmonk
# Download the official compose file
curl -LO https://github.com/knadh/listmonk/raw/master/docker-compose.yml
The default compose file looks something like this:
version: "3"
services:
listmonk:
image: listmonk/listmonk:latest
container_name: listmonk
restart: unless-stopped
ports:
- "9000:9000"
environment:
- TZ=Etc/UTC
volumes:
- ./config.toml:/listmonk/config.toml
depends_on:
- db
db:
image: postgres:15
container_name: listmonk-db
restart: unless-stopped
environment:
- POSTGRES_PASSWORD=listmonk
- POSTGRES_USER=listmonk
- POSTGRES_DB=listmonk
volumes:
- ./data:/var/lib/postgresql/data
This gives you two containers: Listmonk itself and a PostgreSQL database. The database data is persisted to ./data on your host.
Step 2: Generate the Configuration
Before starting the containers, generate a configuration file:
# Generate the default config
docker run --rm listmonk/listmonk:latest --new-config > config.toml
Now edit config.toml. The key settings to update:
[app]
admin_username = "admin"
admin_password = "CHANGE_THIS_TO_A_STRONG_PASSWORD"
admin_emaillist = "you@yourcompany.com"
# Database connection (matches the compose file)
[db]
host = "db"
port = 5432
user = "listmonk"
password = "listmonk"
database = "listmonk"
# SMTP settings — replace with your provider's details
[smtp]
[smtp.myprovider]
enabled = true
host = "email-smtp.us-east-1.amazonaws.com"
port = 587
auth_protocol = "login"
username = "YOUR_SES_USERNAME"
password = "YOUR_SES_PASSWORD"
max_conns = 10
max_msg_retries = 2
idle_timeout = "15s"
wait_timeout = "5s"
Replace the SMTP section with your provider’s credentials. If you’re using Amazon SES, the host will be something like email-smtp.us-east-1.amazonaws.com. If you’re using Postfix on the same server, use host = "localhost" and port = 25.
Step 3: Initialize the Database and Start
# Initialize the database schema
docker compose run --rm listmonk ./listmonk --install
# Start both containers in the background
docker compose up -d
The --install flag creates all the necessary tables in PostgreSQL. You only run this once. For future upgrades, use --upgrade instead.
Visit http://localhost:9000 (or your server’s IP on port 9000) and you should see the Listmonk dashboard. Log in with the admin credentials you set in config.toml.
Step 4: Set Up a Reverse Proxy with SSL
You don’t want to expose port 9000 directly. Use Caddy or Nginx as a reverse proxy to handle HTTPS automatically.
Here’s a simple Caddyfile:
news.yourcompany.com {
reverse_proxy localhost:9000
}
Caddy automatically provisions and renews Let’s Encrypt certificates. Install Caddy, drop this config in, and reload:
# Install Caddy (Debian/Ubuntu)
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
# Copy your Caddyfile
sudo cp Caddyfile /etc/caddy/Caddyfile
sudo systemctl reload caddy
Point your DNS news.yourcompany.com A record to your server’s IP, and Caddy will handle the rest.
Step 5: Create Your First List and Campaign
Inside the Listmonk dashboard:
- Go to Lists → New List. Give it a name (e.g., “Weekly Newsletter”) and choose double opt-in if you want subscribers to confirm their email addresses.
- Go to Subscribers → Import if you’re migrating from another platform. Listmonk accepts CSV files. If you’re coming from Mailchimp, export your list as CSV and import directly.
- Go to Campaigns → New Campaign. Choose your list, write your subject line, and compose your email. Listmonk supports a drag-and-drop builder, raw HTML, Markdown, and plain text — all in the same editor.
The template editor uses Go’s templating language, which lets you insert dynamic content:
This inserts the subscriber’s name, or falls back to “there” if the name field is empty. You can use conditional logic, loops, and over 100 built-in functions.
Step 6: Embed a Subscription Form on Your Website
Listmonk generates embeddable HTML forms for each list. Go to Lists → your list → Subscription Form, and you’ll get code like this:
<form method="post" action="https://news.yourcompany.com/subscription/form">
<input type="hidden" name="l" value="a1b2c3d4">
<div>
<label for="email">Email</label>
<input type="email" name="email" id="email" required>
</div>
<div>
<label for="name">Name</label>
<input type="text" name="name" id="name">
</div>
<button type="submit">Subscribe</button>
</form>
Paste this into any page on your website. Submissions go directly to Listmonk — no JavaScript SDK, no third-party scripts, no cookie banners required.
Automating With n8n
If you’re already running n8n for automation, Listmonk’s REST API opens up useful workflows:
- New customer → auto-subscribe: When a new customer is created in Odoo or your CRM, an n8n webhook calls Listmonk’s API to add them to a welcome sequence list.
- Blog published → newsletter campaign: When a new post is published, n8n creates a draft campaign in Listmonk with the post content, ready for review.
- Tag-based segmentation: Sync tags from your CRM to Listmonk subscriber attributes, then use SQL-based segmentation to target campaigns.
Here’s an example n8n HTTP Request node that subscribes a new contact:
{
"method": "POST",
"url": "https://news.yourcompany.com/api/subscribers",
"authentication": "header",
"headers": {
"Authorization": "Bearer YOUR_API_TOKEN"
},
"body": {
"email": "",
"name": "",
"lists": [1],
"status": "enabled"
}
}
Generate an API token in Listmonk under Settings → API Tokens.
Cost Comparison: One Year
Let’s put real numbers on this. Say you have 15,000 subscribers and send two campaigns per month.
| Platform | Monthly Cost | Annual Cost |
|---|---|---|
| Mailchimp (Standard, 15K) | ~$150 | ~$1,800 |
| Convertkit (Creator, 15K) | ~$130 | ~$1,560 |
| Brevo (15K emails/mo) | ~$65 | ~$780 |
| Listmonk + VPS + SES | ~$12 | ~$144 |
The Listmonk setup breaks down as:
- VPS (2GB RAM): $5–10/month
- Amazon SES (30K emails/mo at $0.10/1K): $3/month
- Domain: ~$10/year
That’s a 92% saving over Mailchimp. Even if you factor in the time spent setting up and maintaining the server (a few hours per year for updates), the math is hard to argue with.
Migration From Mailchimp
Moving from Mailchimp to Listmonk is straightforward:
- Export your subscribers from Mailchimp as a CSV file (Audience → Manage Audience → Export Audience).
- Clean up the CSV — Listmonk needs at minimum an
emailcolumn. Anamecolumn is optional but recommended. - Import into Listmonk — Subscribers → Import → upload CSV. Map the columns and choose your target list.
- Recreate your email templates — Listmonk’s drag-and-drop builder is different from Mailchimp’s, so you’ll need to rebuild your template. If your template is HTML, you can paste it directly into the raw HTML editor.
- Update your subscription forms — Replace Mailchimp embed codes on your website with Listmonk’s form code.
The one thing you can’t migrate is historical analytics. Mailchimp’s open/click data stays in Mailchimp. Listmonk will start tracking from your first campaign onward.
Deliverability: The Elephant in the Room
Self-hosting your newsletter software doesn’t mean you should self-host your email delivery. Deliverability — making sure your emails actually reach the inbox instead of the spam folder — depends on your sender reputation, which depends on your SMTP infrastructure.
This is why most Listmonk users pair it with a transactional email service like Amazon SES. SES handles the hard parts: IP reputation, bounce processing, complaint feedback loops, and DKIM signing. You get the cost savings of self-hosted software with the deliverability of a managed SMTP service.
If you do want to self-host SMTP (with Postfix), make sure you set up:
- SPF record in DNS — identifies which servers can send from your domain
- DKIM signing — cryptographically signs your emails
- DMARC record — tells receiving servers what to do if SPF/DKIM fail
- Warm up your IP — start with small sends and ramp up gradually
Keeping Listmonk Updated
Updating Listmonk is simple:
cd ~/listmonk
# Pull the latest image
docker compose pull
# Run the database upgrade
docker compose run --rm listmonk ./listmonk --upgrade
# Restart with the new version
docker compose up -d
The project releases new versions regularly — the current version as of this writing is v6.2.0. Updates typically include new features, bug fixes, and performance improvements. The maintainer (Kailash Nadh, who also built the popular Knacksteem and golifto projects) has been consistently active since the project’s inception.
Backing Up Your Data
Your subscriber list is valuable. Back it up regularly:
# Back up the PostgreSQL database
docker exec listmonk-db pg_dump -U listmonk listmonk > backup_$(date +%Y%m%d).sql
# Optional: back up the config and data directory
tar czf listmonk_files_$(date +%Y%m%d).tar.gz config.toml ./data
Set this up as a cron job to run daily, and copy the backups to off-site storage (another server, S3, or a B2 bucket). If you’re using n8n, you can even automate the backup-to-S3 step as a scheduled workflow.
Is It Worth It?
If you have fewer than 500 subscribers and send one email a month, a free Mailchimp account is fine. The math doesn’t justify the setup time.
But if you’re past 2,000 subscribers, sending regularly, and comfortable with basic Docker commands — Listmonk pays for itself within the first month. You get unlimited subscribers, unlimited campaigns, full data ownership, and an API that integrates with the rest of your automation stack. The features you’d pay extra for on hosted platforms (transactional emails, SSO, API access) are all included.
The tradeoff is maintenance. You’re responsible for updates, backups, and server security. If that’s a dealbreaker, stick with a hosted service. If you’re already running other self-hosted tools, Listmonk fits naturally alongside them.
Want help setting up Listmonk or integrating it with your existing automation? Get in touch — we help businesses build self-hosted automation stacks that replace expensive SaaS subscriptions without sacrificing capability.