Yoke.sh
Deployment

Multi-tenant

Many isolated tenant runtimes with scale-to-zero compute and always-on Postgres.

Yoke supports multi-tenant hosted deployments where many customers share one Postgres cluster (tenant_id on every row) while compute scales to zero per idle tenant.

"Serverless" here means compute starts and stops on demand — Postgres stays always on.

Architecture

INGRESS (per tenant)
  append API · portal HTTP · webhooks
              │
              ▼
    Always-on Postgres
    stream · queues · leases
              │
              ▼
    TenantSchedulerService
    (serverful reconcile loop)
              │
              ▼
    SandboxProvider (Docker, Modal, Fly, …)
              │
              ▼
    yoke-executor microVM per hot tenant
    Rust kernel + libdeno + user package
              │
              ▼
    S3 (actor SQLite per tenant prefix)

Separation of concerns

ComponentScales to zero?Role
PostgresNoDurable stream, queues, registry, leases
Control planeNoHTTP API port 8090, tenant ingress
SchedulerNo (serverful)Start/stop decisions on activity
Sandbox poolYes0..N executor containers/VMs
Tenant runtimeYesKernel + Deno for one tenant

Tenant lifecycle

COLD ──(activity)──► STARTING ──(ready)──► HOT ──(idle)──► STOPPING ──► COLD
  • COLD: No executor. State in Postgres + S3 only.
  • STARTING: Scheduler acquired lease; sandbox provisioning.
  • HOT: Fan-out, drain, portal HTTP for tenant.
  • STOPPING: Flush S3, graceful stop, release lease.

Stop rule: keep tenant container running while pending_events > 0 OR active_dispatch > 0.

Leases

tenant_runtimes table prevents duplicate executors:

  • Scheduler CAS on lease_holder + lease_expires_at
  • Executor heartbeats every 15s via YOKE_LEASE_HOLDER
  • Expired leases → reconciler stops orphan VMs

Activity signals

KindSource
StreamAppendAfter durable stream write
PortalHttpBefore portal route dispatch
QueueDepthReconciler sees pending rows
CronExternal tick for portal start()
ReconcilePeriodic idle sweep

Sandbox provider trait

MethodPurpose
provision(spec)Create executor VM/container
destroy(handle)Tear down
status(handle)Running / failed / gone

DockerSandbox included for local development.

Executor environment

YOKE_TENANT_ID=customer-abc
DATABASE_URL=postgres://...   # shared; queries scoped by tenant_id
YOKE_PACKAGE_REF=s3://...
YOKE_STORAGE=s3
YOKE_S3_PREFIX=customer-abc

Control plane API

yoke control-plane --database "$DATABASE_URL" --port 8090

Headless chat + schedules + tenant ingress proxy. See HTTP API.

On this page