How Paperclip Enforces Budgets During AI Agent Runs

Paperclip prevents runaway AI costs by tracking every billed token against configurable budget policies that trigger soft alerts or hard stops, automatically pausing agents, projects, or entire companies when spending limits are exceeded.

Paperclip is an open-source AI agent platform that implements hierarchical budget enforcement to prevent unexpected cloud spending. According to the paperclipai/paperclip source code, the system aggregates cost events in real time and applies scope-specific policies that can block new agent invocations and pause active work when budgets are breached.

Cost Event Tracking and Aggregation

Every agent heartbeat generates a cost event that records the provider, model, input/output tokens, and cost in cents. These events populate the costEvents table and feed into budget calculations.

The computeObservedAmount function in server/src/services/budgets.ts aggregates these costs by summing costCents for the relevant company, agent, or project within the policy’s defined time window. This computed total represents the current observed spend against which thresholds are evaluated.

Budget Policy Structure

Budget policies are stored in the budget_policies table (defined in packages/db/src/schema/budget_policies.ts) and specify:

  • Scope: Company, agent, or project level
  • Metric: Typically billed_cents
  • Window: Either calendar_month_utc or lifetime
  • Amount: The budget cap in cents
  • Warning Threshold: Percentage (e.g., 80%) at which to trigger alerts
  • Enforcement Flags: hardStopEnabled and notifyEnabled booleans

The Evaluation Workflow

The evaluateCostEvent function triggers for every new cost event. It selects active policies matching the event’s company/agent/project, computes current spend via computeObservedAmount, and compares against policy thresholds.

Soft Threshold Alerts

When observed spend reaches the configured warn percentage and notifyEnabled is true, the system creates a soft-threshold incident. This generates a non-blocking alert that notifies operators without interrupting agent execution, allowing teams to adjust budgets proactively.

Hard Threshold Enforcement

If spend reaches the hard-stop amount with hardStopEnabled set to true, the policy triggers a hard-threshold incident. The system immediately invokes pauseAndCancelScopeForBudget to halt the scope and cancels any ongoing work, preventing further token consumption.

Scope Pausing Implementation

Paperclip enforces budgets at three hierarchical levels, updating database records to reflect paused status.

Pausing Individual Agents

When an agent budget is exceeded, the system updates the agent record in server/src/services/budgets.ts:

  • Sets status = "paused"
  • Sets pauseReason = "budget"

Pausing Projects and Companies

For broader scope enforcement:

  • Projects: Sets pausedAt timestamp and pauseReason = "budget"
  • Companies: Sets status = "paused" and pauseReason = "budget"

These checks prevent any new activity within the paused scope until the budget incident is resolved.

Blocking New Invocations

Before an agent starts a new task, the getInvocationBlock function validates budget status. It checks company-level budgets first, then agent-level, and finally project-level budgets. If any hard-stop threshold is exceeded, it returns a block object containing a human-readable reason, preventing the agent from receiving new work entirely.

Resuming After Budget Resolution

When operators resolve a budget incident (for example, by raising the budget cap), the resumeScopeFromBudget function clears the pause fields. It restores agent status to "idle" and company status to "active", marks the incident as resolved, and logs the activity. Agents can then resume normal operation immediately.

Practical Implementation Examples

The following patterns demonstrate how to interact with Paperclip’s budget service programmatically:

// Simulate a cost event (normally emitted by the agent heartbeat)
await budgetService(db).evaluateCostEvent({
  companyId: "c123",
  agentId: "a456",
  costCents: 2500,
  // …other fields from costEvents schema
});
// Manually pause an agent because its budget was exceeded
await budgetService(db).pauseScopeForBudget({
  id: "policy-789",
  companyId: "c123",
  scopeType: "agent",
  scopeId: "a456",
  metric: "billed_cents",
  windowKind: "calendar_month_utc",
  amount: 5000,
  warnPercent: 80,
  hardStopEnabled: true,
  notifyEnabled: true,
  isActive: true,
});
// Check whether a new agent invocation should be blocked
const block = await budgetService(db).getInvocationBlock(
  "c123",
  "a456",
  { projectId: "p321" }
);
if (block) {
  console.log(`Invocation blocked: ${block.reason}`);
}

Summary

  • Cost Tracking: Every heartbeat generates a costEvents row aggregated by computeObservedAmount in server/src/services/budgets.ts
  • Policy Configuration: Budgets define scope, window, amount, and enforcement flags in the budget_policies schema
  • Threshold Logic: Soft alerts notify at warning percentages; hard stops trigger pauseAndCancelScopeForBudget to halt execution
  • Scope Hierarchy: Enforcement operates at company, project, and agent levels via status fields and pause reasons
  • Prevention: getInvocationBlock vetoes new tasks before they start when budgets are exhausted
  • Recovery: resumeScopeFromBudget restores scope status after incidents are resolved

Frequently Asked Questions

What happens when an agent exceeds its budget threshold?

When an agent exceeds a soft threshold (e.g., 80% of budget) and notifications are enabled, Paperclip creates a non-blocking incident to alert operators. If the agent hits a hard threshold with hardStopEnabled set to true, the system immediately pauses the agent by setting status to "paused" and pauseReason to "budget", while canceling any ongoing work.

How does Paperclip prevent new agent runs when budgets are exceeded?

Before dispatching new work, the getInvocationBlock function checks budgets hierarchically (company, then agent, then project). If any scope has exceeded its hard limit, the function returns a block object that prevents the invocation from proceeding, ensuring no new costs accrue against exhausted budgets.

Can budget policies apply to multiple projects simultaneously?

Yes. Budget policies can be scoped to the company level, which automatically covers all agents and projects within that organization. Alternatively, operators can create separate policies for individual projects or specific agents, allowing granular control over spending limits across different organizational units.

How do operators resume agents after a budget incident is resolved?

Operators resolve budget incidents through the API or UI, triggering the resumeScopeFromBudget function. This clears the pauseReason field, resets the agent status to "idle" (or company status to "active"), marks the incident as resolved, and restores the agent’s ability to accept new invocations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →