Self-Hosting Matrix with Element: Decentralized Chat You Actually Control
Your team's on Slack, your gaming friends are on Discord, your family uses WhatsApp, and your open source community is on IRC. Each platform owns your messages, each can read them, and each locks you into their ecosystem. If Slack decides to delete messages older than 90 days on the free tier (they did), you lose your history.
Matrix is an open standard for decentralized communication. You run your own server, you own your data, and you can still talk to people on other Matrix servers — or bridge to Slack, Discord, WhatsApp, and more.
How Matrix Works
Matrix is a protocol, not a single service. Here's the architecture:
- Homeserver: Your server that stores your messages and syncs with other servers (like email servers sync with each other)
- Client: The app you use to chat (Element is the most popular)
- Federation: Your server can talk to any other Matrix server, so
@alice:yourserver.comcan message@bob:matrix.org - Bridges: Connect Matrix to other platforms (Slack, Discord, WhatsApp, IRC, Signal)
Think of it like email: you can run your own email server and still send messages to Gmail users. Matrix works the same way for chat.
Matrix vs. The Alternatives
| Feature | Slack | Discord | Matrix (self-hosted) |
|---|---|---|---|
| Message retention | 90 days (free) | Unlimited | Unlimited (your storage) |
| End-to-end encryption | Enterprise only | No | Yes (default for DMs) |
| Federation | No | No | Yes |
| Data ownership | Slack Inc. | Discord Inc. | You |
| Bridges to other platforms | Limited | Limited | Extensive |
| Voice/Video | Yes | Yes | Yes (Jitsi/native) |
| Bots and integrations | Excellent | Excellent | Good |
| File storage | 5 GB (free) | 25 MB per file | Your disk |
| Monthly cost | Free-$12.50/user | Free-$9.99 | Your hardware |
Choosing a Homeserver
Synapse (Reference Implementation)
Synapse is the original Matrix homeserver written in Python. It's the most feature-complete and widely deployed.
services:
synapse:
image: matrixdotorg/synapse:latest
restart: unless-stopped
volumes:
- synapse_data:/data
environment:
SYNAPSE_SERVER_NAME: matrix.yourdomain.com
SYNAPSE_REPORT_STATS: "no"
ports:
- 8008:8008
postgres:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- synapse_db:/var/lib/postgresql/data
environment:
POSTGRES_DB: synapse
POSTGRES_USER: synapse
POSTGRES_PASSWORD: changeme
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
volumes:
synapse_data:
synapse_db:
Generate the initial config:
docker run --rm \
-v synapse_data:/data \
-e SYNAPSE_SERVER_NAME=matrix.yourdomain.com \
-e SYNAPSE_REPORT_STATS=no \
matrixdotorg/synapse:latest generate
Pros: Full feature support, most bridges work best with it, large community. Cons: Resource-hungry (1-2 GB RAM minimum), Python performance, database can grow large.
Conduit (Lightweight Alternative)
Conduit is a Matrix homeserver written in Rust. It's fast, lightweight, and simple to configure.
services:
conduit:
image: matrixconduit/matrix-conduit:latest
restart: unless-stopped
ports:
- 6167:6167
volumes:
- conduit_data:/var/lib/matrix-conduit
environment:
CONDUIT_SERVER_NAME: matrix.yourdomain.com
CONDUIT_DATABASE_BACKEND: rocksdb
CONDUIT_PORT: 6167
CONDUIT_MAX_REQUEST_SIZE: 20000000
CONDUIT_ALLOW_REGISTRATION: "false"
CONDUIT_ALLOW_FEDERATION: "true"
CONDUIT_TRUSTED_SERVERS: '["matrix.org"]'
volumes:
conduit_data:
Pros: ~10 MB RAM, single binary, embedded database (no Postgres needed), fast. Cons: Missing some advanced features, fewer bridges tested, smaller community.
For most self-hosters: Start with Conduit if you want a personal/family server. Use Synapse if you need bridges or are running a community.
Setting Up Element Web
Element is the primary Matrix client. Host it alongside your homeserver:
services:
element:
image: vectorim/element-web:latest
restart: unless-stopped
ports:
- 8080:80
volumes:
- ./element-config.json:/app/config.json:ro
element-config.json:
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.yourdomain.com",
"server_name": "yourdomain.com"
}
},
"brand": "Element",
"default_theme": "dark",
"room_directory": {
"servers": ["yourdomain.com", "matrix.org"]
}
}
Element is also available as a desktop app (Electron) and mobile apps (iOS/Android) — point them at your homeserver URL.
Federation: Talking to Other Servers
Federation requires proper DNS and reverse proxy setup.
DNS Records
_matrix._tcp.yourdomain.com. 3600 IN SRV 10 5 443 matrix.yourdomain.com.
Or use a .well-known file. Serve this at https://yourdomain.com/.well-known/matrix/server:
{
"m.server": "matrix.yourdomain.com:443"
}
And at https://yourdomain.com/.well-known/matrix/client:
{
"m.homeserver": {
"base_url": "https://matrix.yourdomain.com"
}
}
Reverse Proxy (Caddy example)
matrix.yourdomain.com {
reverse_proxy /_matrix/* synapse:8008
reverse_proxy /_synapse/* synapse:8008
}
chat.yourdomain.com {
reverse_proxy element:80
}
Test federation at federationtester.matrix.org — it'll check your DNS and connectivity.
Bridges: Connecting Other Platforms
Bridges are Matrix's superpower. They let you interact with other chat platforms through your Matrix client.
Popular Bridges
| Bridge | Connects To | Puppeting | Notes |
|---|---|---|---|
| mautrix-slack | Slack | Yes | Full message sync, reactions, threads |
| mautrix-discord | Discord | Yes | Messages, reactions, attachments |
| mautrix-whatsapp | Yes | E2EE preserved, media sync | |
| mautrix-signal | Signal | Yes | Full message sync |
| mautrix-telegram | Telegram | Yes | Messages, stickers, media |
| Heisenbridge | IRC | Yes | Replaces the old matrix-appservice-irc |
Example: Discord Bridge
services:
mautrix-discord:
image: dock.mau.dev/mautrix/discord:latest
restart: unless-stopped
volumes:
- discord_bridge:/data
volumes:
discord_bridge:
After starting, generate a config with docker exec, edit it to point at your homeserver, register the appservice with Synapse, and log in with your Discord token. Your Discord DMs and servers appear as Matrix rooms.
The result: You can read and reply to Slack, Discord, and WhatsApp messages all from Element. One client for everything.
End-to-End Encryption
Matrix supports end-to-end encryption (E2EE) using the Olm/Megolm protocols (the same cryptographic design Signal uses).
- DMs: Encrypted by default
- Group chats: Optional, can be enabled per room
- Key backup: Set up cross-signing and key backup so you don't lose message history when adding new devices
Important: E2EE means your server can't read message contents. This is great for privacy but means server-side search only works on unencrypted rooms.
Performance Tuning for Synapse
If you go with Synapse, these settings matter:
homeserver.yaml:
# Use PostgreSQL, not SQLite
database:
name: psycopg2
args:
database: synapse
user: synapse
password: changeme
host: postgres
# Limit federation (if you don't need it)
# federation_domain_whitelist:
# - matrix.org
# Media storage limits
max_upload_size: 50M
url_preview_enabled: true
Resource expectations for Synapse:
- Small (1-5 users, no bridges): 512 MB RAM
- Medium (5-50 users, some bridges): 1-2 GB RAM
- Large (50+ users, many bridges, federation): 4+ GB RAM
Common Pitfalls
- Synapse database growth: Media and message history accumulate. Set up the Synapse Admin API to purge old remote media.
- Federation debugging: Use the Matrix Federation Tester. 90% of federation issues are DNS or reverse proxy misconfigs.
- Bridge maintenance: Bridges need updating separately from the homeserver. Pin versions and update deliberately.
- Key verification: Educate your users about cross-signing verification. Without it, E2EE provides weaker guarantees.
The Bottom Line
Matrix gives you a Slack/Discord-quality chat experience that you fully own and control. Federation means you're not isolated — you can talk to anyone on the Matrix network. Bridges mean you can consolidate all your chat platforms into one client.
The tradeoff is complexity. Synapse is heavier than most self-hosted apps, bridges require per-platform setup, and federation needs proper DNS configuration. But for anyone serious about owning their communications, Matrix is the strongest option available.