Skip to content

Configuration

The two config layers of an install, every oc-host.jsonc key, the OpenClaw keys that oc-workers manages, the budgets, and what is not configurable yet.

Updated

Settings sit in two layers, both stored in the Control DO (the Durable Object that holds the install’s config and records). An op is one action of the install, such as a wake, a sleep or a restart.

The two layers

Layer Where it lives Edit with Applies
oc-host.jsonc Your project directory. Install settings. The CLI reads it. The Worker keeps its own versioned copy of the tuning keys: the settings document in the Control DO. ochost config set <key> <value>, ochost sleep set, ochost alerts setup. Or your editor, then ochost deploy for the keys marked below. At the Worker’s next op, with no deploy, when set through ochost. See the table below.
OpenClaw config document The Control DO keeps numbered versions. The gateway reads the newest good one at each start. ochost config set <path> <json> At the next wake, or now with --restart.

ochost config pull writes the current version to openclaw.jsonc and sets baseVersion in oc-host.jsonc. openclaw.jsonc is only a working copy: edits to it do not reach the install. config set refuses when baseVersion is not the current version, so run config pull and then set again. --force skips that check.

ochost config list shows the versions, and ochost config get [path] --ver N shows one. A path is dotted, such as agents.defaults.model.primary or bindings[0].agentId. The value is JSON, and a bare word that is not JSON counts as a string. --unset removes a key.

See CLI reference for the flags.

Two ways to change OpenClaw settings

OpenClaw has its own settings pages and openclaw config commands, and oc-workers adds ochost config. Both change the same OpenClaw configuration.

OpenClaw UI and openclaw config ochost config set
Writes to openclaw.json inside the container a new version in the Control DO
Works while asleep no, the container does not exist yes
Survives a crash or a restore only from the last snapshot or archive yes, applied at every boot
Checked before boot no yes, against the OpenClaw schema of the pinned image
History and rollback no yes, ochost config list, --ver N
Applies at once at the next wake, or now with --restart

Edits made inside the container come back to the Control DO as a candidate version within about a minute, so both paths persist. The Control DO keeps the newest valid version.

Use ochost for settings that must hold after a restore or that touch the Worker: channel tokens, webhook URLs, gateway auth, the model provider, capability endpoints, sleep settings. Use the OpenClaw UI and CLI for live tuning while awake: persona, tool policy, memory, plugin settings.

When the install is asleep, only ochost works. ochost config set wakes nothing; the change waits for the next boot.

oc-host.jsonc keys

ochost init writes the file with these defaults and comments. The file is JSONC, and comments stay when the CLI edits it. Never edit .oc-host/wrangler.jsonc, because every ochost run rewrites it.

When it loads the file, the CLI checks every key in the tables: type, floor and cap, and the rules between keys. A key you leave out takes its default. A bad value stops the command and shows the allowed range. upgrade.auto: true stops it too, because automatic upgrades are not built.

The settings document

The tuning keys live in a settings document in the Control DO, with numbered versions like the OpenClaw config.

  • ochost deploy seeds version 1 from oc-host.jsonc. After that the document wins, so a later deploy does not change a value.
  • ochost config set <key> <value> checks the value, writes a new version and updates oc-host.jsonc, with no deploy. The Control DO reads the document on every call. The Runtime DO (the Durable Object that runs the container) and the login store re-read it at the start of each op, with a 10 second cache, so a change applies at the next op.
  • ochost config get <key> shows the live value. ochost config settings lists every key with its live value and whether you set it. --unset puts the default back.
  • Editing oc-host.jsonc by hand changes nothing live. Run ochost settings push, which sends every tuning key of the file as the whole document (keys the file omits go back to their default), with no deploy.
ochost config set sleep.idleMinutes 10
ochost config set archive.everyHours 3
ochost config settings

An op in flight keeps the values it started with. A changed sleep.idleMinutes applies at the next sleep decision. The adaptive idle time (it doubles after a quick re-wake) was set at the last wake, so it catches up one wake later.

Install keys

Key Default Allowed values What it changes Applies
baseVersion 0 Integer The OpenClaw config version this copy is based on. The CLI sets it. Do not edit. Local check only
name From init a-z, 0-9, -; starts with a letter or digit; up to 63 chars Worker name. The URL is https://<name>.<subdomain>.workers.dev. Set at init. A new name is a new Worker.
inst 6 random hex chars 6 hex chars, or a-z, 0-9, - up to 31 chars Install id. Names the Durable Objects and the R2 paths. Set at init. Do not change on a live install.
accountId From init Cloudflare account id The account that holds the install. Set at init
bucket oc-host-<inst> (key absent) 3-63 chars of a-z, 0-9, - The R2 bucket. Set at init
instance "2/6/20" "vcpu/GiB/GB" or {vcpu, memoryMib, diskMb}. vCPU 1-4, at least 3 GiB per vCPU, at most 12 GiB, at most 20 GB. Floor 2/6/16. Container size. ochost deploy
timezone Time zone of the machine that ran init IANA name, for example Europe/Berlin Time zone for sleep.proactive hours and the maintenance hour. ochost config set timezone <name>
sandbox "off" on, off Run agent exec and file tools in a separate sandbox container. ochost sandbox on|off sets it. The Setup tab of the owner console has the same control: it saves the choice in the Control DO, and that choice then wins over this key. See Capabilities. Not in the settings document. ochost deploy, then ochost restart
telegram.wakeProgress "delete" delete, ready, off The “Waking up” message in Telegram while the install wakes. delete removes it at the reply. ready edits it to “Ready in N s”. off sends none. Not in the settings document. ochost deploy
upgrade.track "extended-stable" A release track name The track that ochost upgrade check and upgrade run use when you name none. Read by the CLI each run
upgrade.auto false false Reserved for automatic upgrades. Not built: true is refused. CLI check
alerts.channel "none" ntfy, webhook, none Records the alert channel. ochost alerts setup sets it and the Worker secret. Do not edit by hand. A URL saved in the Setup tab of the owner console is used before the Worker secret; ochost alerts setup still works when no URL is saved there. At alerts setup
llm.gateway "default" AI Gateway id, or none The gateway that the Worker’s Workers AI binding routes every model call and web search through. Cloudflare creates default on its first request. none: no gateway, so no logs and no spend limit (web search still uses default). ochost deploy
llm.primary @cf/deepseek-ai/deepseek-v4.1-flash-1017 @cf/<org>/<name> or <provider>/<model> A local copy of the primary model. ochost model set and config set agents.defaults.model.primary keep it in step. Local copy. The model itself changes with the OpenClaw document.
llm.fallbacks [] List of model ids A local copy of the fallbacks. ochost model set --fallback writes it. Local copy
llm.spendLimitUsd null Number above 0, or null A monthly spend cap for the AI Gateway. The CLI cannot set it: the gateway API needs a token that can edit the gateway, and the install holds none. ochost ai-gateway setup prints the dashboard step: AI, AI Gateway, your gateway, Settings, Spend limits, add a cost rule. Dashboard step

The old llm.auth key is gone, since it had only one value. A file that still has it works.

Sleep keys

Change them with ochost config set <key> <value> or ochost sleep set auto|off --idle-minutes N --proactive <v>. Both apply at the next op.

Key Default Allowed values What it changes
sleep.mode "auto" auto, off auto: the container sleeps when idle. off: always on. A socket channel forces always-on in auto.
sleep.idleMinutes 5 1-60 Idle time before sleep. It doubles after a quick re-wake, up to idle.doubleCapMinutes.
sleep.minAwakeMinutes 2 1-60 Stay awake at least this long after a boot.
sleep.minSleepMinutes 10 1-720 No sleep when the next known wake is closer than this.
sleep.uiIdleMinutes 15 1-240 A UI socket closes after this long without input.
sleep.uiMaxMinutes 60 5-1440, at least uiIdleMinutes A UI socket closes after this long without a chat message or a write (a change made from the UI).
sleep.maxAwakeHours 16 6-72 Uptime limit that the Control DO puts in each boot plan. Past it, the install restarts when idle. The old key maintenance.maxUptimeHours still counts when this one is absent.
sleep.costGuard "auto" auto, off auto: the guard holds the install awake when sleeping would cost more than staying on. off: it never holds. Status still shows the numbers.
sleep.snapshotCostUsd 0.0045 0-1 (USD) Cost of one sleep snapshot, used by the cost guard and the cost figures. A guess until you see an invoice.
sleep.proactive "2h@08-22" off, openclaw, 30m, 1h, 2h, 3h, 4h, 6h, 12h with optional @HH-HH, or a 5-field cron How often the install wakes for the proactive check, in the timezone. openclaw keeps the OpenClaw heartbeat cadence.
maintenance.hour 4 0-23 Hour of the daily maintenance wake.
idle.doubleCapMinutes 60 5-1440, at least sleep.idleMinutes Top of the adaptive idle time.
cron.tailSeconds 120 10-3600 Idle time after a wake for a cron job, instead of sleep.idleMinutes.
cron.leadSeconds 120 10-600 How long before a cron job the install wakes. After 20 wakes the Worker adapts it, between 60 and 300 s.
inbox.holdHours 20 1-168, below deadHours A held update waits this long for a wake.
inbox.deadHours 23 2-336 A held update goes dead after this long. It is kept one hour more.

Snapshot, archive and chain keys

Key Default Allowed values What it changes
checkpoint.intervalMinutes 60 10-1440 While awake, a dirty-only checkpoint snapshot when the awake period or the last checkpoint is this old.
checkpoint.maxPerDay 30 0-96 Checkpoints per UTC day. Then they stop.
snapshots.maxPerDay 40 10-200, at least checkpoint.maxPerDay + 2 Planned, checkpoint and maintenance snapshots per UTC day before the alert snapshot-budget.
archive.everyHours 6 1-168 An archive is due when the newest is older than this.
archive.minGapMinutes 15 5-1440 Minimum time between two archives when the state changed.
archive.maxPerDay 24 1-96 Archives per UTC day.
archive.drillEveryDays 30 1-365 Restore drill cadence.
chain.rebaseAfterHours 24 1-720 A snapshot chain whose root is older than this is rebased at the next wake.
chain.rebaseAfterSnapshots 40 5-500 …or one with more snapshots than this.
chain.tagWarn 100 10-2000 ochost status warns above this many registry tags (two per snapshot).

Alert, storage and cost keys

Key Default Allowed values What it changes
alerts.dedupeMinutes 60 1-1440 One send per alert class in this time.
alerts.minSeverity "high" info, warn, high The alert channel gets alerts at or above this level. ochost alerts list shows all.
gens.churnPerDay 10 1-200 The alert gen-churn fires above this many unplanned gens (database replica generations; each boot starts one) in a UTC day.
storage.pruneAtMb 1024 64-8192 Control DO storage size where hard pruning starts and the alert ctl-storage-high fires.
storage.refuseAtMb 2048 128-9000, above pruneAtMb The Control DO refuses growth writes (credentials, config, plugins) above this.
cost.releaseBelowPct 80 10-99 Once the cost guard holds, it lets go when 24 h spend is under this share of the always-on cost.

Login keys

Key Default Allowed values What it changes
login.sessionDays 30 1-365 Lifetime of an owner session. The cookie Max-Age follows. A session made earlier keeps its end date.
login.maxSessions 20 1-200 At most this many sessions. The oldest ends first.
login.codeMinutes 5 1-60 Lifetime of the one-time code from ochost open.
login.rateLimits.windowMinutes 10 1-1440 Window of the limits below.
login.rateLimits.ipFail 5 1-1000 Failed logins per IP per window. Then HTTP 429. ochost open still works.
login.rateLimits.ipTry 20 1-10000 Login tries per IP per window.
login.rateLimits.allFail 30 1-10000 Failed logins from all IPs per window.
login.rateLimits.maxCodes 10 1-100 Open one-time codes.

The settings that matter most are sleep.mode, sleep.idleMinutes and sleep.proactive.

OpenClaw keys that oc-workers manages

Do not set these by hand; use the ochost command named in the table. oc-workers overwrites each of these keys at every boot, checks it, or builds on it.

Overwritten at every boot

The boot step takes the selected config version and sets these keys over it, with values from the Control DO. Your own value is dropped.

Key Value Why
gateway.bind lan The Worker reaches the gateway on the container network.
gateway.port 18789 Fixed port.
gateway.auth.mode trusted-proxy The Worker authenticates you with the owner cookie. The gateway trusts the Worker.
gateway.auth.password, gateway.auth.token Removed A secret never goes into the file.
gateway.trustedProxies 10.1.0.0/32 The Worker address.
gateway.auth.trustedProxy.* User header x-ochost-user; required headers x-forwarded-proto, x-forwarded-host; allowed user owner; loopback off; device auto-approve on Same trust rule.
gateway.auth.identityScopes The owner gets operator.admin One owner.
gateway.publicOrigin The Worker URL Links and webhook checks.

Open the UI with ochost open. A change to gateway.auth, gateway.bind, gateway.port, gateway.trustedProxies, gateway.controlUi, browser.executablePath or tools.exec raises the alert config-sensitive.

A few keys are set for one boot only, and the stored version does not change. A restore from an archive or to a point in time sets cron.enabled to false for that boot. A boot that holds channels off sets channels.<name>.enabled to false for that boot. A plugin that is missing from the image is set enabled: false.

Written by ochost commands

oc-workers writes these keys into the document and checks some of them.

Keys Set by Rule
channels.telegram (botToken, webhookUrl, webhookSecret, webhookPath, dmPolicy) and the Telegram entry in bindings ochost channels add telegram The Control DO refuses a webhookUrl that is not the managed Worker route. Refused versions give HTTP 403 and the alert config-rejected. Secrets are ${OC_...} references.
agents.defaults.utilityModel, agents.defaults.compaction.model, agents.defaults.compaction.thinkingLevel, agents.defaults.thinkingDefault, agents.defaults.models["cfgw/<model>"].params.thinking, and the reasoning, input and compat fields of each models.providers.cfgw.models entry ochost config render, ochost model set --role The render sets a key only when it is absent, except the cfgw entries, which it rewrites. The main model runs at thinking low through agents.defaults.thinkingDefault (the Control UI’s Thinking row). The utility and compaction models get a per-model params.thinking of off; the render removes a per-model low left on the main model by an older render. The default utility model is @cf/google/gemma-4-26b-a4b-it.
models.providers.cfgw, agents.defaults.model.primary as cfgw/<model> ochost init, ochost model set, ochost ai-gateway setup cfgw points at the capability gate (http://15.0.0.3/ai/v1) with a dummy key. The Worker runs the call on its Workers AI binding. No token.
browser, tools.web.fetch, tools.web.search, tools.media, plugins.load.paths, plugins.entries.cf-capabilities, memory.search, tts, models.providers.openai, agents.defaults.mediaModels, mcp.servers.cloudflare-docs ochost init (version 1) Every one points at the capability gate at 15.0.0.3. The container holds no Cloudflare credential. A key that points elsewhere skips the gate and its budgets. See Capabilities.
channels.slack, channels.discord, channels.sms and their bindings entries ochost channels add slack|discord|twilio HTTP mode only, never socket. The webhook path is the adapter route. Secrets are ${OC_...} references.
agents.defaults.sandbox.*, plugins.entries.ochost-sandbox The boot step, when sandbox is on Set at every boot, like the keys above. Backend ochost at the sandbox gate 15.0.0.4.
agents.defaults.heartbeat.every 0m when you give no value A new owner version with no heartbeat.every gets 0m (off), so the OpenClaw heartbeat does not wake a sleeping install. Set your own value to keep it. sleep.proactive: "openclaw" also keeps the OpenClaw cadence.

A key that holds a secret takes a ${NAME} reference. Set the value with ochost secrets set NAME, and the gateway sees it as env NAME. Names that have their own command (TELEGRAM_BOT_TOKEN, TELEGRAM_WEBHOOK_SECRET, the Slack, Discord and Twilio secrets, CF_AI_TOKEN, GATEWAY_TOKEN) are refused, and the error names the command to use.

OpenClaw keys you change

The rest of the document is yours, and the Control DO keeps up to 50 versions of it.

Goal Command
Change the model ochost model set <id> [--fallback <id>]. This also edits the cfgw model list. Or ochost config set agents.defaults.model.primary '"cfgw/@cf/<org>/<name>"'. See Models.
Add a channel ochost channels add telegram|slack|discord|twilio. Other channels: ochost config set channels.<name> '{...}'. A socket channel keeps the install awake. See Channels.
Change the tool policy ochost config set tools.deny '["exec"]'. Keys: tools.allow, tools.deny, tools.profile.
Change the agent defaults ochost config set agents.defaults.workspace '"..."', and other agents.defaults.* keys.
Remove a key ochost config set <path> --unset
Apply now Add --restart. Without it the change applies at the next wake.

The memory search keys (memory.search.*) point at the capability gate, so keep them. Other memory keys follow the OpenClaw reference.

For every other section, see the OpenClaw configuration reference: channels, agents, session, messages, tools, models, mcp, skills, plugins, browser, hooks, cron, logging. Ignore the gateway section, because oc-workers manages it. openclaw config schema prints the live schema.

Budgets

The capability gate and the sandbox gate count what the agent spends each UTC day, and the Control DO holds the counters. An alert fires at 80 percent. At 100 percent the gate answers HTTP 429 with retry-after until the next UTC midnight or until you raise the limit. The verbs and defaults are on Capabilities.

ochost caps                      # used, limit and percent per verb
ochost caps set browser 7200     # change one limit

Not configurable yet

What Current value
Maintenance snapshots per day 2
OpenClaw config versions kept 50 (10 once hard pruning starts at storage.pruneAtMb)
Cost guard cycle One wake cycle counts as 37 s awake and 28 s CPU
Abort hold No sleep for 1 h after 3 aborts
Socket max age 24 h
Maintenance cadence Daily, only if no wake in 24 h

Next

Go to Cost.

Type to search…

↑↓ navigate↵ selectEsc close