Matrix is the self-hosted Slack alternative that doesn’t lock you in
Conduit wins for a solo or small-family server on tiny hardware, and Synapse wins the moment you need bridges to Discord, Slack, or IRC.
You want a chat platform that lives in your homelab, works with everyone (not just your Matrix friends), and doesn’t cost you a kidney in server hardware. That’s Matrix: a federated, encrypted-by-default messaging protocol. Think IRC meets Slack, but open source and owned by the community instead of some VC-funded startup that’ll rebrand and enshittify it in three years.
The problem? Matrix is just the protocol. You need a server to run it. There are three major implementations to choose from, each written in a different language, each with its own philosophy about what a Matrix homeserver should be.
- Synapse (Python): the reference implementation. Full-featured, running in production since 2015, can run everything. Also eats your RAM like it owes it money.
- Dendrite (Go): the second-gen reimagining. Fast, modular, still missing a few features Synapse has. Now in maintenance mode (security fixes only), so treat it as stable rather than improving.
- Conduit (Rust): the lightweight newcomer. Single binary, minimal dependencies, runs on a potato. Opinionated about what you don’t need.
So which one should you run? That depends on your use case. Let’s break it down.
Which Matrix Server Should You Actually Run?
- Pick Synapse if you need every feature, bridges to other platforms, or you’re running a beefy server for 50+ users.
- Pick Dendrite if you want lower memory use than Synapse and might scale across multiple machines later.
- Pick Conduit if you’re a solo user or small family who wants a single lightweight binary on minimal hardware.
The Matrix protocol in 90 seconds
You don’t need to be a protocol wizard, but knowing the basics helps you understand why these servers differ.
Matrix is event-based. Every message, reaction, room state change, that’s an event. Events get signed, stored, and replicated across servers via federation. Your @you:homeserver.com address can talk to @friend:otherserver.com just like they’re in the same room. Servers trust each other through cryptographic signatures, not permissions lists.
Rooms are the atomic unit, like Slack channels but way more flexible. They support encryption (E2EE), state events, and reactions. User accounts live on one homeserver (yours). Everything else, rooms, direct messages, communities, is federated.
That federation is the whole point. You control your data. You’re not renting a seat on someone’s SaaS platform.
Synapse: The mature, feature-complete road hog
Synapse is the reference implementation. It’s what the Matrix core team originally built. Everyone else is chasing parity with Synapse because Synapse supports basically everything the protocol can do.
The good:
- Every feature works. New room versions? Supported. Bridges to Discord, Slack, IRC? Multiple implementations exist (mautrix-*, Bifrost). Widgets? Go for it. Server-side search? Yes. Admin APIs for user management? Obviously.
- Running production servers since 2015. The bugs you’d find have likely already been found and fixed.
- Tons of plugins and extensions. The ecosystem built around Synapse is massive.
- Room versions. Synapse supports all of them, including the latest cryptographic improvements.
The bad:
- It’s written in Python. Python isn’t fast. Synapse uses Twisted (async IO), which helps, but you’re still running a dynamic language that does a lot of work.
- Memory footprint. A fresh Synapse install takes ~300-500 MB. Add a few active rooms, users, and federation traffic, and you’re looking at 2-4 GB easily. I’ve seen Synapse instances hit 6+ GB after a year of daily use.
- Startup time. On smaller hardware, Synapse can take 30-60 seconds to start. Dendrite? 2-3 seconds.
- Disk usage. Synapse caches events aggressively. A year of homelab chatting can balloon to 5-10 GB of SQLite or PostgreSQL database.
- CPU spikes during sync. When clients reconnect, Synapse has to reconstruct the entire room state. It’s not pretty.
Who should run Synapse?
- Small communities (10-100 people) where you need all the bells and whistles.
- Anyone running a relay/bridge to external services that requires Synapse.
- Teams that already know Python and want to hack on the source.
- You’re running on a beefy server and RAM isn’t a constraint.
Dendrite: The polished-up younger sibling
Dendrite is the rewrite. The Matrix team learned from Synapse and built Dendrite in Go, treating it as a chance to rethink the architecture. It’s componentized, the client API, federation, media storage, and room state can run as separate services. You can scale horizontally.
As of 2026, Dendrite is in maintenance mode. Element moved the project to its own element-hq/dendrite repository and only ships security fixes now, matrix.org stopped funding active feature work back in 2023. It still runs and still gets patched, it’s just not moving forward the way it used to.
The good:
- Fast. Go + static compilation. A Dendrite instance starts in seconds.
- Lower memory footprint. Dendrite typically uses 150-400 MB, even with active rooms.
- Polylith mode. Run multiple Dendrite services across machines. Chat component on one box, federation on another. This is where Dendrite shines for scaling.
- Modern design. Dendrite was built with federation and reliability in mind from day one.
- Room versions. Full support for modern room versions and encryption.
The bad:
- Still behind Synapse on features. Admin APIs are less complete, some bridge implementations don’t play nice with Dendrite, widget support is iffy, and none of that gap is closing anymore.
- Monolith mode isn’t production-ready. The single-binary deployment is simpler, but the componentized (polylith) mode is where Dendrite wants to be. That means more complexity.
- Smaller ecosystem. Fewer third-party tools and integrations have been tested in production with Dendrite.
- Documentation lags. Synapse’s docs are miles ahead, and Dendrite’s won’t be catching up: maintenance mode means only security patches land.
Who should run Dendrite?
- Small homelabs where you want low resource usage and can live with the current feature set, since it won’t gain new ones.
- Anyone who already runs it and just wants ongoing security patches without an active migration.
- Teams comfortable running software that won’t get new features, only fixes.
- You’re comfortable saying “no” to some Synapse features you don’t actually need, permanently.
Conduit: The lean, opinionated alternative
Conduit is written in Rust. It’s a single binary. It doesn’t try to be Synapse. Instead, it asks: “What’s the minimum viable homeserver?” and builds exactly that.
The good:
- Tiny. The binary is ~30 MB. Running instances hover around 20-100 MB RAM depending on activity.
- Single binary. Copy one file to your server, add a systemd unit, done. No Python venvs, no Go services to orchestrate.
- Fast startup. Literally seconds. Great for containers.
- Works out of the box. Conduit ships with sane defaults. You don’t have 47 config options to mess with.
- Matrix protocol compliance. Conduit implements the core protocol correctly. Federation works.
- Modern codebase. Rust forces you to think about concurrency and memory safety upfront.
The bad:
- Feature surface is intentionally small. No widget support. Some bridges don’t work. The admin API is minimal. If you need 47 Synapse features, Conduit supports maybe 12 of them: on purpose.
- Smaller community. Dendrite has more eyes than Conduit. Conduit has fewer people reporting bugs and fewer quick fixes.
- Database schema is still evolving. Upgrades between Conduit versions can require migration steps. Not scary, but more friction than Synapse.
- E2EE compliance. Conduit supports encryption, but the story around backup and recovery is less polished than Synapse.
- The fork situation is messy. Original Conduit’s development has slowed since its creator stepped back. A community fork called conduwuit picked up the pace for a while but was itself discontinued in 2025. Its two successors, continuwuity (community-run) and tuwunel (backed by Matrix Construct), are where the active Rust development is happening now. If you want the fastest-moving lightweight option, look at those instead of plain Conduit.
Who should run Conduit?
- Solo users or small families (3-8 people) who want simple, reliable chat.
- You’re running on tiny hardware (Raspberry Pi, ARM box, shared hosting).
- You want the absolute simplest deployment story.
- You don’t need bridges to 47 other platforms. If you need bridges, Conduit might feel too limited.
Head-to-head comparison
| Feature | Synapse | Dendrite | Conduit |
|---|---|---|---|
| Language | Python | Go | Rust |
| Memory (idle) | 300-500 MB | 150-250 MB | 20-50 MB |
| Memory (active) | 2-6+ GB | 400-800 MB | 50-150 MB |
| Startup time | 30-60s | 2-5s | 1-2s |
| Room versions | All | All | All modern |
| E2EE | Yes | Yes | Yes |
| Bridges | Extensive (mautrix-*, Bifrost) | Most work | Limited (some incompatibilities) |
| Admin API | Full-featured | Partial | Minimal |
| Widgets | Yes | Partial | No |
| Polylith/scaling | Not designed | Yes (multiple components) | No (single binary) |
| Configuration | Complex (many options) | Moderate | Simple (opinionated defaults) |
| Community size | Largest | Growing | Smallest |
| Single-user focus | Not really | Not really | Yes |
Installation and deployment
Let’s get concrete. Here’s how you’d run each in Docker.
Synapse with Docker Compose
services: postgres: image: postgres:16-alpine environment: POSTGRES_DB: synapse POSTGRES_USER: synapse POSTGRES_PASSWORD: your_secure_password volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped
synapse: image: matrixdotorg/synapse:latest environment: SYNAPSE_SERVER_NAME: example.com SYNAPSE_REPORT_STATS: 'no' LD_PRELOAD: /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 volumes: - synapse_data:/data ports: - "127.0.0.1:8008:8008" depends_on: - postgres restart: unless-stopped
volumes: postgres_data: synapse_data:Synapse defaults to SQLite, but its own docs call SQLite testing-only and say it performs poorly in large rooms, so run PostgreSQL for anything real. Running it is straightforward, but initialization is a multi-step dance, you need to generate a config, create admin users with registration tokens, and tune settings.
Dendrite with Docker Compose
services: postgres: image: postgres:16-alpine environment: POSTGRES_DB: dendrite POSTGRES_USER: dendrite POSTGRES_PASSWORD: your_secure_password volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped
dendrite: image: matrixdotorg/dendrite:latest environment: TZ: UTC volumes: - dendrite_data:/var/lib/dendrite - /path/to/dendrite.yaml:/etc/dendrite/dendrite.yaml:ro ports: - "127.0.0.1:8008:8008" depends_on: - postgres restart: unless-stopped
volumes: postgres_data: dendrite_data:Dendrite also supports SQLite for testing, but PostgreSQL is the recommended engine once you have more than a handful of users or rooms. The config is simpler than Synapse because there are fewer knobs to turn. Still, you’ll need to generate a config and register users through the admin API.
Conduit with Docker Compose
services: conduit: image: matrixconduit/matrix-conduit:latest environment: ROCKET_ADDRESS: 0.0.0.0 ROCKET_PORT: 6167 CONDUIT_SERVER_NAME: example.com CONDUIT_ALLOW_REGISTRATION: 'true' volumes: - conduit_data:/var/lib/matrix-conduit ports: - "127.0.0.1:6167:6167" restart: unless-stopped
volumes: conduit_data:Conduit is beautifully simple. No external database. It uses RocksDB internally. Environment variables for config. Done.
Reverse proxy: Caddy for all three
All three need a reverse proxy for TLS and .well-known federation endpoints. Here’s a Caddy config that works with any of them:
matrix.example.com { reverse_proxy localhost:8008}
example.com { redir /.well-known/matrix/server matrix.example.com:443 redir /.well-known/matrix/client { status 200 body {"m.homeserver":{"base_url":"https://matrix.example.com"}} }}(If using Conduit, change port 8008 to 6167.)
Managing users and registration
Once your server is running, you’ll want to create users.
Synapse: Registration tokens
# Generate a one-time registration token (valid for 24 hours by default)docker exec synapse_container register_new_matrix_user \ -u username \ -p password \ -a \ http://localhost:8008
# Or with a token for share-based registrationcurl -X POST http://localhost:8008/_synapse/admin/v1/registration_tokens/new \ -H "Authorization: Bearer your_admin_token"Dendrite: Admin API
# Dendrite user creation via admin endpointcurl -X POST http://localhost:8008/_dendrite/admin/v2/users \ -H "Content-Type: application/json" \ -d '{ "user_id": "@username:example.com", "password": "password", "admin": false }'Conduit: Admin panel or direct API
Conduit ships with a minimal web admin panel and supports user creation via the standard Matrix APIs.
# Create user via Matrix register endpoint (if registration is open)curl -X POST http://localhost:6167/_matrix/client/v3/register \ -H "Content-Type: application/json" \ -d '{ "username": "username", "password": "password", "initial_device_display_name": "Desktop" }'The federation reality check
All three servers federate. But federation is hard. Here’s what to expect:
- Initial federation. When you first join a room on another server, messages might take 2-5 seconds to sync over the network. That’s normal.
- Room backfill. Synapse will try to pull 100 messages of history when you join a large room. Dendrite backfills less aggressively. Conduit backfills what it needs.
- State events. If a room has been around for years, there’s a lot of accumulated state (bans, profile changes, etc.). Synapse caches aggressively. Dendrite is smarter about it. Conduit keeps what it needs.
- Reliability. Synapse breaks the least. Dendrite is improving. Conduit works but may drop connections under heavy load (it’s not tuned for thousands of concurrent users).
For a homelab? All three federate just fine. You won’t notice the difference unless you’re in mega-sized rooms or have thousands of users.
Bridges: Talking to Discord, Slack, IRC
Want your Matrix room to mirror Discord? Or IRC? That’s what bridges do.
Synapse: Full ecosystem. mautrix-discord, mautrix-slack, mautrix-telegram, Bifrost (for everything), heisenbridge (for IRC). All tested and documented.
Dendrite: Most bridges work, but you’ll hit edge cases. The admin APIs differ just enough that some bridge setup scripts break. Doable, but rough.
Conduit: Bridges are spotty. Some work great (mautrix-discord is fine). Others assume Synapse-specific APIs. Before deciding on Conduit, check if your target bridge is compatible.
Encryption: E2EE and key backups
All three support encryption out of the box. Clients encrypt messages client-side; servers can’t read them.
- Synapse: Full key backup story. Keys saved server-side, encrypted with your password.
- Dendrite: Works, but key backup is newer. If your client’s key backup broke, recovering is harder.
- Conduit: Works. The story is simpler because Conduit is opinionated.
For personal/family use, don’t overthink this. All three are fine.
Recommendations by use case
Solo user on a Raspberry Pi or VPS: → Conduit. 20 MB RAM, single binary, no fuss. You don’t need every Synapse feature. Just chat.
Family of 4-8 people: → Conduit or Dendrite. Conduit if you want dead-simple deployment and low power. Dendrite if you want more feature parity with Synapse without the RAM overhead.
Small community (10-50 people): → Dendrite or Synapse. Dendrite if you’re budget-conscious and can tolerate some rough edges. Synapse if you need every feature and have hardware to spare.
Medium community (50-500 people) with bridges to other platforms: → Synapse. The bridge ecosystem is too good to pass up. If your community spans Matrix, Discord, IRC, and Slack, Synapse is the only one that holds it together.
Anything larger or mission-critical: → Synapse on a beefy server, probably in polylith mode (multiple services) or even multiple Synapse instances behind a load balancer. By that point, you’re not running a homelab anymore, you’re running infrastructure.
Final thoughts
Matrix is the chat protocol that respects your data. But the server you run matters.
Synapse is the safe choice if you have the hardware and want every feature. Dendrite is the lighter-weight option if you can live with a feature set that’s frozen at security fixes. Conduit is the minimalist’s win if you’re willing to accept intentional limitations.
No wrong choice here. Pick the one that matches your hardware and your patience for rough edges. And honestly? All three are simpler to run than you’d think. Pick one, spin it up in Docker, and get chatting.
Your friends will thank you. Your ISP’s upload bandwidth less so.