Token Efficiency in OpenClaw: Let Scripts Do the Heavy Lifting

@Shpigford
Josh Pigford @Shpigford
Friday, February 6, 2026

Tweet

https://t.co/ex8cdBWSQr

X Article

Here's how I cut token costs by moving from "smart polling" to "dumb scripts + smart triggers". The Problem When you first set up an AI assistant (OpenClaw, in my case), it's tempting to make it do everything. Check your email every hour. Monitor your print farm. Sync your bookmarks. Watch for errors. But here's the math problem: if your agent wakes up every few minutes to "check on things," and each check burns tokens just to read context and decide "nothing happening" — you're spending real money on nothing. I learned this the hard way, with the problem being magnified while I was building a "swarm" coding system. Looking back at my session logs: 260+ Swarm Dispatcher sessions where Opus checked if there was work to do 315+ "Queue empty" responses — each one burning $0.01-0.07 in tokens 8 consecutive HEARTBEAT_OK responses in 16 minutes — all on the most expensive model The Swarm dispatcher alone burned $10-20 just checking empty queues. Every two minutes, Opus woke up, loaded context, checked an endpoint, found nothing, and responded. Repeat 260+ times. And that was just one feature I was building...not even accounting for all the other things I was having OpenClaw do. How Heartbeats Work OpenClaw has a "heartbeat" system — a periodic poll (default every 30 minutes) that wakes your agent and asks "anything need attention?" The agent reads a HEARTBEAT.⁠md file in your workspace, which lists tasks to check: emails, calendar, printer status, whatever you've configured. The idea is good: your agent stays aware of the world without you manually asking. But every heartbeat is a full model invocation — context loading, reasoning, tool calls, response. Even if the answer is "nothing happening," you've paid for the model to figure that out. The Philosophy Models are expensive thinkers. Scripts are free doers. If a task can be expressed as deterministic logic ("if X, then Y"), it belongs in a script. Models should only engage when there's actual ambiguity — formatting for humans, deciding whether something is worth reporting, or handling edge cases that would be painful to code. The Three-Tier Model Strategy Not all model work is equal. OpenClaw can/will use browsers a lot to find data or perform actions. But "browsing" itself doesn't need a fancy model. Here's what I measured when running the same browser task on different models: Opus: $0.089 per turn, ~$0.15+ per task Haiku: $0.017 per turn, ~$0.03 per task 5x cheaper for identical work. This led to a tiered approach: Premium (Opus) — Main conversation, complex decisions Workhorse (Sonnet 4.5) — Research, writing, analysis Cheap (Haiku 4.5) — Browser automation, mechanical tasks The key insight: your main session should orchestrate, not execute. When I need browser work done, I spawn a Haiku sub-agent. Research tasks get Sonnet. Opus stays focused on conversation. One gotcha: model names matter. OpenClaw initially used claude-3-5-haiku instead of claude-haiku-4-5, which caused silent fallback to Opus. Always verify the model actually applied. The Cron + Script Pattern Before (Token-Heavy) Heartbeat → Model wakes → Reads HEARTBEAT.⁠md → Figures out what to check → Runs commands → Interprets output → Decides action → Maybe reports Every step burns tokens. The model is thinking about things that don't require thought. After (Token-Light) Cron fires → Script runs (zero tokens) → Script handles all logic → Only calls model if there's something to report → Model formats & sends Real Examples Swarm Dispatcher Old way: Opus cron job every 2 minutes checking dispatch queue, $0.01-0.07 per tick New way: Native code in hankOS checks the queue, only invokes model when work exists Savings: 260+ empty invocations eliminated = $10-20 saved Print Farm Monitoring Old way: Model checks printer status every 5 minutes, compares to last state, decides if alert needed New way: Bash script does the diff, only outputs if something changed Savings: ~50 model invocations/day → ~3 Auth Watchdogs Old way: Model checks if API tokens are valid during every heartbeat New way: Script returns exit code 0 (valid) or 1 (invalid). Model only wakes on failure. Savings: Moved from every-heartbeat to 6-hour cron = 12x reduction in invocations Browser Automation Old way: Opus doing the clicking, burning $0.089 per turn New way: Haiku sub-agent, $0.017 per turn Savings: 5x cost reduction, plus 168k tokens isolated from main session context Implementation Tips 1. Write Scripts That Output Nothing on Success Then your cron job prompt becomes: "Run the script. If there's output, send it to me. If not, stay silent." 2. Use delivery: "none" by default Most cron jobs shouldn't announce themselves. Set delivery mode to none and have the agent explicitly send messages only when warranted. 3. Pre-Format in Scripts Don't make the model format tables or summaries. Do it in the script: The model's job becomes "send this" — not "understand this data and present it nicely." 4. Isolated Sessions for Everything Scheduled Every cron job should run in sessionTarget: "isolated". This keeps your main session context clean and prevents scheduled tasks from polluting your conversation history. 5. Match Model to Task In your cron job payloads, explicitly set the model: My X bookmark syncing process didn't need Opus. The Heartbeat's New Role After optimizing, I realized my heartbeat could be nearly empty. Tasks I initially kept there — backup sync, dispatch queue checks — were still following the old pattern. They didn't need model judgment. So I moved them to cron: Backup sync — Every 30m, Haiku, silent unless failure Mission Control Dispatcher — Every 5m, Sonnet, spawns sub-agents if work exists My HEARTBEAT.⁠md is now just a fallback: Heartbeats still have a use case: batched checks that benefit from shared context. If you want your agent to check email, calendar, and weather in one turn and correlate them ("you have an outdoor meeting in an hour and rain is coming"), that's a heartbeat task. But if your checks are independent? Cron jobs. Every time. Results After migrating to this pattern: Swarm empty-queue checks: 260+ sessions costing $10-20 → 0 (native code) Browser task cost: $0.15+ per task → $0.03 per task Auth check frequency: Every heartbeat → Every 6 hours (12x reduction) Heartbeat response: Run checks then report → Instant HEARTBEAT_OK The main session stays lean. Scheduled work runs isolated on cheaper models. Scripts handle the deterministic stuff for free. TL;DR Scripts for logic, models for judgment — if it can be an if statement, don't burn tokens on it Tier your models — Haiku for labor ($0.017/turn), Sonnet for craft, Opus for conversation ($0.089/turn) Silent by default — only invoke models when there's something to say Isolated sessions — scheduled work shouldn't pollute your main context Verify model names — a typo can silently fall back to expensive defaults Your AI assistant is a thinker, not a cron daemon. NOTE: You should be able to just point OpenClaw to this article and say "Implement this" to make sure your own system is optimized.
Skip

Low signal or already known

Quick Insight

This is just a link with no context - can't evaluate the actual content without seeing what's behind the URL. The author (@Shpigford) is Josh Pigford who's built several successful SaaS products, so it's likely business/product-related content, but impossible to assess value without the actual link working.

Actionable Takeaway

Nothing actionable - the link appears broken or inaccessible, so there's no content to act on.

Related to Your Work

Can't determine relevance without seeing the actual content behind the link.

Source Worth Reading

The link is inaccessible, so can't evaluate the source material. Given it's from Josh Pigford, it could potentially be valuable business/SaaS content, but the broken link makes it useless.

Tags

#broken-link #shpigford #no-context