Self-hosting a control plane
The control plane is a single FastAPI process backed by SQLite. There is no broker, no Redis, and no background scheduler thread.
Local only
macbatch control start --port 8000Binds 127.0.0.1. Only workers on the same machine can reach it.
LAN
macbatch control start --publicBinds 0.0.0.0. Other machines on your network can reach it at http://<your-lan-ip>:8000.
Internet, via tunnel
macbatch control start --tunnelStarts the server, then a Cloudflare quick tunnel, and prints the public URL. Requires cloudflared on PATH. The public URL is written to public_url in your config while the tunnel is alive and cleared when it exits.
Quick tunnels are ephemeral — the hostname changes on every restart, and every worker must be re-pointed. Fine for a benchmark session with friends, not for anything standing.
If a healthy control plane is already listening on the port, --tunnel attaches to it rather than starting a second server.
Internet, on a VPS
For something durable, run uvicorn directly behind a real hostname:
pip install macbatch
python -m uvicorn macbatch.control.app:app --host 0.0.0.0 --port 8000Put TLS in front of it. Workers only need the base URL.
No authentication
Every endpoint is unauthenticated in the current release, including POST /v1/jobs and POST /v1/admin/reclaim. A token field exists in the config but is not enforced anywhere.
Anyone who learns your URL can submit jobs, read every result, and reclaim leases. Do not expose a control plane holding real data without putting your own authentication layer in front of it — a reverse proxy with basic auth or mTLS is the minimum.
Storage
Everything lives in one SQLite file:
~/.macbatch/control-plane/batch.dbWAL mode, connection per request, no pooling. Four tables: jobs, tasks, workers, task_events.
There is no migration system. Schema setup is CREATE TABLE IF NOT EXISTS at startup, so an existing database is never altered when you upgrade. If a release changes the schema, move the old file aside.
Backing up is copying the file. Resetting is deleting it.
Operations
macbatch control workers # who is alive, tasks done, tasks failed
macbatch control url # local and public URLs currently configured
curl <url>/health # liveness
curl -X POST <url>/v1/admin/reclaim # force-expire stale leases nowA worker counts as alive if it heartbeated within 60 seconds and did not report itself offline.
Capacity
Expired leases are reclaimed opportunistically inside request handlers — on lease, heartbeat, job read, and worker list. A completely idle control plane with no requests reclaims nothing, which is harmless: the reclaim happens the moment the next worker polls.
The practical ceiling is SQLite write throughput. Increase shard_size before adding control-plane capacity; it reduces both task-table rows and HTTP requests per item.