How to self-host a Matrix Synapse homeserver: sizing, federation, and the public-room limit

Size Synapse by rooms and media, run Postgres on NVMe, delegate via .well-known, keep 8448 open. Warden 16 GB at $19.00 list, $15.20 annual-eff.
Size Synapse by rooms and media, run Postgres on NVMe, delegate via .well-known, keep 8448 open. Warden 16 GB at $19.00 list, $15.20 annual-eff.
What people actually host
Matrix is a federation protocol: homeservers exchange rooms with each other the way mail servers exchange mail, and every participant keeps a full copy of the rooms their users join. Synapse is the reference homeserver, and clients such as Element web and mobile apps connect to it through the operator’s own domain. Families and small organizations host it so your chat metadata — who talks to whom, when — lands in a database you administer instead of a consumer messenger’s.
The mental model that will save you the most trouble: you are not installing a chat app, you are operating a server in a network of servers, reachable by 8448 federation like any peer. Everything that follows — sizing, DNS, moderation — flows from that one fact. A homeserver that never federates is just a private database with a client API; the moment it joins public rooms, it is a participant with copies, obligations and bandwidth.
What lands on the disk is bigger than newcomers expect: every joined room’s history grows on the operator’s storage, every room’s media — images, files, avatars shared in it — lands in the media store, and state for each room is tracked in the database alongside it. User IDs carry the shape of the choice, too: @you:example.org is a surname, chosen once. That is the price of sovereignty, it is a fair one, and it is priced in RAM and NVMe rather than in a vCPU label on an order form.
The common first mistake is sizing like a website: a hundred users of a static site is nothing, while a dozen federated rooms with active media can outgrow a 2 GB slice in a month. Rooms, not user counts on an order form, are your load unit — and that is where the sizing logic starts.
VPS from $3* (fund $50+), storage 1–5 TB NVMe from $24/mo annual-eff, dedicated with IPMI from $30.80/mo. Crypto invoice, no KYC.
Launch nowSize by rooms and media, not by label
RAM is the axis that matters, and rooms decide it. A household server — a dozen light rooms, mostly private, media occasional — is comfortable on Warden at $19.00 list ($15.20 annual-eff): 6 vCPU, 16 GB DDR5 ECC, 240 GB NVMe. Order Warden as your floor and resize upward from the panel when the media store and database say so — resize is live, no reinstall. Federated rooms with heavy media push past that quickly; bridges to other networks add state machines that never sleep.
The database is the second sizing fact, and it is yours to get right on day one. Synapse’s own documentation recommends PostgreSQL over SQLite for anything beyond testing: SQLite degrades under concurrent federation traffic, and state-group tables on busy rooms turn it into your bottleneck long before the CPU breaks a sweat. Postgres lives on the same box at this scale, on the local NVMe where write bursts are absorbed instead of queued — your media repository and your database both want that disk, and both get it here on every tier.
Growth signals are concrete, and you can watch for them: resident memory climbing toward the plan ceiling, sync requests latency-spiking when a busy room receives a burst, media store outgrowing tens of gigabytes. The ladder handles each in order — Vanguard at $26.50 list ($21.20 annual-eff), Sentinel at $33.50 ($26.80) — and a homeserver that becomes the family institution graduates to metal from Shield at $38.50 ($30.80 annual-eff) with ECC across the board on the dedicated line.
The sizing mistake to avoid is buying vCPUs for RAM problems: federation is not CPU-bound at household scale, and the eight-core plan with tiny memory loses to the six-core plan with more of it — at a lower line on your invoice, which you will notice monthly.
The install, in code
Follow the distribution path in the installation guide rather than improvising from blog posts — the packaged route keeps the systemd unit, the config directory and the upgrade plumbing aligned for you. On Debian-family boxes that is the matrix-synapse-py3 package flow: the installer asks for your server name once, writes the signing key, and leaves the main configuration in /etc/matrix-synapse/homeserver.yaml. Enable it with systemctl enable --now matrix-synapse and the listener comes up on localhost:8008 for a reverse proxy to meet.
Three config edits cover the first hour. Set public_baseurl to the URL clients will actually use, review enable_registration — closed is the sane default for a family server — and create your first user with register_new_matrix_user -a using the shared secret from the config. Keep secrets file-backed rather than inline: your signing key and registration secret belong in the config directory with restrictive permissions, and a stray paste of registration_shared_secret into a chat is the classic self-own of week one.
Upgrades are routine on this stack, which is the point of choosing it: package updates land through the normal system upgrade, the schema migrates itself on restart, and your rollback path is a snapshot before the window — cheap insurance on NVMe. What upgrades do not fix is a misnamed server: the server name is written into every user ID at creation, and changing it later means migrating identities by hand while your contacts watch.
That irreversibility is the mistake to avoid: pick the server name the way you pick a surname, and pick it before your first install rather than after your fifth. Everything else on the box — listeners, keys, database — can be rebuilt in an afternoon; the name cannot.
DNS and federation: the three strings
Federation is DNS correctness before it is compute, and the strings are the operator’s to get right. Three decide whether remote homeservers can reach you: the server name in your user IDs must resolve; the delegation files under the .well-known path must point at where you actually listen; and the federation port must answer TLS with a certificate your domain owns. Get all three right and rooms join themselves; get one wrong and remote servers decline the handshake silently — no error reaches you, your users just cannot join public rooms.
The delegation guide describes the pattern this setup uses: your users get short IDs at example.org while Synapse actually runs on synapse.example.org. Publish .well-known/matrix/client so clients find your homeserver, and .well-known/matrix/server containing {"m.server": "synapse.example.org:443"} so servers do — both as JSON documents, both reachable without redirects. The full server-to-server flow, port 8448 included, is documented in the federation setup.
Certificates bind your story together: whatever hostname answers federation traffic must present a valid cert for the name the delegation advertises, because the remote side validates before speaking. With delegation through 443, the cert lives at your reverse proxy; check the handshake with curl -v https://example.org/.well-known/matrix/server and then from a remote machine to rule out local resolver optimism. Port 8448 is open by policy on every plan here, so nothing on the platform side filters you.
The failure mode worth naming is the split-brain: delegation says one hostname, the reverse proxy routes it to the wrong backend or the cert covers only the apex — and your federation fails while client logins work, which convinces people the problem is elsewhere.
Reverse proxy and the two ports
Synapse speaks plain HTTP on localhost:8008; your public TLS story belongs to a reverse proxy that fronts it. The reverse proxy guide covers both listeners: client traffic on 443 and server-to-server federation traffic, which may arrive on 8448 directly or on 443 when your delegation advertises the masked route — the proxy terminates TLS for both and forwards to the same backend.
Two proxy settings matter disproportionately for the users behind your server. First, upload limits: Matrix media goes up as POST bodies, and default proxy body-size ceilings choke it — raise the client-body limit to match max_upload_size in homeserver.yaml, or your video and document sharing dies with a cryptic 413. Second, timeouts: sync endpoints hold connections open, and aggressive proxy idle timeouts break background clients in ways that look like flaky apps rather than server config. Generous on both, and your room joins stop being mysterious.
Unmetered networking makes the bandwidth side boring for you by design: federation traffic never meters, and the ceiling is port speed rather than a quota, so a busy public room costs your attention, not overage charges. What the proxy cannot fix is a thin pipe in front of a media-heavy room — the media store grows on your NVMe regardless of proxy generosity, which is why disk class came before this section and backups come after it.
The classic proxy mistake is hiding the client API and the federation API behind different names or certs — your clients then work while federation fails, and the split symptom sends you debugging DNS when the proxy config is the whole problem. One pass through the proxy guide with both listeners in mind, and neither failure surface stays open long enough to cost you a user.
Postgres, media and backups
The database decision you made in sizing becomes daily practice here: psycopg2 pointing at a local Postgres, per the Postgres guide, with the cluster on the same NVMe as your media store. The media repository is the silent grower — every image ever posted in a joined room lands there — and it plus the database is the entire irreplaceable state of your server. Everything else can be rebuilt from packages in minutes.
Back up both with one policy you actually follow: nightly dumps of the Postgres cluster, file-level sync of the media store, retention measured in weeks, and a restore test that is really run — an untested backup is a hope with a timestamp, and hope does not restore your rooms. The platform-side pattern for a small homeserver is simple: snapshots on the box, off-box copy to a storage tier from $30/mo for the archive, and the full recovery order is written out in the backup and restore guide. Media housekeeping has native tooling — purge jobs for remote media age out what your users never asked you to store permanently.
Disk headroom is a running number, not a setup decision: the media store grows with every joined room’s life, state tables grow with federation history, and NVMe at 240 GB on Warden buys a household years — a busy community server checks df -h weekly and graduates to the storage line or bigger metal before the disk, not after it fills.
The mistake with the worst ratio of effort to pain is running your database and media on spinning rust or network mounts at household scale — the platform’s local NVMe on every tier exists precisely because federation’s write pattern punishes latency first, and your sync latency shows it within hours.
Location and payment
The flag choice costs you nothing but thought here, because one list price covers all 40 locations with six published premiums: Iceland and Norway at +20%, Switzerland at +35%, Luxembourg, Cyprus and Panama at +15%. For a homeserver the reasoning is short: Switzerland as the process-minded default — the Zurich page carries the site details — Iceland when speech posture is your reason, and Amsterdam when the household’s readers are European and milliseconds matter more than paperwork. The Matrix server solution page collects the same decision in catalog form.
Payment runs on the 19-coin checkout with no identity step: a token or an email plus a 12-character password is your whole account. Annual term first — the 20% discount applies to the USD total before coin conversion — then the rail: USDT when the household budget wants a stable dollar figure, BTC when auditability is fine, XMR when your invoice should say little. One exact transfer, the watcher credits, and your box images about a minute later with root waiting in your panel.
What the platform does not do is equally relevant to you: no managed Synapse, no application-layer backups, no tuning. The contract is the KVM slice and the network beneath it — installs, upgrades, database care and moderation all ride on your root login. That division is why the sizing, Postgres and DNS sections above are operator skills rather than ticket requests.
The location mistake specific to homeservers is over-weighting the flag before the workload exists: your household server that never joins public rooms attracts no process from anywhere, and the premium buys posture the workload may never use — decide with your room list in view, not in the abstract.
Moderation and the public-room limit
Federation is public by default, and you should plan around it: rooms your server joins are visible to the remote servers participating in them, and their membership metadata crosses 8448 with the room. Encrypted rooms keep message payload private, but who is in the room is federation-level fact. No payment method changes that for you — it is the protocol’s design, not a setting someone sold you short on.
The operational consequence is that joining a public room makes your server a carrier for it: remote media from that room lands in your media store, room state lands in your database, and moderation obligations travel with participation. The moderation guide on matrix.org covers the toolkit — room shutdowns, server ACLs, abuse reporting — and the platform-side rule is short: rooms hosted here must satisfy the AUP, the same as any other service on your account. Legal rooms only, at every flag.
Two housekeeping patterns keep a server of yours boring. First, curate joins: a private server that joins a handful of known rooms stays light, while one that auto-joins every invite becomes a storage problem with a chat interface. Second, use the purge tooling — remote-media retention and room-state purges configured in homeserver.yaml — so yesterday’s curiosity does not live on your disk forever. Both patterns cost you minutes and prevent the two most common “why is my disk full” surprises of Matrix ownership.
The mistake to avoid is the reverse reading — assuming encrypted rooms make your server invisible. Payload privacy is real; metadata visibility is structural, and 8448 carries it either way. Users of yours who want payload privacy plus metadata quiet join fewer public rooms, and that choice belongs to the operator, not to the checkout.
The homeserver install, in the order to run it
Run it in this order and each step validates the last. One: pick your server name the way you pick a surname, because it enters every user ID permanently — for this walk-through, example.org. Two: order the box with RAM for the room count, Warden with its 16 GB as the household floor, in the flag whose posture matches your room list; pay the printed amount once on any of the nineteen rails and root lands about a minute later.
Three: DNS — synapse.example.org pointed at the box, the .well-known/matrix/client and .well-known/matrix/server files published at the apex per the delegation guide, both served as JSON over valid TLS. Four: install from the distribution packages, answer the server-name prompt with the surname from step one, and flip your three config edits — public_baseurl, registration closed, secrets file-backed. Five: put Postgres behind psycopg2 before real traffic, on the local NVMe alongside the media store.
Six: the proxy — client traffic terminated at the proxy with federation routed per your delegation choice, upload limits raised to match max_upload_size, generous timeouts on sync. Seven: verify from outside — federation checkers and curl against both delegation files, a test account joining one public room from a remote account as your end-to-end proof. Eight: backups on schedule — nightly Postgres dumps, media sync off-box, one restore actually performed by you. Nine: join rooms deliberately, set retention, and write down the one paragraph of choices this page walked you through.
That is the whole build: a surname, a box, three DNS strings, a database, a proxy, a backup job — in that order, each step proving the one before it for you. Run the sequence twice on different boxes and it drops under an hour; run it once with the checklist above open in a second window and the first install already lands clean.
Do you manage Synapse for me?
No. The platform rents the KVM slice and stays out of the application layer — installs, upgrades, database tuning and moderation all ride on your root login. The network, the port policy and the NVMe underneath are the platform side of the contract.
Dendrite or Conduit instead of Synapse?
Both run fine on the same VPS as lighter alternative homeservers from the Matrix ecosystem. The sizing logic stays identical: RAM by rooms and media, Postgres on local NVMe, delegation files published, and federation ports reachable — only the install commands differ.
How much RAM does a family homeserver need?
A dozen active users in mostly private rooms sit comfortably in Warden's 16 GB at $19.00 list. Federated rooms with heavy media, or bridges to other networks, are what push an install toward Vanguard — rooms and media are the load unit, not user count.
Can I pay the annual term in USDT?
Yes — the 20% annual discount applies to the USD total first, then the invoice converts at the live rate on any of nineteen coins. A dollar-stable quote is exactly the USDT use case, and one exact transfer on TRC-20 or any listed network credits the order.
What ports does federation need?
8448 for server-to-server traffic plus 443 for clients, both open by policy on every plan. With .well-known delegation advertising 443, remote homeservers knock there — federation is DNS correctness before it is bandwidth, and the platform filters neither port.
Primary sources
More ways to pay
Pay with Bitcoin · Pay with Monero · Pay with USDT (TRC-20/ERC-20/SPL) · Pay with XRP · Pay with TRX · Pay with Dogecoin · Pick the jurisdiction first.
Video walkthrough
How to setup a Matrix Homeserver! — Denshi (self-hosting series). The player loads from youtube-nocookie.com on click; watch on YouTube.
Ready to launch?
Build the box — VPS, storage or bare metal — create the password, pay the invoice that follows.