Somewhere in your company there is a spreadsheet comparing Intercom, Customer.io and Zendesk quotes, and somewhere near it an engineer asking why customer conversations need to live in a US vendor's database at four figures a month. Self-hosting is the answer to both, and it deserves a straight description rather than a pitch. This is what running Messy yourself involves, with the boring parts left in.
Why teams self-host messaging
- Data residency. Customer conversations, email addresses and behavioral events are exactly the data your DPA and your security review care about. On your servers, the vendor section of that questionnaire collapses to a paragraph.
- Cost that stays flat. No per-seat, per-profile or per-resolution meters. A VM costs the same with five agents or fifty. The pricing teardowns of Intercom and Customer.io show what you are opting out of.
- No feature gates. Open source means the whole product. There is no enterprise tier hiding SSO or audit logs behind a sales call.
- An exit that already happened. The usual migration fear works in reverse: your data starts in your database, so leaving any future vendor is a non-event.
The moving parts
A production Messy deployment is four processes and a database:
- The API, a Rails application serving the REST endpoints your product and the dashboard both use.
- A background worker (same image, different command) that processes sends, delivery rules, drips and scheduled jobs.
- The dashboard, a static single-page app you can serve from anything.
- PostgreSQL, the only stateful piece. Jobs run through the database too, so there is no Redis to operate.
The repository ships Docker images for the backend and frontend plus the Terraform modules we use for our own Kubernetes deployments. But Kubernetes is our preference, not a requirement: docker compose on a single 2 GB VM serves a small team fine. The API runs db:prepare on boot, so upgrades are pull, restart, done.
Delivery still comes from providers
Self-hosting the platform does not mean running your own mail server, and you should not want to. Messy orchestrates; delivery goes through providers you connect with your own credentials: Amazon SES or any SMTP relay for email, Twilio for SMS, Meta's Cloud API for WhatsApp, FCM and APNs for push. You pay them directly at cost (SES is around $0.10 per thousand emails), and your sending reputation belongs to your domain, not to a shared pool. The email side of that setup, DNS records included, is covered in the BYO-keys transactional email guide.
The ops you are signing up for
This is the part vendor comparisons skip. Choosing self-hosting means owning:
- Backups. One database makes this easy (
pg_dumpon a timer plus an offsite copy), but easy is not automatic. Test a restore once a quarter. - Upgrades. Pulling new images monthly keeps the delta small. Skipping a year makes any software upgrade an event.
- TLS and uptime. A reverse proxy with automatic certificates, and something that restarts crashed containers. Your existing infra almost certainly does both already.
- Webhook reachability. Bounce notifications and WhatsApp replies arrive as webhooks, so the API needs a public HTTPS endpoint.
Realistic budget: an afternoon to stand it up, an hour or two a month to keep it current. If that hour is not worth the vendor line item you are deleting, the math has answered your question.
A sane rollout order
Do not cut over everything in a weekend. Stand up the deployment, connect SES in a test environment, and point one low-stakes transactional trigger at it. Delivery rules let you restrict staging to internal recipients, so a misconfigured loop emails your team, not your users. Then move channels one at a time: transactional email, the chat widget, campaigns, SMS. Each step is reversible, and by the last one your messaging stack is something you own outright.



