Deploying the host
Run the host in production with a persistent store, secrets from the environment and safe restarts.
A production host is the same module you ran with threads dev, started with threads start. There is no separate server to operate: the host is one process, and all of its state is in the store.
Checklist
Keep the store on a persistent disk
sqlite(".threads") is a directory holding a SQLite database and stored artifacts. Everything lives there: every thread's log, the channel inbox, pending replies, schedule claims. Put it on a volume that survives redeploys, and back it up like any database.
Provide secrets as environment variables
Every secret("NAME") reads NAME from the host process environment: model keys (ANTHROPIC_API_KEY, OPENAI_API_KEY), sandbox keys (E2B_API_KEY, DAYTONA_API_KEY) and channel secrets. A missing channel secret stops startup with missing_secret.
Protect the HTTP API
Pass authenticate to host(). Without it the /v1 API answers 401 to everyone, which is safe but not useful. Channel webhooks are verified with each provider's signing secret and don't need it. See HTTP API.
Start the host
threads startSee CLI for the module each language loads and the port it listens on. Put it behind your usual HTTPS reverse proxy or load balancer and point each channel's webhook at https://<your-domain>/channels/<name>/events.
Restarts and crashes
You can stop or restart the host at any time, including mid-run:
- Channel messages are stored before the provider gets its
200, so nothing that was acknowledged is lost. - On the next start the host picks up waiting messages, resumes runs and sends replies that are still owed.
- An action that may already have happened is never blindly retried. It is confirmed with the provider or held for a person. See Durability & crash safety.
One store, one machine
The store is SQLite, so run the host on one machine with the store on local disk. Each thread is owned by one process at a time: if a second process tries to run the same thread, it is refused rather than allowed to write alongside the first. Two hosts pointed at the same store never double-fire a schedule.
Housekeeping
Two CLI commands keep a long-running store tidy. Neither runs automatically.
| Command | When |
|---|---|
threads gc [module] | Periodically, for example from cron. Releases sandboxes that were left running and removes stored artifacts nothing refers to anymore. |
threads delete <thread_id> / threads delete --tenant <id> | For retention or a customer's deletion request. |
Containers and platforms
Any platform that runs a long-lived process with a persistent volume works: a VM, a container with a mounted volume, or a platform service with a disk. In Python you can also serve app.asgi with your own ASGI server; in TypeScript, mount app.fetch in your existing server (see Host server). Serverless functions without a persistent disk are not a good fit, because the store must outlive each request.