Open Source Team Messaging at Scale: Running Mattermost Yourself

Every few years a company looks at its Slack invoice, adds up the per-seat cost, notices that a decade of internal conversation is sitting in someone else's database in another jurisdiction, and asks whether there is another way. There is. Mattermost is the most credible self-hosted answer, and it has been for a while.
It is also the tool most often misunderstood before deployment, because the free edition people think they are getting is usually not the one they end up running. This guide is about what Mattermost actually is, what the free version really includes, and the three operational problems that catch almost every first-time self-hoster.
What Mattermost is
A Go server, a PostgreSQL database, a React web client, and native desktop and mobile apps. Channels, threads, file sharing, search, slash commands, incoming and outgoing webhooks, bots, and a plugin framework. If you have used Slack you will be productive in an afternoon, and so will everyone else, which matters more than any feature list when you are asking a whole company to move.
Around that core sit Playbooks for checklist-driven incident and process work, and Calls for audio, video and screen sharing. The integrations catalogue covers the usual suspects: GitLab, GitHub, Jira, Jenkins, PagerDuty. ChatOps is where the product is genuinely strong, which is why it has such a following among engineering and operations teams, and among defence and public sector organisations that cannot put their traffic on a commercial SaaS at all.
The important architectural fact is that all of it runs on infrastructure you choose. Same principle as self-hosting your analytics with Matomo or your marketing automation with Mautic. The messages are in your database, the files are in your object storage, and nobody can change the retention policy or the price without asking you.
The licensing picture, stated plainly
This is where people get confused, so it is worth being direct about it.
Team Edition is the open source one. MIT licensed, free, no user cap, and it is what most self-hosters actually run. You get messaging, channels, threads, search, integrations, webhooks and the plugin framework. You do not get SAML or AD/LDAP single sign-on, compliance export, enterprise search, high availability clustering, or guest accounts.
Entry is a free commercial edition. It unlocks the advanced feature set but caps you: message history is limited, playbook runs are limited, support is community only, and it is aimed at teams under about fifty people. It is a good way to evaluate the paid product. It is a bad way to build a permanent home for your company's conversation history, because the history limit is exactly the thing you eventually care about.
Professional, Enterprise and Enterprise Advanced are the paid tiers. Professional adds SSO, MFA and advanced permissions. Enterprise adds AD/LDAP synchronisation, compliance automation, enterprise search, high availability and Playbooks at scale. Enterprise Advanced adds classified information handling, zero trust controls and air-gapped deployment, which is the tier the defence and government users are on. Mattermost does not publish per-seat pricing any more, so budget for a sales conversation.
The decision most teams face is simpler than the tier list suggests. If you need SAML against your identity provider, you are paying. If you can live with local accounts or GitLab OAuth, Team Edition will carry a surprisingly large organisation.
Setting it up
A small deployment
For a team of tens to low hundreds, a single well-specified VPS is genuinely enough. Mattermost's own guidance puts one to a thousand users at one vCPU and 2GB of RAM, which is optimistic in the way vendor minimums always are. Give it four cores and 8GB and you will not think about it again.
The stack is Mattermost, PostgreSQL, and a reverse proxy terminating TLS. Traefik with Let's Encrypt is the least work:
services:
mattermost:
image: mattermost/mattermost-team-edition:latest
restart: unless-stopped
environment:
- MM_SQLSETTINGS_DRIVERNAME=postgres
- MM_SQLSETTINGS_DATASOURCE=postgres://mmuser:your_secure_password@db:5432/mattermost?sslmode=disable
- MM_SERVICESETTINGS_SITEURL=https://chat.example.com
volumes:
- mm_data:/mattermost/data
- mm_config:/mattermost/config
depends_on:
- db
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=mmuser
- POSTGRES_PASSWORD=your_secure_password
- POSTGRES_DB=mattermost
volumes:
- db_data:/var/lib/postgresql/data
volumes:
mm_data:
mm_config:
db_data:
Set SiteURL correctly before you invite anyone. A wrong or missing SiteURL breaks push notifications, OAuth callbacks and link previews in ways that are annoying to debug later and trivial to avoid now.
One caveat worth repeating because the vendor says it too: containers are fine for evaluation and for small production installs, but the container path does not give you clustering or high availability out of the box. If you need those, deploy on Linux directly or use the Kubernetes operator.
A production deployment
PostgreSQL 14 or newer. MySQL support is being deprecated from v11, so if you are standing something up now, do not start on MySQL. Amazon Aurora PostgreSQL is supported and is the sane managed option on AWS.
Put files in S3-compatible object storage from day one. The local filesystem works and is the default, and it is also the thing that quietly makes your server stateful, your backups enormous and your migration painful. Switching later means moving files and rewriting paths. Switching at install time means setting a handful of config values.
For high availability you need the Enterprise tier: multiple app nodes behind a load balancer, a shared object store, and a database with read replicas. For search at scale you want Elasticsearch or OpenSearch, also Enterprise. PostgreSQL full-text search is fine for a few hundred people and a few million messages, and CJK search now works by default on PostgreSQL, which used to be a real reason to buy the search add-on.
The three things that go wrong
Everything above is in the documentation. These are the parts people discover in production.
Push notifications are not free in the way you expect
Mobile push has to go through Apple's and Google's networks, which means something has to hold the signing certificates. Mattermost runs a Test Push Notification Service that works out of the box and is explicitly not for production. The Hosted Push Notification Service is the production one and it comes with a paid licence.
The third option is running your own push proxy. It is well documented and entirely doable, but it means building and distributing your own mobile app with your own Firebase and APNs credentials, which is an app store relationship and a release process, not an afternoon.
Decide which of the three you are on before you roll out to phones, not after the first person asks why they get messages only when the app is open. This single issue accounts for more abandoned Mattermost migrations than anything else.
Calls need more than a port
Calls has two modes. Integrated mode runs the media service inside the Mattermost server and is recommended below about fifty active users. Above that you want rtcd, a separate service that keeps call media off your main server and scales horizontally. rtcd requires Enterprise.
Either way, clients need to reach the media service over UDP on port 8443, and that port has to be open on the host running the media service. Your nginx reverse proxy will not forward it, because nginx is not in the UDP path. Half the "calls do not connect" threads come down to a firewall rule that was never added.
On the free tier, expect one to one calls with a time limit rather than unlimited group calls. If company-wide video is a requirement, price it in.
Someone has to run it
The honest cost comparison is not licence versus zero. It is licence versus infrastructure plus the person who patches it. Mattermost ships frequent releases, you will want to stay current for security reasons, and upgrades involve database migrations that you should test somewhere that is not production.
For a team that already runs its own infrastructure this is marginal work and the economics are overwhelming. For a ten-person company with no operations capacity, a SaaS invoice may genuinely be cheaper than the Tuesday afternoons. Be honest about which one you are.
Moving from Slack
Mattermost has an import path from Slack export files, and it works, with caveats that are worth knowing in advance. Public channel messages and users come across well. Private channels and direct messages depend on what your Slack plan lets you export at all. Threading, file attachments, custom emoji and integrations need attention and some of them need rebuilding.
The approach that works: import history as an archive people can search, and treat the cutover date as a clean start. Trying to reproduce every Slack behaviour exactly is how a two-week migration becomes a two-quarter one.
Run both in parallel for a fortnight, move one team first, and set the switch-off date publicly at the start. Chat migrations fail socially rather than technically.
The European angle
For companies in the EU this is not only about cost. Self-hosting puts your internal communication inside a boundary you control, which changes the shape of several conversations at once: GDPR transfer analysis, NIS2 supply chain scrutiny, and the sovereignty questions that increasingly show up in public sector procurement and are the whole subject of the Cloud and AI Development Act.
Internal chat is one of the densest concentrations of confidential material a company has. It holds incident detail, customer names, credentials people should not have pasted but did, and every commercial negotiation in progress. When someone asks where that data lives, being able to answer with a region and a rack rather than a subprocessor list is worth something.
When not to bother
If your company is fifteen people, your compliance requirements are light and nobody wants to own a server, use the SaaS. The savings will not cover the attention.
If you need deep integration with an ecosystem you already live inside, look hard at what you would lose. Teams inside a Microsoft 365 estate get a lot of things for free that you would rebuild.
And if the driver is one loud person's dislike of a vendor rather than a real requirement around cost, control or jurisdiction, the migration will stall at about sixty percent adoption, which is the worst possible outcome for a communication tool.
Getting help
We deploy and run self-hosted open source infrastructure for companies operating in Europe, including the parts that are unglamorous: push proxies, object storage migrations, upgrade paths and the identity integration that makes a chat rollout stick.
If you want a Mattermost deployment sized properly, a Slack migration planned by someone who has done it, or an honest answer about whether self-hosting is worth it for your team, write to office@c9group.dev. More about our infrastructure work on the AWS cost optimisation page.
If you are assembling a full self-hosted stack, the same reasoning applies to analytics and to marketing automation.
Published: August 8, 2026 Categories: Collaboration, Open Source, Privacy