The problem · Why OpenClaw is expensive out of the box
OpenClaw is a powerful platform for AI assistants. But out of the box it isn't optimised for cost:
One model for everything. By default OpenClaw uses one model (usually Sonnet) for the main tasks, heartbeats and subagents. Sonnet costs $3 per million input tokens.
A bloated bootstrap. Every message starts by loading all the workspace files. A typical workspace is 45+ KB (~15,000 tokens). That's $0.045 for the bootstrap alone.
No limit on context. If the workspace has grown to 100 KB, OpenClaw will load all 100 KB into every message.
Heartbeats on an expensive model. Every 3-4 hours. Each heartbeat = bootstrap + check + reply. On Sonnet that's $0.10-0.20, or $2-5 a day.
The result: $100-300/month, of which 60-70% is overhead. This guide gives 6 steps that will cut costs by 80%.
Step 1 · Multi-model routing 5 min ~40-50%
The biggest effect. The expensive model for complex tasks, the cheap one for routine.
Open ~/.openclaw/openclaw.json and set up the agents.defaults section:
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-5-20250929",
"fallbacks": ["anthropic/claude-haiku-4-5-20251001"]
},
"models": {
"anthropic/claude-haiku-4-5-20251001": { "alias": "haiku" },
"anthropic/claude-sonnet-4-5-20250929": { "alias": "sonnet" }
},
"subagents": {
"model": "anthropic/claude-haiku-4-5-20251001"
}
}
}
}
What's happening:
primary— the main model for chats (Sonnet, $3/M input)fallbacks— automatic switch to Haiku on a rate limit ($0.25/M input)subagents.model— subagents always use Haiku (12 times cheaper)
Subagents on Haiku are fine. They do parallel subtasks: finding files, checks, simple queries. Haiku 4.5 handles them perfectly.
Step 2 · Compressing the workspace 30 min ~50% input
Workspace files are loaded into the context with every message. Every extra kilobyte is money.
Check the current size
du -sh ~/.openclaw/workspace/
# Typical result: 45-80 KB
wc -c ~/.openclaw/workspace/*.md
The DRY principle: don't duplicate
The most common problem is information repeated across several files:
- The project description — in SOUL.md, AGENTS.md and MEMORY.md
- The list of tools — in TOOLS.md and AGENTS.md
- Commands — in AGENTS.md and MEMORY.md
Rule: every fact should live in one place. Other files link to it.
MEMORY.md is the main source of bloat
It grows over time. After a month — 20-30 KB. The fix:
- Create
memory/archive-YYYY-MM-DD.mdfor old entries - Keep only what's current in MEMORY.md
- Target: MEMORY.md < 5 KB
AGENTS.md, HEARTBEAT.md, SOUL.md
Delete unused sections, simplify the instructions for the cheap model, remove duplicates.
| File | Before | After |
|---|---|---|
| MEMORY.md | 22 KB | 4.4 KB |
| AGENTS.md | 7.8 KB | 2.3 KB |
| SOUL.md | 7.2 KB | 4.2 KB |
| HEARTBEAT.md | 4.8 KB | 1.6 KB |
| Total | 45+ KB | 20 KB |
Step 3 · Ollama for heartbeats 15 min $0/month
Ollama runs an LLM locally. The llama3.2:3b model weighs 2 GB and handles heartbeat tasks perfectly.
Installation
# Install Ollama
brew install ollama
# Download the model (~2 GB)
ollama pull llama3.2:3b
# Start it (or open Ollama.app)
ollama serve
Set up the provider in openclaw.json
{
"models": {
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434/v1",
"api": "openai-completions",
"apiKey": "ollama-local",
"models": [
{
"id": "llama3.2:3b",
"name": "Llama 3.2 3B",
"reasoning": false,
"input": ["text"],
"cost": {
"input": 0, "output": 0,
"cacheRead": 0, "cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192
}
]
}
}
}
}
Assign Ollama to heartbeats
{
"agents": {
"defaults": {
"heartbeat": {
"model": "ollama/llama3.2:3b"
}
}
}
}
Result: heartbeats run locally, without the API. Cost: $0. Latency: 2-5 sec.
Step 4 · bootstrapMaxChars 1 min insurance
One line in agents.defaults:
{
"agents": {
"defaults": {
"bootstrapMaxChars": 12000
}
}
}
If the workspace grows beyond the limit, OpenClaw will trim the bootstrap context instead of loading all of it.
Recommended values:
12000— aggressive savings (for a compressed workspace)20000— moderate (a good balance)30000— light (for a workspace with lots of instructions)
Step 5 · Token Efficiency in the system prompt 5 min ~30-50% output
Add a block of savings instructions to SOUL.md:
## Token Efficiency
- Answer briefly. Don't repeat the context back.
- For heartbeats: if there's nothing to report → only HEARTBEAT_OK
- Don't retell files — use links.
- Group checks: one message instead of several.
Without this block the assistant may retell file contents (+500-1000 output tokens), reply at length to a heartbeat instead of HEARTBEAT_OK, and send 3 messages instead of one.
With Token Efficiency instructions the assistant generates 30-50% fewer output tokens.
Step 6 · Automatic session cleanup 5 min speed
Every OpenClaw session is saved to a .jsonl file. Over a month that's hundreds of megabytes. Create a script:
#!/usr/bin/env bash
# cleanup-sessions.sh
set -euo pipefail
SESSIONS_DIR="$HOME/.openclaw/agents/main/sessions"
ARCHIVE_DIR="$HOME/.openclaw/sessions-archive"
DAYS="${1:-7}"
[ ! -d "$SESSIONS_DIR" ] && echo "No sessions" && exit 1
TOTAL=$(find "$SESSIONS_DIR" -name '*.jsonl' | wc -l | tr -d ' ')
OLD=$(find "$SESSIONS_DIR" -name '*.jsonl' -mtime +"$DAYS" | wc -l | tr -d ' ')
SIZE_BEFORE=$(du -sh "$SESSIONS_DIR" | cut -f1)
echo "Sessions: $TOTAL ($SIZE_BEFORE), older than $DAYS days: $OLD"
[ "$OLD" -eq 0 ] && echo "Nothing to archive" && exit 0
mkdir -p "$ARCHIVE_DIR"
ARCHIVE="sessions-$(date +%Y%m%d).tar.gz"
find "$SESSIONS_DIR" -name '*.jsonl' -mtime +"$DAYS" -print0 | \
tar czf "$ARCHIVE_DIR/$ARCHIVE" --null -T -
find "$SESSIONS_DIR" -name '*.jsonl' -mtime +"$DAYS" -delete
echo "Done: $(du -sh "$SESSIONS_DIR" | cut -f1), deleted: $OLD"
chmod +x cleanup-sessions.sh
./cleanup-sessions.sh 7
The full config · Everything together
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-5-20250929",
"fallbacks": ["anthropic/claude-haiku-4-5-20251001"]
},
"models": {
"anthropic/claude-haiku-4-5-20251001": { "alias": "haiku" },
"anthropic/claude-sonnet-4-5-20250929": { "alias": "sonnet" }
},
"bootstrapMaxChars": 12000,
"heartbeat": {
"model": "ollama/llama3.2:3b"
},
"subagents": {
"model": "anthropic/claude-haiku-4-5-20251001"
}
}
},
"models": {
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434/v1",
"api": "openai-completions",
"apiKey": "ollama-local",
"models": [
{
"id": "llama3.2:3b",
"name": "Llama 3.2 3B",
"reasoning": false,
"input": ["text"],
"cost": {
"input": 0, "output": 0,
"cacheRead": 0, "cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192
}
]
}
}
}
}
The result · Before and after
| Step | What we do | Time | Savings |
|---|---|---|---|
| 1. Multi-model routing | Haiku for subagents, fallback | 5 min | ~40-50% |
| 2. Compressing the workspace | DRY, archiving, audit | 30 min | ~50% input |
| 3. Ollama heartbeats | A local model | 15 min | $15-25 → $0 |
| 4. bootstrapMaxChars | A context limit | 1 min | Insurance |
| 5. Token Efficiency | Brevity instructions | 5 min | ~30-50% output |
| 6. Session cleanup | An archiving script | 5 min | Speed |
| Metric | Before | After |
|---|---|---|
| Bootstrap context | 45+ KB (~15K tokens) | 20 KB (~7K) |
| Heartbeat model | Sonnet ($3/M) | Ollama ($0) |
| Subagent model | Sonnet ($3/M) | Haiku ($0.25/M) |
| Idle spend/day | $2-5 | $0 |
| Spend/month | $100-300 | $10-30 |
Time for all 6 steps: ~1 hour. Savings: 80-90% a month.
Don't want to do it by hand?
All these optimisations are already built into MILA GPT — a personal AI assistant based on OpenClaw.
- ✓ Multi-model routing — out of the box
- ✓ Ollama for heartbeats — preinstalled
- ✓ Workspace compressed and optimised
- ✓ Token Efficiency — in the system prompt
- ✓ Session cleanup script — included