The NordBastion polar-bear mascot conducting a federation graph of cyan node-globes connected by glowing lines with floating speech-bubble icons representing end-to-end encrypted messages, aurora borealis through Nordic observatory windows
How-to · 2h hands-on·Updated 2026

Self-host Matrix on a VPS.
Synapse + Element. Federated. End-to-end encrypted.

Matrix is what email would look like if it had been designed for chat in the open-protocol era. Synapse as the homeserver, Element as the client, PostgreSQL as the store, Caddy as the front door — and a federated room graph that nobody in particular owns.

TL;DR
  • 01

    Synapse is the right default homeserver in 2026 — the production-proven, fully-featured reference implementation. Conduit and Dendrite are valid for narrower use-cases.

  • 02

    Switch to PostgreSQL on day one; the default SQLite is for testing only and falls over above a handful of users. Plan disk for media uploads — federated rooms accumulate them quickly.

  • 03

    Closed registration is the safe default. Public registration is real moderation work; only enable it if you mean to take it on.

Chapter 1

Matrix in five sentences. What you are actually deploying.

Matrix is an open protocol for real-time communication. A homeserver is a server that runs the protocol; users belong to one homeserver each, identified as @alice:example.com — the same pattern as email. Rooms are the units of conversation; a single room can have members from many different homeservers, and the room state is replicated across all participating homeservers. Private rooms encrypt every message with per-device keys (Olm/Megolm) so the server only sees ciphertext. The whole network is a graph of homeservers federating room state to each other.

The interesting properties: no central authority can shut Matrix down (the protocol is open and runs everywhere), users on different servers talk transparently (federation), private rooms have proper end-to-end encryption (not advertising-style encryption-in-transit), and a user can switch homeservers and keep their identity by running their own. The trade-off is operational complexity — running a homeserver is more work than logging into Discord — and a smaller polished-client ecosystem than the proprietary platforms.

What you deploy in this guide: Synapse (the homeserver), PostgreSQL (its database), Element Web (the browser client, hosted from your own domain), and Caddy (the reverse proxy + automatic TLS). Optionally a media-storage backend and the well-known endpoints for federation discovery. The whole stack is two Docker Compose files and one Caddy config.

Chapter 2

Sizing. Synapse is memory-shaped.

Synapse holds per-room state in memory, and joining a large federated room (say #matrix:matrix.org with 60,000 members) pulls a lot of that state into your homeserver. The result is that even a single-user Synapse can use 2–3 GB of RAM steadily if the user is in busy federated rooms. Plan accordingly.

Single user, modest federation. 2 vCPU, 4 GB RAM, 40 GB SSD. The <a href="/vps/" class="text-nord-cyan border-b border-nord-cyan/40 hover:border-nord-cyan transition">Ravelin tier ($5.90/mo)</a> at NordBastion is correctly sized. Disk grows by ~10 GB/year for an active single user; provision room for that.

Small team, 5–20 users. 4 vCPU, 8 GB RAM, 100 GB SSD. The Iron tier ($24.90/mo) handles this comfortably. Run PostgreSQL on the same VPS; the database fits in spare RAM and disk.

Public homeserver, 100+ users. Past 100 active users, Synapse benefits from worker processes (separate federation sender, federation reader, client reader workers) and a tuned PostgreSQL. The Iron or Granite tiers handle this, but the operational complexity grows non-linearly — at that scale you are a Matrix admin in addition to a software user.

Disk reality. Media uploads (images, videos, files) from federated rooms accumulate on your homeserver because Matrix federation pulls media to local for serving. A busy public homeserver can add 1 GB of media per week. The Synapse media_retention configuration lets you prune older content; review it once a quarter.

Chapter 3

The Docker Compose install. Synapse, PostgreSQL, Element.

Spin up a fresh Debian 12 VPS, point three DNS records at it: matrix.example.com (the homeserver hostname), element.example.com (the web client), and example.com itself if you want the @alice:example.com identifier short-form. SSH in as sudo user.

1. Install Docker and Compose. curl -fsSL https://get.docker.com | sh — Docker Engine ships Compose v2 in the same package.

2. Generate the Synapse config. mkdir -p ~/synapse/data && docker run -it --rm -v ~/synapse/data:/data -e SYNAPSE_SERVER_NAME=example.com -e SYNAPSE_REPORT_STATS=no matrixdotorg/synapse:latest generate — this writes homeserver.yaml. Edit it: change database from SQLite to PostgreSQL, set the media URL, set enable_registration: false to start (you create users via the admin CLI for now).

3. Write docker-compose.yml. Three services: postgres (postgres:16, persistent volume, locale C), synapse (matrixdotorg/synapse:latest, mounts ~/synapse/data, depends on postgres), element (vectorim/element-web:latest, mounts a small config.json pointing at https://matrix.example.com). Map only synapse:8008 and element:80 to localhost; do not bind 0.0.0.0.

4. Front with Caddy. Two Caddyfile sites: matrix.example.com proxies to 127.0.0.1:8008 (Synapse) on both ports 443 and 8448 (the federation port); element.example.com proxies to 127.0.0.1:8001 (Element Web). Caddy fetches Let's Encrypt certificates automatically.

5. Federation discovery (.well-known). Add two static JSON files on example.com itself: /.well-known/matrix/server returning {"m.server": "matrix.example.com:443"} and /.well-known/matrix/client returning {"m.homeserver": {"base_url": "https://matrix.example.com"}}. This lets short-form identifiers @alice:example.com resolve correctly. Verify with the Federation Tester at federationtester.matrix.org.

6. Create your first user. docker exec -it synapse register_new_matrix_user -u alice -p <password> -a -c /data/homeserver.yaml http://localhost:8008 — that creates an admin account. Log in via https://element.example.com.

Chapter 4

Element, branding, registration policy. The decisions that stick.

Element configuration. Element Web reads a config.json that points at your homeserver, sets the default theme, branding, and the list of "suggested rooms" for new accounts. Set default_server_config.m.homeserver.base_url to https://matrix.example.com, brand to your project name, and disable the matrix.org-suggesting brand_url field. New users land on Element Web pointed at your server, not somebody else's.

Registration policy. Three modes: closed (only the admin can register users via the CLI; the cleanest moderation posture), token-based (you generate registration tokens via the admin API and share them; better for a small group), open (anyone can register; only enable if you intend to operate a public homeserver with moderation tooling). Start closed and only relax if you have a reason.

Federation block-list. Synapse supports federation_domain_whitelist (allow-list only) and per-server blocks via the admin API. For most public homeservers, the default is "federate with everything", with reactive blocks of abusive servers as needed. The Mjolnir bot automates this if you become a target.

Backups. PostgreSQL nightly dump + ~/synapse/data tarball, sent off-server via rclone to a second VPS or B2 bucket. Both are required; the database is the room state and accounts, the data directory holds the signing keys and media. Restore tests every quarter, as for any backup.

Chapter 5

The moderation reality. What self-hosting actually means.

Running a Matrix homeserver means accepting that the host is responsible for what the server does. On a private invite-only homeserver, that responsibility is small — you know every user. On a public homeserver, the responsibility scales with the user base.

Inbound abuse. A federated public room can be drawn into abuse coordination, image dumps, or harassment. Synapse exposes admin API endpoints to ban a user (across all rooms), block a homeserver (no further federation), and force a server to leave a room. The Mjolnir bot wraps these into a moderation room workflow; the Draupnir fork is its actively-maintained continuation.

Outbound abuse. A compromised user account can post abusive content to federated rooms, which damages your server's reputation with the rest of the network. Two mitigations: rate-limit per-user (Synapse default rate limits are reasonable), and require email verification for new accounts (raises the bar on automated registration).

Legal posture. In the EU, an infrastructure-provider role gives strong intermediary liability protections (e-Commerce Directive Article 14, DSA Article 6) — you are not liable for user content as long as you respond to notice and takedown. The Nordic jurisdictions extend this with explicit constitutional press-freedom protections. The same homeserver run in a jurisdiction without intermediary protections is operationally riskier; choose the host location accordingly.

The safe default. Invite-only registration, federation enabled with reactive blocks, Mjolnir / Draupnir installed but unused until needed, terms of service published on the homeserver website with a clear acceptable-use policy. That posture handles 95% of operators without further effort.

Chapter 6

Why the host matters. Encryption protects content, the host protects metadata.

Matrix E2EE protects message bodies — the server holds ciphertext only for private rooms. What it does not protect is the metadata: which homeservers federate with each other, which users are in which rooms, when they are online, how often they send messages, what their devices are. That metadata graph lives on the homeserver and the homeservers it federates with, and is technically out of reach of the encryption layer.

A homeserver running on a KYC-linked VPS ties the metadata graph to the legal identity of the operator. A subpoena to the host yields not just the encrypted database but the link from the @alice:example.com identifier to a real-world name. The encryption still holds; the metadata layer is open.

NordBastion's posture is the inverse: <a href="/doctrine/" class="text-nord-cyan border-b border-nord-cyan/40 hover:border-nord-cyan transition">no-KYC signup</a>, crypto payment, Nordic constitutional jurisdictions. The homeserver is yours; the link from the homeserver back to a name does not exist; the legal regime that touches the disk has explicit press-freedom protections. The combination matches the security model of Matrix itself — both the cryptographic content layer and the metadata operational layer are defended.

FAQ · Self-host Matrix

Questions, answered.

Eight questions that come up running a Matrix homeserver in 2026.

What is Matrix and how is it different from Discord or Slack?

Matrix is a federated, open-standard real-time communication protocol — think SMTP for chat. Anyone runs a homeserver (Synapse, Dendrite, Conduit), users on different homeservers talk to each other transparently, every message in a private room is end-to-end encrypted by default, no central company controls the network. Discord and Slack are centralised, proprietary, and the company hosts every conversation. The trade-off: Matrix has slightly higher operational complexity and a smaller polished-client ecosystem, but you own every byte.

Synapse, Dendrite or Conduit — which homeserver?

Synapse is the reference, written in Python, the most feature-complete and the production-proven choice. It is memory-heavy. Dendrite is the newer Go rewrite, much lighter, missing a few advanced moderation features but rapidly closing the gap. Conduit is the third option, a Rust homeserver focused on tiny resource footprint, good for a single-user homeserver on a cheap VPS. Default to Synapse unless you have a specific reason — the documentation, the moderation tooling and the third-party bridges all assume Synapse.

How much VPS do I need for a Matrix homeserver?

Single user federating to the broader Matrix network — 2 vCPU, 4 GB RAM, 40 GB SSD is the practical floor. Small team (5–20 users) — 4 vCPU, 8 GB RAM, 100 GB SSD. The Ravelin or Iron tiers cover both cases. The dominant resource is RAM (Synapse keeps a lot of room state in memory) and disk (media uploads and federated room history grow continuously).

Should I enable federation?

Almost always yes — it is the whole point of Matrix. Federation lets your users talk to anyone on matrix.org, mozilla.org, kde.org and the thousands of other homeservers. The exceptions: a private internal-team server where you do not want anyone discovering rooms; a high-risk threat model where federation traffic patterns leak information; a server hosting sensitive subject matter where you want strict membership control. Disabling federation later is fine; re-enabling it makes you discoverable.

Are private rooms end-to-end encrypted by default?

Yes — every Element client enables E2EE by default for new direct messages and private rooms. The encryption is per-room Olm/Megolm with cross-signed device verification. The server only sees ciphertext for the message body. Public rooms are unencrypted by design (since anyone can join, the encryption would not protect anything). Federated public rooms are visible to anyone — which is the point of a public room.

What is the moderation reality of running a public homeserver?

It is real work. If you allow public registration, your homeserver will federate to spam-rooms, get drawn into abuse coordination rooms, and occasionally surface objectionable content from federated servers. Running a public homeserver requires the willingness to apply server-level bans, federate-block hostile servers, and respond to abuse reports. For most operators, the correct posture is closed registration (invite-only) — every user is someone you know, and the abuse surface drops to roughly zero.

Can I use my Matrix homeserver as a Slack / Discord replacement at work?

Yes — Element Server Suite and the underlying Synapse + Element Web combination cover the "team chat with persistent rooms, threads, reactions, voice/video huddles" feature set. The main gap relative to Slack is third-party integrations (fewer pre-built apps); the main gap relative to Discord is the polished voice channels. Both are workable but require a bit of operator effort. For a small team that values data sovereignty over polish, the trade is clearly worth it.

Why does the host I rent the VPS from matter for a Matrix server?

Because the federated chat protocol creates persistent metadata about who-talks-to-whom-when at the homeserver. That metadata is rich (federated room graph, federation events, media uploads). Putting it on a host with KYC ties the metadata to your identity; putting it on a host in a hostile jurisdiction means a state actor can compel it. A no-KYC Nordic VPS aligns the metadata posture of the host with the cryptographic posture of the protocol — both halves of the privacy story.

Get the metal

A Nordic VPS for your homeserver. KYC-free, crypto-paid.

Ravelin (2 vCPU, 4 GB, $5.90/mo) covers a single-user federating Synapse. Iron (4 vCPU, 8 GB, $24.90/mo) is the small-team answer.

Last reviewed · 2026-05-20 · Sources · Synapse upstream docs, Element config reference, Matrix specification, EU DSA Article 6 · Cadence · yearly