Tech Digest

Communication

Synapse

Reference Matrix homeserver: AGPL since 2024, and still what federation is tested against

CommunicationAGPL-3.0-only (or a commercial license from Element)Maturearm64 buildsNative OIDC
Last reviewed Profile maintained against the project's own documentation
Operational load
4 / 5
Heavy
Idle memory
700 MB
typical use ~2000 MB
Moving parts
2
containers in a normal deployment
Backup shape
Postgres dump
needs a dump or a stop

Synapse is the original Matrix homeserver, a federated chat server with end-to-end encryption, voice and video, and bridges to other networks. It replaces a hosted Slack or Discord workspace with a server you own that can still talk to other people's servers.

Our verdict on Synapse#

Run Synapse if you specifically want federation. If you only want private team chat, this is the wrong shape of work for the result. Element relicensed it from Apache-2.0 to AGPL-3.0-only in late 2023 and moved the repo from matrix-org to element-hq in December 2023. The Matrix.org Foundation still owns the spec, but Element writes and ships the server, and the README now points at Element Server Suite as the official deployment path; ESS Community is free but scoped to non-commercial use up to 100 users, so check that before you standardize on it. The operational tax is PostgreSQL. Messages are small, state_groups_state is not: sit in a few large public rooms and that one table dominates a database that runs to tens of gigabytes, with reports on the tracker of 274 million rows and 51 GB. Schedule synapse_auto_compressor from day one, not after the disk fills.

Who Synapse is for#

Choose it if

  • You want to talk to people on other servers, not just your own users. Federation is the entire reason to accept the rest.
  • A club or community that already lives on Matrix and wants addresses of the form @you:yourdomain.
  • Someone leaving Slack or Discord who accepts running a real PostgreSQL and reading upgrade notes every two weeks.
  • Homelabbers who want bridges to Signal, WhatsApp or IRC surfaced in one client.

Look elsewhere if

  • You want private team chat with no outside contact. Mattermost gives you that with a fraction of the state growth and none of the federation debugging.
  • Your storage is a 32 GB SD card or a small VPS disk. A federated Synapse will fill it and then fail in ways that look like unrelated bugs.
  • You will not do periodic database maintenance. Synapse degrades quietly rather than failing loudly.

What running it actually looks like#

Two containers minimum, Synapse and PostgreSQL, plus whatever reverse proxy already terminates TLS for you. Create the database first with --encoding=UTF8 --locale=C --template=template0; Synapse refuses to start on a wrong collation unless you set allow_unsafe_locale. Generate homeserver.yaml with the generate command, then set server_name once and never change it, because it is baked into every event you have ever signed. Synapse listens on 8008 for clients; federation is 8448, or port 443 fronted by a /.well-known/matrix/server file. First run gives you nothing until you create an account with register_new_matrix_user. Upgrades are usually a pull and restart, but background schema updates can grind for hours on a large database, and docs/upgrade.md is not optional: 1.157.0 removed the experimental MSC3861 auth delegation entirely.

Resource profile#

Memory
700 MB idle, around 2000 MB in ordinary use. The install docs ask for at least 1 GB of free RAM purely to join large public rooms; in practice you pay for the Python process plus its PostgreSQL, and caches grow with the number of joined rooms.
CPU and acceleration
Near zero at rest, but joining or backfilling a large federated room pins a core for minutes while state resolution runs. One vCPU is enough for a family server.
Storage growth
`state_groups_state` in PostgreSQL is the growth driver, not your messages. The media store separately caches remote attachments indefinitely unless you purge them.
Operational load
4 of 5, Heavy. A PostgreSQL with a mandatory collation, a fortnightly release cadence with upgrade notes that occasionally remove config options outright, periodic state compression to stop the database running away, and an in-flight migration to Matrix Authentication Service. A restore needs the database and the signing key together, in order.

Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.

Data and backup surface#

Back up three things: a pg_dump of the Synapse database, the media_store directory, and homeserver.yaml together with the *.signing.key beside it. The signing key is the irreplaceable one. Lose it and other servers reject your events, so keep a copy off the host. Do not file-copy the PostgreSQL data directory while it runs; dump it. The media store mixes your users' uploads (irreplaceable) with cached remote media (regenerable, and usually most of the bytes), so you can exclude remote_content and let it refetch. Restore order is database, then media, then start Synapse.

Derived backup shape

Postgres dump. pg_dump (or pg_dumpall) into a file, then snapshot that file plus the app's data volume.

Traps and surprises#

PostgreSQL must be created with C collation

Synapse requires UTF8 encoding with LC_COLLATE=C and LC_CTYPE=C, created from template0. Miss it and Synapse refuses to start, or worse, you set allow_unsafe_locale and get subtly wrong string ordering that surfaces later as duplicate or missing events. Fixing it after the fact means dumping, recreating the database correctly and reloading. Get it right in the createdb line.

state_groups_state is what fills your disk

Room state, not message content, dominates a Synapse database, and joining large public rooms multiplies it. The project's own tracker has reports of that single table reaching 274 million rows and 51 GB. The accepted mitigation is rust-synapse-compress-state: run synapse_auto_compressor on a schedule, which is transaction-safe while Synapse is running and routinely cuts row counts to under 10 percent of the original.

MSC3861 delegated auth was removed in 1.157.0

If your config still has experimental_features.msc3861, Synapse 1.157.0 and later will not accept it. You have to migrate to the stable matrix_authentication_service config section first, which is a different shape, not a rename. Do that migration on your current version, confirm logins work, and only then upgrade. Upgrading blind leaves every user locked out of a running server.

Federation is invisible until .well-known is right

If you serve Matrix on 443 rather than 8448 you need /.well-known/matrix/server returning the right JSON with the right content type. Your own clients will work perfectly while no other homeserver can reach you, and the symptom is invitations that never arrive rather than an error. Test with the Matrix federation tester before you invite anyone.

Remote media is cached forever by default

Every image and file in every federated room you are in gets cached on your disk and never expires on its own. On a server in a handful of busy public rooms this outgrows your users' own uploads. Use the Purge Remote Media admin API on a schedule, or set a media retention policy. Local uploads are yours and are not covered by the same purge.

Specifications#

Category
Chat, mail and notifications
Licence
AGPL-3.0-only (or a commercial license from Element) (Copyleft)
Written in
Python / Rust
First release
2014
Maturity
Mature
Datastore
PostgreSQL
Default ports
8008, 8448
Ships as
docker, deb package (packages.matrix.org), python venv / pip, helm chart (ESS Community)
arm64 builds
Yes
Identity
Native OIDC. `oidc_providers`, SAML2 and CAS are configured directly in homeserver.yaml, but Element's strategic path is now the separate Matrix Authentication Service.
Replaces
Slack, Discord, Microsoft Teams, WhatsApp
Project site
matrix.org
Source
github.com/element-hq/synapse
Documentation
element-hq.github.io/synapse/latest

Alternatives to Synapse#

Everything else in chat, mail and notifications, closest in operational weight first.

ToolOps loadIdle RAMLicence
mailcow: dockerized4, Heavy3500 MBGPL-3.0 for mailcow's own code; bundled components keep their own licenses
Mattermost3, Moderate500 MBAGPL-3.0 core, Mattermost Source Available License for `server/enterprise/`, Apache-2.0 for webapp and admin tools, MIT for official binaries
Stalwart3, Moderate150 MBAGPL-3.0 for the Community edition, dual licensed with the proprietary Stalwart Enterprise License for gated features
Gotify1, Set and forget20 MBMIT
ntfy1, Set and forget30 MBApache-2.0 (dual licensed with GPL-2.0)

Where Synapse comes up elsewhere#

Migration guides

Sources#

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.