Single-tenant
Run one Yoke runtime with one Postgres database — dev, compile, and colocated production deployment.
Single-tenant deployment runs one logical tenant (YOKE_TENANT_ID=default) against one Postgres database. The intended production shape is your product binary embedding yoke-runtime, not exposing the yoke CLI. See Embed Yoke in your product.
The CLI yoke run / yoke compile (CLI crate) path below is the same kernel without a custom host — useful until your server exists, or as an executor sidecar. Product workspaces use yoke compile --crate and depend on the library.
Recommended production path
Embed the compiled library in your product (intended):
yoke compile ./packages/runtime -o ./crates/yoke --cratelet rt = strum_yoke::start_colocated(database, data_dir, "default", 8090).await?;
// Your axum/actix server is the public API.See Embed Yoke in your product.
Generated CLI (same kernel, no custom main yet):
yoke compile ./my-agents -o dist/my-agents
cd dist/my-agents && cargo build --release
export DATABASE_URL=postgres://...
./target/release/my_agents runSee Compile & deploy for the generated CLI crate and yoke run from a source tree.
Architecture (colocated)
your-product binary
embeds start_colocated / YokeRuntime
→ your public HTTP (users land here)
→ Postgres (stream, queues, instances, conversations)
→ Control plane API :8090 (loopback / private)
→ In-process tenant worker (embedded Deno + internal package)
→ Portal HTTP (executor port — keep private)
→ pg_sqlite BYTEA or S3 actor stateScale-to-zero is off in colocated mode — the worker stays hot. yoke run --package ... is this architecture without your own main.
Dev setup
For local authoring, use yoke dev instead of compile:
docker compose up -d
export DATABASE_URL=postgres://yoke:yoke@localhost:5432/yoke
export YOKE_STORAGE=pg_sqlite
yoke dev ./your-package --database "$DATABASE_URL"Storage choice
Recommended for single-tenant. Actor SQLite serialized as BYTEA in actor_sqlite — one Postgres handles everything. No S3 dependency.
Ingress
Expose portal HTTP behind TLS reverse proxy:
- Webhook routes from
definePortal().routes GET /healthfor load balancer checksGET /metricsfor Prometheus
In colocated mode, portal routes are served by the in-process executor. Control plane conversation API is on port 8090.
User package deployment
The TypeScript package is loaded by your host. How you ship the host:
| Method | Description |
|---|---|
| Your product crates | yoke compile --crate → depend on the library from CLI/server — embed |
| Generated CLI | yoke compile -o dist/app → cargo build --release → ship that binary |
| Dev source tree | yoke dev / yoke run --package ./packages/runtime while authoring |
Package updates require runtime restart to reload definitions (definitions are fixed at boot). Don't expose portal or control-plane ports as the product API.
Instance data
Actor instances and queues persist in Postgres across restarts. No additional backup beyond Postgres (+ S3 if used) required for recovery.
When to move to multi-tenant
Consider multi-tenant when:
- Hosting many isolated customers on shared infra
- Scale-to-zero per customer compute
- Centralized control plane API on port 8090 with Docker sandbox workers
Single-tenant colocated mode remains valid for dedicated customer VMs or internal tools.