Deploying on hosted workers
The question this page answers: my pipeline runs on a hosted platform. How do I make sure every process exports to the right org, and check it after a deploy?
Locally, one .env file usually feeds everything. On a hosted platform each service, worker and cron job has its own environment, and the SDK reads only the environment of the process it runs in. Most "it works on my laptop but the console is empty" reports come down to one of four things on this page: a process without the key, a stale override, a shell that predates the deploy, or a key from another org.
1. Set the key on every process that creates a rig
MODELRIG_API_KEY switches export on per process. A process without it still runs every call, buffers rows to its own local SQLite file and ships nothing, without an error. If the web service has the key and the background worker doesn't, every run the worker produces is lost to the console.
List every service, worker and cron that calls createRig, and set MODELRIG_API_KEY on each one. The ingest host defaults to https://api.modelrig.ai; set MODELRIG_INGEST_URL only if you were given a different one.
2. Know which value wins (Render)
Render lets you set a variable in an environment group shared by several services, and directly on a service. When both define MODELRIG_API_KEY, the service's own value wins. So when you rotate the key in the group, a service that also has its own copy keeps using the old value.
When you change the key, check both places for every service: the environment group, and the service's own Environment tab. Delete the service-level copy unless you mean it to differ.
3. A change needs a finished redeploy and a new shell
- A process reads its environment once, when it starts. A changed variable reaches your code only after the service has redeployed and the deploy has finished. On a worker that runs a long batch, that means the next batch.
- A shell attached before the deploy still has the old environment, and it may be attached to the old instance. Open a new shell after the deploy finishes; on Render the hostname suffix in the shell prompt changes. Run your checks there, not in the old shell.
After you change the key on a hosted worker. A hosted process reads the environment it was started with. After you set or change MODELRIG_API_KEY, wait for the redeploy to finish, then open a new shell: a shell attached before the deploy still has the old environment. Confirm from inside it that the key resolves to the org you expect: --expect-org takes the org's slug, the part in parentheses in doctor's output.
npx modelrig doctor --expect-org your-org # exits non-zero if the key belongs to another org
Pin the org a deployment must export to. --expect-org and expectOrg take the org's slug, not its display name. modelrig doctor prints both, as → org «Your Org» (your-org) ✓: the slug is the part in parentheses. In the console, hover the org badge in the header to see it. With --expect-org <slug>, doctor exits non-zero when the key belongs to another org, so a deploy check fails loudly instead of exporting somewhere else.
// The same check in code: the exporter asks whoami on its first flush and logs
// ORG MISMATCH on every flush while the key belongs to another org.
const rig = createRig({ ...loadConfigFromEnv(), expectOrg: "your-org" });
4. Rotate a key without a gap
1. Mint a new key in the same organization (console → API keys). 2. Set it as MODELRIG_API_KEY everywhere the old one is set (step 2 above). 3. Redeploy every service that uses it, and wait for each deploy to finish. 4. Verify from a new shell on each service: npx modelrig doctor --expect-org <slug>. 5. Revoke the old key. Do this last: a process still holding it starts getting 401 on its next export, logs AUTH FAILED, and its telemetry is dropped (not queued) until it has a working key.
5. Verify after every deploy
Two checks, in order:
1. Org check: npx modelrig doctor --expect-org <slug> from a new shell on the service. It exits non-zero if the key is missing, rejected or from another org, so it works as a post-deploy step in CI. 2. One real run: trigger one pipeline execution and open /runs in the console, with the org badge showing the same org. The run should be there with its steps. If it isn't, work through Troubleshooting an empty console.
In your app, createRig({ ...loadConfigFromEnv(), expectOrg: "<slug>" }) makes the SDK log the org it exports to on the first flush ([modelrig] exporting to org «Name» (slug) as key «name» rig_sk_…last4), and ORG MISMATCH on every flush if the key resolves elsewhere. Search your service logs for [modelrig]. A rejected key logs AUTH FAILED once per failure streak. See Orgs and keys.
Runtime notes by platform
The SDK needs a Node runtime (version 20 or later) and a writable disk for its local buffer. The quickstart's runtime requirements are the full list.
- Render, Fly.io, Railway and similar. Long-lived processes: nothing extra beyond steps 1 to 5. Call
await rig.close()on shutdown so the last rows flush. On Fly,fly secrets set MODELRIG_API_KEY=…restarts the machines; open a newfly ssh consolesession to check. - Vercel functions and other serverless runtimes. Set
MODELRIG_TELEMETRY_DB=/tmp/modelrig/telemetry.dbandawait rig.close()once per invocation before you return, or the last rows of each invocation are lost. A changed environment variable reaches new deployments only: redeploy after you change it. Edge runtimes are unsupported. - Docker. Pass the key at run time (
docker run -e MODELRIG_API_KEY …, or your orchestrator's secret), never baked into the image. Give the container a writable path for the telemetry file.docker execinto the running container to rundoctor, since a newdocker runstarts a different container with whatever environment you give it.
Related: Orgs and keys · Troubleshooting · Quickstart