Skip to content
Deploy

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 idLocationCheapest typePrice/monthFor
euFalkenstein (fsn1)cx23 2c/4GB$5.99Europe only
sgSingapore (sin)cpx12 1c/2GB$17.99SE Asia, Australia, NE Asia
us-eastAshburn (ash)cpx11 2c/2GB$20.49North 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

Up nextEnvironment