Run your first job
Three terminals on one Mac. Once this works, adding a second machine is one flag.
1 — Control plane
macbatch control startServes on http://127.0.0.1:8000. The queue lives in ~/.macbatch/control-plane/batch.db, created on first start.
If the port is busy with a healthy macbatch control plane, the command tells you so and exits rather than starting a second one. Use --port 8001 if you genuinely want two.
2 — Worker
macbatch setup --control-url http://127.0.0.1:8000
macbatch serveYou should see a ● live line with your worker id, then heartbeats. Confirm the control plane agrees:
macbatch control workers3 — Submit a benchmark job
macbatch bench embed --n 500 --mode soloThis generates 500 synthetic sentences, submits them as one job, polls until every shard is done, and writes artifacts:
benchmarks/runs/<run_id>/summary.json full stats
benchmarks/runs/<run_id>/events.jsonl timeline
benchmarks/runs/embed_compare.jsonl one line per run, for comparingWARNING
bench refuses to start if no worker is alive. That is intentional — a benchmark against an empty pool would just measure the polling loop.
Submitting your own work
bench is a convenience wrapper. The real interface is HTTP:
curl -X POST http://127.0.0.1:8000/v1/jobs \
-H 'content-type: application/json' \
-d '{
"type": "embed",
"model": "nomic-embed-text",
"shard_size": 32,
"items": [
{"id": "doc-1", "text": "first chunk of text"},
{"id": "doc-2", "text": "second chunk of text"}
]
}'You get back a job_id. Poll it, then collect results:
curl http://127.0.0.1:8000/v1/jobs/<job_id>
curl http://127.0.0.1:8000/v1/jobs/<job_id>/resultsRead the items array from the results response — it is the flattened, per-item view. The results array is per-shard and mostly useful for debugging which worker did what.
Full endpoint list: Control plane API.
Adding a second Mac
Restart the control plane with a tunnel:
macbatch control start --tunnelIt prints a public https://….trycloudflare.com URL. On the other Mac:
npm i -g macbatch
macbatch setup --control-url https://….trycloudflare.com
macbatch serveThen re-run the benchmark with the multi label:
macbatch bench embed --n 500 --mode multi --shard-size 32Keep local workers on localhost
The Mac hosting the control plane should point its own worker at http://127.0.0.1:8000, not the tunnel URL. Routing local traffic out through Cloudflare and back adds latency for no reason.
Stopping
macbatch sleep # stop serve, clear temp cache, keep model weights
macbatch clean # clear caches onlysleep sends SIGTERM to the recorded pid and marks the worker offline on the control plane. If serve is running in the foreground, Ctrl+C does the same thing.