Scale
One region is the ceiling.
A one-person instance on a box that costs $56 a month and a replica fleet behind a load balancer run the same Vidra — the same image, one variable apart.
Validated at two api replicas and three workers; designed for more; not yet exercised by production traffic. This page says which is which.
How an instance grows
One box or a fleet. Same image.
Start on one box
The default role runs everything in one core process: it serves viewers and runs all 25 background workers, video encoding included. The published profiles start at $56 a month.
The library grows
Flip canonical storage to S3-compatible object storage with a zero-downtime migration, hash-verified end to end. Uploads already stream straight to the backend — they never touch the server's local disk.
The audience grows
Split roles: api replicas behind a load balancer, worker hosts for encoding. Work rides durable Postgres queues, so adding workers adds throughput without double-processing — a two-replica soak delivered 406 of 406 events with zero duplicates, and the same run with the safeguards taken out produced 423 deliveries and 17 duplicates, which is the control below. Put a CDN, with purge wired in, in front of public media. Encoding scales by adding hosts, not by stacking containers on one box — ffmpeg already uses the cores.
Past that, the roadmap
Multi-CDN steering, studio DRM and multi-region replication are planned, written down with decision records, and not built. The roadmap is public, so you can judge the distance yourself.
The ledger
Shipped, and planned.
The floor below is soak-tested; the modules above it are written down, decision-recorded, and honestly unbuilt.
- Roles and replicas Shipped
- One boot variable splits the same image into api and worker processes. Replicas take leases, elect a leader for sweeps, and drain behind /readyz — soak-tested at two replicas with a deliberate counterfactual.
- Zero-downtime storage migration Shipped
- Local to S3 with hash verification at every step; rollback is one settings change.
- CDN with purge Shipped
- Public media behind a CDN, with cache purge wired into the pipeline rather than left as an exercise.
- One-release rollback, enforced by CI Shipped
- In vidra-core, every migration runs the previous release's own integration suite against the new schema before it merges, and vidra update puts the previous tags back if the deploy's health probes fail.
- Multi-CDN steering Planned
- Content steering across CDNs — a decision record exists; nothing is built.
- Studio DRM Planned
- Production DRM is not built. A test lane proves the seam, and nothing more.
- Multi-region replication Planned
- A single region is the shipped shape; multi-region is on paper.
- Live beyond one host Planned
- Live streaming runs on one host today, and no sentence on this site says otherwise.
Controls
Exactly-once delivery — and the test that proves the test can fail.
A passing test only means something if it was capable of failing. So each of these was run twice: once as it ships, and once with the safeguard taken out on purpose to confirm the harness notices.
- 406 of 406 deliveries, zero duplicates
- Two api replicas against one PostgreSQL, draining 400 outbox events concurrently: 406 deliveries for 406 unique events.Then the lease and
SKIP LOCKEDwere removed, the image rebuilt, and the same run repeated — it produced 423 deliveries with 17 duplicates. The harness caught every one of them. - Two workers never claim the same job
- Queued work is claimed under a lease with
FOR UPDATE SKIP LOCKED, so adding worker hosts adds throughput rather than duplicate work.ThenSKIP LOCKEDwas removed and the claim run against real PostgreSQL — the double claim reproduced in 5 runs out of 5.
The ceiling
The wall, named.
The honest ceiling today: a single-region deployment — several api replicas and a worker fleet on one PostgreSQL, object storage as the canonical store, one CDN for public media, live streaming on one host. Validated at two replicas and three workers; designed for more; not yet exercised by production traffic.
And the first thing that needs rework past it: playback authorisation checks the database per request, which puts PostgreSQL on the byte path. It is in the plan; it is not done. You should know where the wall is before you pay to find it.
The number is the connection budget.
Every process opens its own pool of up to DB_MAX_CONNS connections — 10 by default — and PostgreSQL's max_connections is server-wide. What has to fit is DB_MAX_CONNS × processes, and processes means api replicas plus worker replicas. One all-in-one process wants 10 of a stock server's 100. Three api replicas and three workers want 60, and a managed plan capped at 25 or 40 is past its limit well before that.
It does not degrade on the way there. It is FATAL: sorry, too many clients already on whichever process connects last — which in a rolling deploy is the new one. The deployment that fails is the one you just started, and the instance still serving looks fine. Lower DB_MAX_CONNS per process rather than chasing a max_connections you probably cannot move.