Architecture Overview
BitBonsai uses a shared-database, direct-poll model for distributed encoding. Every node — main and child — connects directly to the same PostgreSQL database and polls the job queue independently.- No central job dispatcher — nodes self-assign via optimistic locking
- No message queue (no Redis, no RabbitMQ) — PostgreSQL is the queue
- Child nodes need direct database access (
DATABASE_URL) to poll jobs MAIN_NODE_URLis used only for node registration and health reporting
Node Registration
When a child node starts withNODE_MODE=LINKED, it:
- Connects to PostgreSQL via
DATABASE_URL - POSTs its registration to
MAIN_NODE_URL/nodes/registerwith:- Hostname / IP address
CONCURRENT_JOBScapacity- Hardware info (CPU cores, GPU presence)
- Main node inserts a row in the
nodestable - Child node appears in Settings → Nodes in the web UI
OFFLINE and its active jobs are reset to QUEUED.
Job Distribution Mechanics
There is no central scheduler. Each node runs its own polling loop:FOR UPDATE SKIP LOCKED clause is the key — PostgreSQL’s row-level locking prevents two nodes from claiming the same job. No distributed lock manager needed.
Load balancing result:
| Scenario | Outcome |
|---|---|
| All nodes equally loaded | Jobs distributed round-robin by creation time |
| One node faster than others | Faster node picks up more jobs (polls more aggressively) |
| Node offline | Its QUEUED jobs are immediately visible to other nodes |
| Node crashes mid-encode | Orphan recovery resets its ENCODING jobs to QUEUED on next startup |
NFS: Why It’s Required
All nodes must mount the same NFS share at the same path (/media inside the container). Here’s why:
- Job assignment stores the file path — e.g.,
/media/Movies/Film.mkv - FFmpeg runs on the assigned node — it opens that exact path
- Output is written back to the same path (encoded file replaces original)
ENOENT: no such file even if the file exists on the main node.
TRANSFERRING Status
When a job entersTRANSFERRING, the assigned node is verifying that the source file is accessible on its local NFS mount before starting FFmpeg. This is a brief file-existence check (not a copy operation).
Flow:
TRANSFERRING for more than 30 seconds, the NFS mount on that node is degraded. Check:
Capacity Planning
Use this formula to determine how many nodes you need:| Library Size | Recommended Setup |
|---|---|
| < 500 GB | Single node (main only) |
| 500 GB – 5 TB | 1 main + 1–2 child nodes |
| 5–20 TB | 1 main + 3–5 child nodes (GPU recommended) |
| > 20 TB | 1 main + 6+ child nodes, 10GbE NFS |
Related
- Multi-Node Setup — Step-by-step configuration
- GPU Acceleration — Hardware encoding per node
- Monitoring — Track distributed encoding performance
- Understanding Jobs — Job lifecycle and status reference