mech.app

The mech.app newsletter

Agentic AI, minus the noise.

Get practical field notes on AI agents, automation, developer tools and security delivered to your inbox.

No spam. Unsubscribe anytime.

Security

Peras: How Rate-Limiting Middleware Prevents Coding Agents from Burning Through Weekly API Quotas

Technical breakdown of Peras middleware: how it intercepts Claude Code and Codex API calls, tracks usage state locally, and enforces tiered limits befor...

Source: peras.vertias.eu
Peras: How Rate-Limiting Middleware Prevents Coding Agents from Burning Through Weekly API Quotas

Coding agents like Claude Code and Codex ship without built-in spend governance. Developers manually spam /usage commands to check quota before starting tasks, hoping the agent won’t exhaust the weekly limit mid-refactor. Peras solves this by intercepting API calls at the tool execution layer, tracking usage state locally, and enforcing tiered limits (75% soft warning, 90% hard stop) before agents burn through quotas.

This is not a monitoring dashboard. It is a blocking middleware layer that pauses agent execution when usage crosses thresholds. The architecture exposes a missing primitive: cost control as an active guardrail, not a passive alert.

The Problem: Agents Have No Spend Awareness

Claude Code and Codex operate on weekly API quotas. A single complex prompt can consume 3% of the limit. Overnight runs or parallel sessions can exhaust the quota before the developer notices. The agent has no visibility into remaining budget, no concept of “too expensive to continue,” and no mechanism to pause gracefully.

The pain points:

  • Mid-task exhaustion: Agent stops halfway through a refactor when quota runs out.
  • No checkpointing: Partial work is lost or left in an inconsistent state.
  • Manual monitoring: Developers interrupt workflow to check usage, breaking focus.
  • Shared quota: Activity on claude.ai counts against the same weekly limit as local CLI usage.

Provider-side rate limits do not solve this. They throttle requests per second, not cumulative spend over a week. API key scoping does not help because the quota is tied to the account, not the key.

Architecture: Where Peras Intercepts

Peras operates as a filesystem watcher and tool call proxy. It does not modify the Claude Code or Codex binaries. Instead, it hooks into the agent’s state directory and intercepts tool execution requests before they reach the API.

Interception Point

Peras watches ~/.claude and ~/.codex directories. When an agent prepares a tool call (code execution, file write, terminal command), Peras:

  1. Reads the current usage state from local logs.
  2. Checks the call against configured thresholds (weekly %, prompt %, time-of-day rules).
  3. Decides whether to allow, warn, ask, or block the call.
  4. If blocking, injects a refusal response before the API request is sent.

This happens at the tool call boundary, not the HTTP layer. The agent sees a refused tool execution, not a network error. This distinction matters because the agent can handle a refusal gracefully (end the turn, log the reason) rather than retrying or crashing.

State Persistence

Peras stores usage data in a local SQLite database (or flat file, depending on version). No backend service is required. State includes:

  • 5-hour rolling usage: Recent activity to detect spikes.
  • Weekly cumulative usage: Percentage of quota consumed since last reset.
  • Per-folder attribution: Which project directories are responsible for spend.
  • Pace projection: Estimated time until quota exhaustion at current burn rate.

The state file is updated after every tool call. If the agent crashes or the machine restarts, Peras resumes tracking from the last known state.

Tiered Enforcement

Peras supports three enforcement modes at each threshold:

ModeBehaviorUse Case
warnDesktop notification, agent continuesEarly awareness without interrupting flow
askNext tool call waits for manual approval (once per session)High-stakes tasks where human review is cheap
pauseTool calls refused, turn ends, until peras resume or threshold clearsHard budget enforcement, overnight runs

Example configuration:

# Soft warning at 75% weekly usage
peras set weekly 75 warn

# Hard stop at 90% weekly usage
peras set weekly 90 pause

# Block any single prompt that consumes >3% of weekly quota
peras set prompt 3 pause

# Pause overnight runs if weekly usage exceeds 50%
peras set 01:00-08:00 weekly 50 pause

The ask mode is particularly useful for long-running agents. The approval request is sent via desktop notification and can be answered from a phone (via a companion app or webhook, depending on implementation). This allows the developer to authorize the next step without being physically present at the machine.

What Happens When an Agent Hits the Limit

When Peras blocks a tool call, the agent receives a refusal message instead of executing the tool. The exact behavior depends on the agent’s error handling:

  • Claude Code: Ends the turn and logs the refusal. The conversation remains open. The developer can run peras resume and continue from the last checkpoint.
  • Codex: Similar behavior, but may retry the tool call once before giving up (depends on version).

Peras does not roll back partial changes. If the agent wrote three files before hitting the limit, those files remain. This is intentional: rollback logic belongs in the agent’s transaction layer, not the rate limiter. Peras only controls whether the next tool call is allowed.

Graceful Degradation

If Peras itself crashes or is uninstalled, the agent continues to operate normally. The hooks are non-invasive: they inject a decision layer but do not replace the agent’s core execution loop. Running peras remove uninstalls the hooks cleanly.

Why This Cannot Be Solved Client-Side

The obvious question: why not build this into the Claude Code UI or the Codex CLI?

Three reasons:

  1. Shared quota across surfaces: Usage on claude.ai counts against the same weekly limit as local CLI usage. A client-side solution in the CLI cannot see web activity.
  2. No API for quota visibility: Anthropic and OpenAI do not expose real-time quota data via API. Peras infers usage by parsing local logs and tracking tool call volume.
  3. Cross-session state: Agents often run in multiple terminal sessions or background processes. A UI-level solution cannot enforce limits across all active sessions without a shared state layer.

Peras solves this by operating at the filesystem level, where all agent activity is logged. It is the only place where cross-session, cross-surface usage can be tracked without requiring a backend service.

Observability: Pace Projection and Attribution

The peras status command shows:

  • 5-hour usage bar: Recent activity, useful for detecting runaway loops.
  • Weekly usage bar: Cumulative spend as a percentage of quota.
  • Pace projection: Estimated time until quota exhaustion at current burn rate.
  • Per-folder attribution: Which projects are responsible for spend.

Example output:

Peras 🍐 watching ~/.claude
5h  ▰▰▱▱▱▱▱▱▱▱ 24%  resets 18:24  on pace for 75% at reset
7d  ▰▰▰▰▰▰▰▰▱▱ 78%  resets Sat 12:00  full by Thu 14:59

⚠️ weekly 78% (line 75%), weekly runs out Thu 14:59 at this pace

This week by chat (≈: shared out by what each spent):
≈ +41%  ~/code/app     7f3a9c21
≈ +12%  ~/code/blog    b81e04d7

The pace projection is critical. It answers the question: “If I start this task now, will I have quota left for tomorrow’s work?” Without it, developers are guessing.

Deployment Shape

Peras ships in two forms:

  1. CLI: Free, MIT-licensed, runs as a background process. Installed via npx peras-cli setup. Works on any platform with Node.js 18+.
  2. macOS app: Paid ($4.99 one-time), adds a menubar widget and system-wide hotkey (⌃⌥P). Built with SwiftUI, no Electron overhead.

The CLI is sufficient for enforcement. The app adds convenience (glanceable status, one-click pause/resume). Both share the same state file and enforcement logic.

For teams, the CLI can be deployed via dotfiles or a shared configuration repository. Each developer runs their own Peras instance, but the configuration (thresholds, enforcement modes) can be standardized.

Failure Modes

Peras introduces new failure surfaces:

  • False positives: If the local usage log is corrupted or out of sync, Peras may block tool calls prematurely. Mitigation: peras reset rebuilds the state from API logs.
  • Missed calls: If the agent bypasses the tool call layer (e.g., direct HTTP requests), Peras cannot intercept. This is rare but possible with custom agent implementations.
  • Stale projections: Pace projection assumes constant burn rate. Bursty workloads (large refactors followed by idle periods) will skew the estimate.
  • Quota reset timing: Peras relies on the developer to configure the correct weekly reset time. If the reset time is wrong, enforcement thresholds will be off by hours or days.

None of these are catastrophic. The worst case is a blocked tool call that should have been allowed, which is resolved by running peras resume.

Technical Verdict

Use Peras if:

  • You run long-running or overnight coding agents and have been burned by mid-task quota exhaustion.
  • You need per-project spend attribution to understand which codebases are expensive to maintain.
  • You want a local-first solution with no backend dependencies or SaaS subscriptions.

Avoid Peras if:

  • Your agent workloads are short and bursty. Manual /usage checks are sufficient.
  • You need cross-team quota pooling or centralized spend dashboards. Peras is single-user, local-state only.
  • You require sub-second enforcement latency. Peras polls the state file every few seconds, which is fine for tool calls but too slow for real-time request throttling.

Peras is not a cost optimization tool. It does not make agents cheaper. It prevents them from spending more than you intended, which is a different problem. The value is in predictability: knowing that an agent will stop before exhausting the quota, rather than discovering it mid-task.