The media plane
A rented box with a public address and an open UDP range, at about $7 a month.
The switchboard: a rented computer with a public address, running the call server. Everything else in this kit deploys to accounts that already exist; this one is a box.
About $7 a month per region. Budget thirty minutes the first time.
The full runbook is infra/DEPLOY.md in the repository, and it was run against
live infrastructure before it was written down. What follows is what you need to
decide before opening it.
One region or several#
Each region is a fully independent box — its own key pair, its own firewall, no shared state with any other. There is no cluster to join and no coordination step: standing up a second region is this runbook, run again, in a different location.
Two regions is two independent $7/month subscriptions, not one bigger purchase. Cancel either at any time without touching the other.
Pick by where the callers are#
Not where you are, and not where the models are. The VM's only job is moving packets, so proximity to the caller is what the money buys.
| Region id | Location | Cheapest type | Price/month | For |
|---|---|---|---|---|
eu | Falkenstein (fsn1) | cx23 2c/4GB | $5.99 | Europe only |
sg | Singapore (sin) | cpx12 1c/2GB | $17.99 | SE Asia, Australia, NE Asia |
us-east | Ashburn (ash) | cpx11 2c/2GB | $20.49 | North America |
Server types are location-locked, and the provider's API misreports it.
cx23 exists only in the EU. cpx11 publishes a Singapore price for a type that
is not actually available there. Use the combinations above rather than the ones
the API offers you.
What the box needs open#
An SFU forwards media over UDP. The firewall has to allow:
- UDP 50000–60000 — the media itself
- TCP 7880/7881 — signalling and the HTTP API
- TCP 443 — the WebSocket endpoint behind TLS
This is why the media plane is a VM and not a container on a platform-as-a- service: an open UDP range is not something those platforms offer, and it is not optional for an SFU.
It is also why the worker runs here and posts its records over HTTP rather than connecting to the database — this is the most exposed machine in the system, and nothing on it should hold a database credential. Transcripts
Afterwards#
The box gives you three values. They are the input to everything else:
LIVEKIT_URL=wss://<your host>
LIVEKIT_API_KEY=...
LIVEKIT_API_SECRET=...
Point the CLI at them and probe it before going further — one command, and it distinguishes "DNS resolves" from "the process is up":
npx udk health
For more than one region, put them in REGIONS_JSON by key name, never by
value. Regions