How I cut my Claude Code bill from $180 to $31/month — and what the Agent Monitor revealed about how AI coding tools actually waste your money.
I pulled three months of Claude Code session logs and analyzed them. The result was uncomfortable.
"Could you please help me with…"
"If it's not too much trouble…"
"I was wondering if you might be able to…"
"What I'd like you to do here is just…"
Roughly 35% of my input tokens went to content that provided zero signal to the model. I was talking to Claude like a nervous intern I didn't want to offend. Claude doesn't have feelings. It doesn't try harder because you said "please." The politeness tax is 100% yours.
Your prompt, tokenized:
Claude Sonnet 4.5 is priced at $3 per million input tokens. But that's not the number that matters. Every message in a long session re-sends the entire conversation history. Message 50 costs 200 tokens plus 49 previous messages. Context compounds. That 35% noise compounds with it.
Terse is a macOS application that sits between your keyboard and your AI tools. It reads what you're typing, compresses it locally, and replaces it before you send. No servers. No third parties. Your prompts never leave your machine.
One thing worth getting right immediately: Terse is not an Electron app. It's built on Tauri — a framework that uses Rust for the backend and the system's native WKWebView for the frontend.
Using Rust wasn't aesthetic. The performance requirements for real-time text processing, file system watching, and process introspection made a compiled systems language the right call. The NLP optimizer runs in a Node.js sidecar, but all system-level operations — agent monitoring, capture pipeline, IPC — are native Rust.
terse-ax Swift HelperThe core challenge: reading from and writing to arbitrary third-party apps requires access to their text fields — owned by other processes. On macOS, the answer is the Accessibility API.
Terse ships a compiled Swift binary called terse-ax. When Terse starts, Rust resolves the path from the Tauri bundle structure:
// Contents/MacOS/ — main binary
// Contents/Resources/terse-ax — Swift helper
let r1 = contents_dir.join("Resources/terse-ax");
if r1.exists() { return r1.to_string_lossy().to_string(); }
On first run, two things happen automatically:
// Remove macOS quarantine (set on all DMG-installed binaries)
Command::new("xattr").args(["-dr", "com.apple.quarantine", &path]);
// Ensure executable bit is set
Command::new("chmod").args(["+x", &path]);
Without quarantine removal, Gatekeeper would block the Swift helper even after the user grants accessibility permissions — a common DMG distribution pitfall.
Cmd+C → compress → Cmd+V). The UI shows which method is active.Before any compression logic runs, a three-stage spellcheck fires first.
Stage 1 — Hardcoded TYPOS dictionary (~600 entries). O(1) lookups for the most common developer typos: fucntion → function, algortihm → algorithm, databse → database. A TECH_WORDS allowlist (~100 entries: async, jwt, kubernetes…) prevents downstream stages from mangling valid tech vocabulary.
Stage 2 — Norvig edit-distance with QWERTY proximity weighting. Generates candidate corrections at edit distance 1–2, filters to known words, ranks by frequency. The QWERTY weight means teh scores higher confidence than zeh as a correction of the — adjacent-key errors are structurally more likely.
Stage 3 — nspell (Hunspell-backed). Same dictionaries as Firefox and LibreOffice. Catches anything the first two stages miss.
After spellcheck, code blocks are extracted and vaulted (restored verbatim at the end). Then compression runs:
| Mode | Reduction | What it removes | Best for |
|---|---|---|---|
| 🟢 Soft | 5–15% | Contractions, verbose phrases, filler adverbs, greetings | Precise technical conversations |
| 🟡 Normal | 20–35% | Politeness wrappers, meta-language, hedging, redundancy | Daily coding — default mode |
| 🔴 Aggressive | 40–70% | Articles, prepositions, markdown, all social scaffolding | Batch Agent tasks, pipelines |
Prompt compression is linear savings. The Agent Monitor catches geometric waste — the kind that can run up hundreds of turns before you notice.
When a Claude Code session runs long, the context window fills. At high fill percentages, agents start thrashing: re-reading files already processed, re-calling tools used 20 steps ago, generating filler text to "stay busy." This is invisible in a terminal — tool calls scroll by, costs accumulate silently.
Claude Code stores every session as a JSONL file under ~/.claude/projects/<encoded-cwd>/. The directory name is the working directory with / replaced by -. Terse finds the right session by:
// 1. lsof to get CWD of every running 'claude' process
Command::new("lsof").args(["-c", "claude", "-a", "-d", "cwd", "-Fn"])
// 2. Encode CWD to match Claude's project dir naming
let encoded = cwd.replace('/', "-");
// 3. Prefer the session matching the focused terminal
// (highest PID = most recently started claude process)
if is_focused && !was_focused { true } // focused wins over recency
else if mtime > prev_mtime { true } // recency as tiebreaker
Duplicate detection uses a hash of tool_name + first 100 chars of input. If a hash is already in the seen set, the call is flagged:
let cache_key = format!("{}:{}", name, input_prefix);
if !self.tool_call_hashes.insert(cache_key) {
// Already seen this tool+input combo — flag it
self.duplicate_tool_calls += 1;
}
Redundant file reads are tracked separately with a HashMap<String, u32> — any file with count ≥ 2 is flagged. Wasted tokens estimated at ~800 per redundant read (average file size in a typical project).
Not all tool output is equally dense. Terse estimates how compressible each tool's results are:
Bash output is most compressible: git logs, test runners, build output — lots of structure that tokenizes poorly but compresses well.
The monitor isn't Claude Code-specific. Terse detects any of these agents automatically:
| Agent | Detection Method | Parser |
|---|---|---|
| Claude Code 🤖 | lsof CWD → ~/.claude/projects/ JSONL | claudeCode |
| Cursor Agent 📝 | Process scan (Cursor Helper) + ~/.cursor | generic |
| Cline 🔍 | VS Code extension storage mtime | generic |
| Windsurf 🏄 | Process scan (Windsurf Helper) + ~/.windsurf | generic |
| Aider 🔧 | Process scan (aider) | generic |
| OpenAI Codex 🧠 | ~/.codex/sessions mtime | codex |
| Copilot CLI ✈ | Process scan (ghcs, copilot-cli) | generic |
For VS Code extensions (Cline, Copilot Chat) with no standalone process, Terse checks whether the extension's storage directory has been recently modified — a modification means the extension is active.
My Claude Code monthly spend: $180 → $31 over three months of daily use.
| Savings driver | Type | Mechanism |
|---|---|---|
| Prompt compression | Linear | Normal mode, 20–35% per message × thousands of messages |
| Interrupted degenerate sessions | Non-linear | Agent Monitor flags thrashing → /compact or restart |
| Behavior change | Compounding | Live token counter changes how you write prompts |
/compact earlier. You start fresh sessions more readily. A monthly invoice tells you nothing actionable. A live counter changes behavior.| Limitation | Why |
|---|---|
| macOS only | AX API is mature and consistent on macOS. Windows UIA is unreliable across Electron apps. Roadmap. |
| No browser-terminal Claude Code | Desktop client and VS Code terminal only. Browser-based terminal isn't AX-readable. |
| Aggressive mode loses precision | By design. For batch Agent automation, not nuanced technical discussions. |
| Agent Monitor requires local Claude Code | Reads ~/.claude/projects/ JSONL. Remote/SSH sessions not watched. |
A background tool that quietly consumes 300 MB of RAM and 15% CPU is one that gets force-quit. Terse runs alongside Claude Code, Cursor, and whatever else you have open — it can't be the memory hog.
Tauri eliminates bundled Chromium by using WKWebView. The Rust backend handles all system-level operations with memory-safe compiled code. The app binary is ~6 MB, starts in under half a second, and idles at 15–30 MB — numbers that matter when your AI tools are already hungry.
Most advice about AI productivity focuses on outputs: better prompts, better responses. Almost none focuses on the input side — what you're actually sending, how much is noise, what that noise costs at scale.
Heavy AI users send millions of tokens per month. At those volumes, 35% waste is a real number. Fixing it doesn't require understanding transformer architecture. It requires acknowledging that habits built for human communication don't apply to language models — and running a tool that enforces that awareness automatically.
Full access, no limits, no credit card. Every feature unlocked for 30 days. Install, watch your bill.
30 days free · Unlimited access · No credit card required · $4.99/mo after trial