CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
Stop Runaway Agent Bills: Use --max-turns and total_cost_usd to Cap and Track Every Claude Code Run

Stop Runaway Agent Bills: Use --max-turns and total_cost_usd to Cap and Track Every Claude Code Run

Chris Harper

3 min read

Jul 10, 2026 · 20:05 UTC

AI
Workflow
Claude Code
Best Practices

TL;DR: --max-turns N exits the agent loop after N turns so it can't spiral; --output-format json returns total_cost_usd in the result so you know exactly what every automated task cost — wire them together and your CI never surprises you with an unexpected bill.

Running Claude Code headlessly in a pipeline is powerful, but two failure modes bite teams early: (1) the agent gets stuck retrying a bad approach and burns through turns and tokens, and (2) nobody knows what any individual task cost until the monthly invoice arrives. Two flags fix both.

--max-turns — the hard stop

claude -p "refactor the payment module" \
  --max-turns 10 \
  --output-format json \
  --allowedTools Edit,Read,Bash \
  --permission-mode dontAsk

--max-turns 10 means the agent completes at most 10 turns (a tool call + response counts as one turn). When the limit hits, Claude summarizes what it completed and exits — it doesn't leave you with partial, half-applied edits. Good defaults by task type:

Task--max-turns
Single-file refactor5–8
Multi-file feature10–15
Security scan / read-only analysis3–5
Open-ended research20+

Too low and Claude can't finish; too high and a confused agent runs up cost. Start conservative and tune up.

total_cost_usd — per-task spend tracking

With --output-format json, the envelope Claude prints to stdout includes the cost field:

result=$(claude -p "write unit tests for auth.ts" \
  --max-turns 8 \
  --output-format json \
  --allowedTools Read,Bash,Write \
  --permission-mode dontAsk)

cost=$(echo "$result" | jq -r '.total_cost_usd')
session=$(echo "$result" | jq -r '.session_id')
text=$(echo "$result" | jq -r '.result')

echo "Session $session | Cost: \$${cost}"
echo "$text"

A cost-alert wrapper

#!/usr/bin/env bash
# agent-run.sh — run a Claude Code task with cost ceiling
PROMPT="$1"
MAX_TURNS="${2:-10}"
ALERT_THRESHOLD="${3:-0.25}"   # alert if task exceeds $0.25

result=$(claude -p "$PROMPT" \
  --max-turns "$MAX_TURNS" \
  --output-format json \
  --permission-mode dontAsk 2>&1)

cost=$(echo "$result" | jq -r '.total_cost_usd // "0"')

if (( $(echo "$cost > $ALERT_THRESHOLD" | bc -l) )); then
  echo "COST ALERT: \$${cost} exceeds threshold of \$${ALERT_THRESHOLD}" >&2
fi

echo "$result" | jq -r '.result'

Usage: ./agent-run.sh "review the PR for security issues" 5 0.10

Logging for cost attribution

For CI pipelines, log session_id and total_cost_usd to your observability tool (Datadog, Grafana, or even a flat log file). After a week you'll see which task types cost most and can tune --max-turns accordingly. A task that should take 3 turns but is configured for 20 will keep finding new ways to spin.

Sources: Run Claude Code programmatically — Claude Code Docs · Claude Code CI/CD Automation Guide — hidekazu-konishi.com · Claude Code Headless Mode CI/CD Playbook — Code With Seb