# How Paperclip Enforces Budgets During AI Agent Runs

> Learn how Paperclip enforces budgets during AI agent runs with configurable policies. Prevent runaway AI costs by setting alerts or hard stops to automatically pause agents when spending limits are exceeded.

- Repository: [Paperclip/paperclip](https://github.com/paperclipai/paperclip)
- Tags: how-to-guide
- Published: 2026-08-12

---

**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`](https://github.com/paperclipai/paperclip/blob/main/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`](https://github.com/paperclipai/paperclip/blob/main/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`](https://github.com/paperclipai/paperclip/blob/main/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:

```typescript
// 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
});

```

```typescript
// 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,
});

```

```typescript
// 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`](https://github.com/paperclipai/paperclip/blob/main/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.