How to Install Matrix Synapse + Element on Ubuntu 24.04 — Self-Host Decentralized Chat on Your VPS
Centralized chat platforms control your conversations, your data, and increasingly your ability to say things they disagree with. Discord can delete servers overnight. Slack holds historical messages hostage behind a paywall. WhatsApp and Telegram each know exactly who you talk to, when, and from where. Matrix is the decentralized, federated, end-to-end encrypted alternative — and unlike XMPP or IRC, it has a mature ecosystem, modern mobile apps, voice and video calling, and a growing list of governments and Fortune 500 companies running their own homeservers.
This tutorial walks you through deploying a production-ready Matrix Synapse homeserver with the Element web client on an Ubuntu 24.04 VPS. By the end you will have your own federated chat service at @you:yourdomain.com, able to talk to users on matrix.org, Mozilla, KDE, the German Bundeswehr, and anyone else running Matrix — with all traffic end-to-end encrypted and your server in control of the keys.
Skip the manual config? The Professional VPS plan has the exact specs Synapse needs for a 50-200 user deployment — 6 vCPU, 12 GB RAM, 100 GB NVMe — at a flat monthly rate with unmetered bandwidth.
Table of Contents
Why Self-Host Matrix Instead of Using Discord or Slack?
Matrix is an open protocol, not a product. That single fact drives every other advantage:
- No vendor can delete your community. Your rooms live on your server. Even if matrix.org itself disappeared tomorrow, your homeserver would continue operating and federating with thousands of others.
- End-to-end encryption by default. All direct messages and private rooms are E2EE with the Olm/Megolm double ratchet. Your server stores ciphertext; not even you as the admin can read user messages. Contrast this with Slack, where workspace admins can export everything in plaintext.
- You own the data. Full SQL access to every message, every media file, every reaction. Export, back up, or migrate on your terms — no "Enterprise plan" upsell to access your own history.
- Federation, not islands. A
@alice:yourcompany.comuser can DM@bob:mozilla.orgwithout either of them creating an account on the other's server. It works exactly like email, and it is the feature that kills the network-effect moat of Discord and Slack. - Bridges to everything else. Matrix has mature bridges to Discord, Slack, Telegram, WhatsApp, Signal, IRC, XMPP, SMS, and more. You can run Matrix as the single pane of glass for every chat network your team is already in, and migrate gradually.
- Voice, video, and VoIP. Element supports 1:1 and group audio/video calls, screen sharing, and (with Element Call / LiveKit) scalable group video for dozens of participants — all self-hosted, no Zoom or Google Meet account required.
- Flat cost. A 12 GB VPS costs the same whether 5 or 500 people chat on it. Slack charges per seat, per month, forever.
- Regulatory and sovereignty-friendly. GDPR, HIPAA, and government data-residency requirements are trivially satisfied when the server is in a datacenter you chose, running software you can audit.
If federation turns out to be more than you need, take a look at our guides on installing Mattermost on Ubuntu 24.04 (Slack-style closed team chat) and installing Rocket.Chat on Ubuntu 24.04 (omnichannel customer support focus) — both are excellent alternatives for teams that do not need cross-organization federation.
Architecture Overview
A typical production Matrix deployment on a single VPS looks like this:
┌──────────────────────────────────┐
user @alice:example.com │ VPS (Ubuntu 24.04) │
│ │ │
│ https://element.example.com │ Nginx ──► Element (static) │
├──────────────────────────────►│ │
│ │ Nginx ──► Synapse :8008 │
│ https://matrix.example.com │ (client + federation)│
├──────────────────────────────►│ │ │
│ │ ▼ │
│ https://example.com/.well- │ PostgreSQL 16 │
│ known/matrix/{server, │ │
│ client} │ Bridges (systemd): │
├──────────────────────────────►│ - mautrix-telegram │
│ - mautrix-discord │
federating homeserver (e.g. │ - heisenbridge (IRC) │
matrix.org) hits └──────────────────────────────────┘
https://matrix.example.com:443
after resolving .well-known/matrix/serverThree DNS names, one VPS:
example.com— your apex domain, serves two tiny.well-knownJSON files. This is what appears in user IDs (@alice:example.com).matrix.example.com— the Synapse homeserver. Client API (/_matrix/client) and federation API (/_matrix/federation) both live here on 443.element.example.com— the Element web client (static HTML/JS files served by Nginx).
example.com stays free for your marketing site, and you can redeploy Element independently.Prerequisites
Before you begin, make sure you have:
- A VPS running Ubuntu 24.04 LTS with root or sudo access
- A domain name you control, with the ability to create A / AAAA records
- Ports 80, 443, and 8448 open in your firewall and provider console (8448 is only required if you do not use
.well-knowndelegation; we will use.well-knownin this guide, so 443 is enough for federation) - At least 4 GB of RAM for a small server; 12 GB recommended for any real federated use
- At least 40 GB of disk space, 100 GB recommended (federated rooms accumulate media fast)
Recommended Plan: Professional>
For 50-200 active Matrix users with federation to major homeservers and a couple of bridges, we recommend the Professional VPS plan:>
- 6 vCPU cores
- 12 GB RAM
- 100 GB NVMe SSD
- Unmetered bandwidth, 1 Gbps port>
Synapse is memory-hungry once it joins popular federated rooms — plan RAM first, CPU second.
Connect to your server:
ssh root@your-server-ipStep 1: Prepare DNS and the Server
In your DNS provider (Cloudflare, Route 53, etc.), create these records — replace example.com with your domain and 203.0.113.10 with your server's IP:
| Type | Name | Value |
|---|---|---|
| A | example.com | 203.0.113.10 |
| A | matrix.example.com | 203.0.113.10 |
| A | element.example.com | 203.0.113.10 |
Update the system and open the firewall:
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget gnupg lsb-release ca-certificates ufwsudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enableStep 2: Install PostgreSQL 16
Synapse supports SQLite for tiny deployments, but PostgreSQL is mandatory for anything touching federation. SQLite will collapse under load the first time you join a busy room.
sudo apt install -y postgresql postgresql-contrib
sudo systemctl enable --now postgresqlVerify it is running:
sudo systemctl status postgresqlCreate the Synapse database and user. The LC_COLLATE and LC_CTYPE must be set to C — Synapse rejects any other collation on startup.
sudo -u postgres psql <<'EOF'
CREATE USER synapse_user WITH PASSWORD 'change-this-strong-password';
CREATE DATABASE synapse
ENCODING 'UTF8'
LC_COLLATE='C'
LC_CTYPE='C'
TEMPLATE=template0
OWNER synapse_user;
EOFExpected output:
CREATE ROLE
CREATE DATABASEEdit /etc/postgresql/16/main/pg_hba.conf and ensure there is a line for local password auth for the synapse database:
local synapse synapse_user md5
host synapse synapse_user 127.0.0.1/32 md5Reload PostgreSQL:
sudo systemctl reload postgresqlStep 3: Install Synapse from the Matrix.org Debian Repo
The Matrix.org team maintains an official Debian repository with up-to-date matrix-synapse-py3 packages for Ubuntu 24.04. This is the recommended install path — do not use pip or the old Ubuntu universe package.
sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg \ https://packages.matrix.org/debian/matrix-org-archive-keyring.gpgecho "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" \ | sudo tee /etc/apt/sources.list.d/matrix-org.list
sudo apt update sudo apt install -y matrix-synapse-py3
During install, dpkg will prompt for a server name. Enter your apex domain (e.g. example.com) — NOT matrix.example.com. The server name becomes the domain part of every user ID (@alice:example.com) and cannot be changed later without rebuilding the server.
If you missed the prompt, re-run:
sudo dpkg-reconfigure matrix-synapse-py3Confirm the service installed and started:
sudo systemctl status matrix-synapseSynapse listens on 127.0.0.1:8008 by default.
Step 4: Configure homeserver.yaml
The main config lives at /etc/matrix-synapse/homeserver.yaml. Open it:
sudo nano /etc/matrix-synapse/homeserver.yamlMake these changes:
Server name (should already be set from the install prompt):
server_name: "example.com"
public_baseurl: "https://matrix.example.com/"Switch the database from SQLite to PostgreSQL. Find the database: block and replace it with:
database:
name: psycopg2
args:
user: synapse_user
password: change-this-strong-password
database: synapse
host: 127.0.0.1
cp_min: 5
cp_max: 10Registration settings. Keep open signups disabled and generate a shared secret you will use to create admin users from the command line:
enable_registration: false
registration_shared_secret: "PASTE-64-HEX-CHARS-HERE"Generate the secret with:
openssl rand -hex 32Paste the resulting 64-character string into the YAML.
Media and upload limits:
max_upload_size: 50M
media_store_path: "/var/lib/matrix-synapse/media"
url_preview_enabled: true
url_preview_ip_range_blacklist:
- '127.0.0.0/8'
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
- '100.64.0.0/10'
- '169.254.0.0/16'Federation — leave the defaults (federation is enabled). If you want a closed server, add:
federation_domain_whitelist: []Save and exit. Restart Synapse and inspect the logs:
sudo systemctl restart matrix-synapse
sudo journalctl -u matrix-synapse -n 50 --no-pagerYou should see Synapse now listening on TCP port 8008 with no Python tracebacks.
Step 5: Register the First Admin User
Open registration is disabled, but with the registration_shared_secret you can create users (including admins) from the CLI.
register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml http://localhost:8008Example session:
New user localpart [root]: alice
Password:
Confirm password:
Make admin [no]: yes
Sending registration request...
Success.The user ID will be @alice:example.com once .well-known delegation is in place (Step 7). Before that, it is @alice:<whatever-server_name-is>.
Step 6: Nginx Reverse Proxy and TLS
Install Nginx and Certbot:
sudo apt install -y nginx certbot python3-certbot-nginxVhost for the Matrix server (matrix.example.com)
sudo tee /etc/nginx/sites-available/matrix > /dev/null <<'EOF' server { listen 80; listen [::]:80; server_name matrix.example.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name matrix.example.com;
ssl_certificate /etc/letsencrypt/live/matrix.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/matrix.example.com/privkey.pem;
# Federation uploads can be large client_max_body_size 50M;
# Matrix client + federation API location ~ ^(/_matrix|/_synapse/client) { proxy_pass http://127.0.0.1:8008; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; proxy_http_version 1.1; proxy_read_timeout 600s; }
location / { return 404; } } EOF
Vhost for the Element web client (element.example.com)
sudo tee /etc/nginx/sites-available/element > /dev/null <<'EOF' server { listen 80; listen [::]:80; server_name element.example.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name element.example.com;
ssl_certificate /etc/letsencrypt/live/element.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/element.example.com/privkey.pem;
root /var/www/element; index index.html;
# Long cache for versioned assets, no cache for config location ~* \.(js|css|woff2|png|svg|jpg)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location = /config.json { add_header Cache-Control "no-store"; }
location / { try_files $uri $uri/ /index.html; } } EOF
Vhost for the apex domain (serves .well-known)
sudo tee /etc/nginx/sites-available/apex > /dev/null <<'EOF' server { listen 80; listen [::]:80; server_name example.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/apex;
location /.well-known/matrix/ { default_type application/json; add_header Access-Control-Allow-Origin *; }
location / { try_files $uri $uri/ =404; } } EOF
Enable the sites and issue certificates:
sudo ln -sf /etc/nginx/sites-available/matrix /etc/nginx/sites-enabled/ sudo ln -sf /etc/nginx/sites-available/element /etc/nginx/sites-enabled/ sudo ln -sf /etc/nginx/sites-available/apex /etc/nginx/sites-enabled/ sudo mkdir -p /var/www/apex /var/www/element sudo rm -f /etc/nginx/sites-enabled/defaultsudo certbot certonly --nginx -d example.com -d matrix.example.com -d element.example.com \ --non-interactive --agree-tos --email [email protected]
sudo nginx -t && sudo systemctl reload nginx
Certbot installs a daily systemd timer that auto-renews.
Step 7: Publish .well-known Delegation Files
Without delegation, other Matrix servers try to federate with you on port 8448 of your apex domain — which would require running Synapse there and breaks your marketing site. The .well-known mechanism lets you tell the world "reach example.com user accounts via matrix.example.com:443."
Server delegation (for other homeservers):
sudo mkdir -p /var/www/apex/.well-known/matrix
sudo tee /var/www/apex/.well-known/matrix/server > /dev/null <<'EOF'
{"m.server": "matrix.example.com:443"}
EOFClient discovery (so Element auto-detects the homeserver when a user logs in with @alice:example.com):
sudo tee /var/www/apex/.well-known/matrix/client > /dev/null <<'EOF'
{
"m.homeserver": {"base_url": "https://matrix.example.com"},
"m.identity_server": {"base_url": "https://vector.im"}
}
EOFTest both:
curl https://example.com/.well-known/matrix/server
curl https://example.com/.well-known/matrix/clientBoth must return valid JSON with Content-Type: application/json and CORS headers.
Step 8: Deploy the Element Web Client
Element is a static single-page application. Download the latest release tarball from GitHub and serve it with Nginx.
ELEMENT_VERSION=$(curl -s https://api.github.com/repos/element-hq/element-web/releases/latest | grep tag_name | cut -d '"' -f 4)
cd /tmp
wget "https://github.com/element-hq/element-web/releases/download/${ELEMENT_VERSION}/element-${ELEMENT_VERSION}.tar.gz"
tar -xzf "element-${ELEMENT_VERSION}.tar.gz"
sudo rm -rf /var/www/element/*
sudo cp -r element-/ /var/www/element/
sudo chown -R www-data:www-data /var/www/elementCreate /var/www/element/config.json to pin it to your homeserver:
sudo tee /var/www/element/config.json > /dev/null <<'EOF'
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.example.com",
"server_name": "example.com"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"brand": "Example Chat",
"default_country_code": "US",
"disable_custom_urls": true,
"disable_guests": true,
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"features": {
"feature_pinning": true,
"feature_custom_status": true
},
"showLabsSettings": false,
"room_directory": {
"servers": ["example.com", "matrix.org"]
}
}
EOFSetting disable_custom_urls: true locks users into your homeserver — they cannot accidentally log into matrix.org through your Element install.
Reload Nginx:
sudo systemctl reload nginxVisit https://element.example.com in a browser. You should see the Element login screen branded for your server. Log in with the admin account you created in Step 5.
Step 9: Verify Federation
Point a browser at the official Matrix Federation Tester and enter example.com. Every check should pass:
WellKnown— valid JSON at/.well-known/matrix/serverDNS— A record formatrix.example.comresolvesConnectionReports— TLS handshake, certificate chain, version negotiation all green
curl https://matrix.example.com/_matrix/federation/v1/versionExpected:
{"server":{"name":"Synapse","version":"1.115.0"}}Now test an actual federation round-trip. From Element, click "Explore rooms," switch the directory to matrix.org, and join #matrix:matrix.org. Messages should appear within a few seconds. If you see the spinner forever, skip to Troubleshooting.
Step 10: Install Appservice Bridges
Bridges are separate processes that connect Matrix to another network via Synapse's appservice API. Each one registers an application_service.yaml file that Synapse loads on startup.
Telegram Bridge (mautrix-telegram)
Mautrix-telegram is the most polished Telegram bridge and supports puppeting (your Matrix messages appear from your real Telegram account).
sudo useradd -r -s /bin/false -d /opt/mautrix-telegram mautrix-telegram
sudo mkdir -p /opt/mautrix-telegram
sudo chown mautrix-telegram:mautrix-telegram /opt/mautrix-telegram
sudo -u mautrix-telegram python3 -m venv /opt/mautrix-telegram/venv
sudo -u mautrix-telegram /opt/mautrix-telegram/venv/bin/pip install mautrix-telegram[all]
sudo -u mautrix-telegram /opt/mautrix-telegram/venv/bin/python -m mautrix_telegram -g -c /opt/mautrix-telegram/config.yamlEdit /opt/mautrix-telegram/config.yaml:
- Set
homeserver.address: https://matrix.example.comanddomain: example.com - Get an API ID + hash from my.telegram.org/apps and paste into the
telegram:section - Set
bridge.permissionswith your Matrix user ID asadmin
sudo -u mautrix-telegram /opt/mautrix-telegram/venv/bin/python -m mautrix_telegram \
-g -c /opt/mautrix-telegram/config.yaml -r /opt/mautrix-telegram/registration.yaml
sudo cp /opt/mautrix-telegram/registration.yaml /etc/matrix-synapse/mautrix-telegram.yamlAdd to /etc/matrix-synapse/homeserver.yaml:
app_service_config_files:
- /etc/matrix-synapse/mautrix-telegram.yamlCreate a systemd unit for the bridge and restart Synapse:
sudo tee /etc/systemd/system/mautrix-telegram.service > /dev/null <<'EOF' [Unit] Description=mautrix-telegram bridge After=matrix-synapse.service[Service] Type=simple User=mautrix-telegram WorkingDirectory=/opt/mautrix-telegram ExecStart=/opt/mautrix-telegram/venv/bin/python -m mautrix_telegram -c /opt/mautrix-telegram/config.yaml Restart=on-failure
[Install] WantedBy=multi-user.target EOF
sudo systemctl daemon-reload sudo systemctl enable --now mautrix-telegram sudo systemctl restart matrix-synapse
Start a DM with @telegrambot:example.com in Element and follow the login instructions to link your Telegram account.
Discord Bridge (mautrix-discord)
Follow the same pattern — install mautrix-discord into its own directory, generate registration, add to app_service_config_files, restart Synapse. Full instructions live at docs.mau.fi/bridges/go/discord/setup.html. Mautrix-discord supports portal rooms (a whole Discord server mirrored into Matrix), DMs, threads, reactions, stickers, and voice channel presence.
IRC Bridge (Heisenbridge)
Heisenbridge is a single-file "bouncer style" IRC bridge — each Matrix user connects to IRC with their own credentials. It is far simpler to deploy than the legacy matrix-appservice-irc for personal or small-team use.
sudo pip3 install heisenbridge --break-system-packages
heisenbridge -c /etc/matrix-synapse/heisenbridge.yaml --generateAdd to app_service_config_files, create a systemd unit analogous to the Telegram one, and restart Synapse. Then invite @heisenbridge:example.com to a new DM for the setup wizard — you can connect to Libera.Chat, OFTC, and any other IRC network from there.
Hardening and Maintenance
Automatic media retention. Federated media piles up fast. Add to homeserver.yaml:
retention:
enabled: true
default_policy:
min_lifetime: 1d
max_lifetime: 365dPostgreSQL backups. Nightly dump via cron:
0 3 * postgres pg_dump synapse | gzip > /var/backups/synapse-$(date +\%F).sql.gzKeep Synapse updated. sudo apt upgrade pulls the latest release. Subscribe to the Matrix security disclosure list — Synapse issues CVEs several times a year.
Monitor with Prometheus. Synapse exposes /metrics on port 9000 when you set enable_metrics: true. Point a Prometheus + Grafana stack at it for room counts, federation lag, and memory usage.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Federation tester fails with "no route to homeserver" | .well-known/matrix/server missing, wrong Content-Type, or Cloudflare proxy rewriting response | curl -I https://example.com/.well-known/matrix/server — must be 200, application/json, CORS . Turn off Cloudflare proxy for the apex. |
| Synapse eats 8+ GB RAM and OOMs | Joined #matrix:matrix.org or another huge room | Leave massive rooms, add swap, set caches: global_factor: 0.5 in homeserver.yaml, or upgrade RAM. |
register_new_matrix_user fails with 403 | registration_shared_secret unset or mismatched | Regenerate with openssl rand -hex 32, paste into homeserver.yaml, restart Synapse. |
| Element shows "Can't connect to homeserver" | CORS on .well-known/matrix/client missing or wrong base_url | Verify response includes Access-Control-Allow-Origin: and "base_url": "https://matrix.example.com" with no trailing slash. |
| Bridges send messages but Matrix users can't reply | Appservice sender_localpart collides with an existing user, or registration file not in app_service_config_files | Check journalctl -u matrix-synapse for appservice load errors on startup. |
| TLS chain incomplete (federation only) | Nginx configured with cert.pem instead of fullchain.pem | Point ssl_certificate at fullchain.pem — it contains the intermediate. |
sudo journalctl -u matrix-synapse -f
sudo tail -f /var/log/matrix-synapse/homeserver.logFAQ
Do I have to federate, or can I run a closed Matrix server?
Federation is optional. Set federation_domain_whitelist: [] in homeserver.yaml or block outbound 443 from the server — Synapse will only talk to its own users. You keep end-to-end encrypted chat, voice, video, and bridges to other networks, but your users cannot join rooms on matrix.org or DM external accounts. This is a legitimate deployment for regulated industries or internal-only corporate chat.
How much RAM does Synapse actually need?
A 5-person private server runs happily on 2 GB. The moment anyone joins #matrix:matrix.org, #rust-lang:matrix.org, or any other popular federated room, working memory jumps to 4-6 GB as Synapse caches thousands of member events. Plan for 8-12 GB for 50-200 active users, with PostgreSQL wanting another 2-4 GB on top. The Professional 6 vCPU / 12 GB plan is the practical minimum for a federated deployment; anything smaller will swap under real load.
Why do I need two subdomains plus a .well-known file?
The server_name in user IDs (@alice:example.com) is semantically separate from the HTTP endpoint where Synapse actually runs. Keeping Synapse on matrix.example.com frees port 443 on the apex for your website. The .well-known/matrix/server file tells federating servers "reach example.com users at matrix.example.com:443," and .well-known/matrix/client does the same for Element and mobile apps during login auto-discovery. Without these files, other homeservers would expect Synapse on example.com:8448, which would conflict with any normal web presence.
Can I migrate from Discord or Slack?
Yes. mautrix-discord and mautrix-slack puppet bridges mirror channels, DMs, threads, reactions, and file uploads bidirectionally. You can run Matrix alongside Discord/Slack while users migrate, then retire the old platform. Historical message import is a manual export/replay (the bridges ship scripts for it), but day-forward mirroring is out-of-the-box. Many open source projects have used this approach to move communities without losing anyone.
Is Synapse the only Matrix homeserver?
No. Dendrite (Go, from the core Matrix team) and Conduit (Rust, community) are lighter-weight alternatives. Synapse is the reference implementation with the most features, the best docs, and the biggest community — which is why this guide uses it and why it is right for production. Dendrite is a strong choice if you need a smaller memory footprint; Conduit is excellent for a 1-10 user personal server and can run in under 200 MB RAM.
How do I enable end-to-end encryption?
You do not — it is client-side and is on by default for new direct messages and private rooms in Element. Synapse stores and relays ciphertext; it never sees plaintext. What you should do is enable cross-signing and secure key backup in Element (Settings > Security & Privacy), which lets users recover their message history on new devices. Without key backup, a user who reinstalls Element loses access to all their encrypted messages — this is the single most common self-host support ticket.
Should I allow open registration?
Almost never. Public Matrix servers with open signup get overrun by spam bots that join federated rooms and cause your domain to get blocked across the network. Keep enable_registration: false and create accounts with register_new_matrix_user, or add registration tokens (registrations_require_token: true), or wire up SSO via Keycloak, Authentik, or GitHub OAuth for self-service signup with guardrails.
Next Steps
Now that your Matrix stack is running, here is where to go next:
- Enable Element Call for group video. Element Call uses LiveKit for scalable SFU-based video conferencing — deploy the LiveKit server, wire it into homeserver.yaml, and replace Zoom for internal meetings.
- Explore the other self-hosted chat options. If federation is more than you need, see our guides on installing Mattermost on Ubuntu 24.04 (Slack-style team chat, no federation) and installing Rocket.Chat on Ubuntu 24.04 (omnichannel customer support with WhatsApp/Facebook integration).
- Add identity providers. Wire Synapse into Keycloak, Authentik, or your corporate SAML IdP so staff log in with SSO instead of managing a separate Matrix password.
- Set up automatic purges. Configure
retentionin homeserver.yaml and run the admin APIPOST /_synapse/admin/v1/media/<server_name>/deletemonthly to reclaim disk. - Read the official Synapse docs. The matrix-org.github.io/synapse site is the canonical reference for every config option, admin API, and upgrade path — bookmark it.
Skip the Manual Install — Deploy Matrix on a Professional VPS>
Run Synapse + Element for a 50-200 user team on our Professional plan — 6 vCPU, 12 GB RAM, 100 GB NVMe, unmetered 1 Gbps, at a flat monthly rate. Full root access, snapshots, and DDoS protection included.>
Launch a Professional VPS and start self-hosting decentralized chat in under an hour.