Multi-Agent Shared Workspace Budget Patterns
When multiple agents operate within the same workspace — a team of planners, executors, and reviewers working on a shared task — they need to share finite reservation capacity without racing each other. This guide covers recommended patterns for structuring budgets in multi-agent systems.
Concurrency is the core challenge
Multiple agents checking and spending against a shared budget creates race conditions. Always use Cycles reservations (not balance reads) for spending decisions. See Concurrent Agent Overspend for a detailed explanation of the failure mode.
What “cap” means here
Atomic reservations cap concurrent submitted estimates on mandatory instrumented paths. Actual external cost is known only after execution and settlement follows the configured commit overage policy. Use conservative estimates and treat the application/provider record as the economic outcome.
Pattern 1: Shared workspace budget with no per-agent limits
The simplest pattern. Every instrumented agent submits the same workspace scope. Atomic reservations prevent their submitted estimates from oversubscribing that explicitly provisioned ledger.
Scope: tenant:acme-corp/workspace:project-alpha
# Create a shared $50 budget for the workspace
curl -s -X POST http://localhost:7979/v1/admin/budgets \
-H "Content-Type: application/json" \
-H "X-Cycles-API-Key: $CYCLES_API_KEY" \
-d '{
"scope": "tenant:acme-corp/workspace:project-alpha",
"unit": "USD_MICROCENTS",
"allocated": { "amount": 5000000000, "unit": "USD_MICROCENTS" }
}'Client setup (Python):
@cycles(
estimate=lambda prompt: len(prompt) * 10,
tenant="acme-corp",
workspace="project-alpha",
agent="planner", # identifies which agent, but all share workspace budget
)
def planner_call(prompt: str) -> str:
return call_llm(prompt)When to use: Small teams of cooperating agents where individual fairness does not matter and one shared estimate-admission ceiling is sufficient.
Trade-off: A single expensive agent can exhaust the budget for all others.
Pattern 2: Per-agent ledgers under a shared workspace cap
Give each agent its own explicitly provisioned ledger, with a workspace ledger acting as a shared cap. These balances are not transferred from the workspace ledger. Each protected call submits both scopes, and the server checks matching ledgers atomically.
Scope hierarchy:
tenant:acme-corp/workspace:project-alpha → $50 (shared reservation ceiling)
tenant:acme-corp/workspace:project-alpha/agent:planner → $20
tenant:acme-corp/workspace:project-alpha/agent:executor → $30
tenant:acme-corp/workspace:project-alpha/agent:reviewer → $10
───
Sum: $60 > $50 (OK)# Workspace-level cap
curl -s -X POST http://localhost:7979/v1/admin/budgets \
-H "Content-Type: application/json" \
-H "X-Cycles-API-Key: $CYCLES_API_KEY" \
-d '{
"scope": "tenant:acme-corp/workspace:project-alpha",
"unit": "USD_MICROCENTS",
"allocated": { "amount": 5000000000, "unit": "USD_MICROCENTS" }
}'
# Per-agent budgets
for agent_budget in "planner:2000000000" "executor:3000000000" "reviewer:1000000000"; do
agent="${agent_budget%%:*}"
amount="${agent_budget##*:}"
curl -s -X POST http://localhost:7979/v1/admin/budgets \
-H "Content-Type: application/json" \
-H "X-Cycles-API-Key: $CYCLES_API_KEY" \
-d "{
\"scope\": \"tenant:acme-corp/workspace:project-alpha/agent:${agent}\",
\"unit\": \"USD_MICROCENTS\",
\"allocated\": { \"amount\": ${amount}, \"unit\": \"USD_MICROCENTS\" }
}"
doneWhy per-agent budgets can exceed the workspace budget: The workspace scope is checked at reservation time alongside the agent scope. If the workspace is exhausted, the reservation is denied — regardless of the agent's remaining budget. Over-allocating at the agent level provides flexibility: if the planner finishes under budget, the executor can use more of the shared pool.
When to use: Multi-agent workflows where you want both individual estimate ceilings and a collective reservation ceiling.
Pattern 3: Workflow-scoped budgets for task isolation
When agents run multiple independent workflows (e.g. processing different customer requests), scope budgets per workflow to prevent one task from consuming another's budget.
Scope hierarchy:
tenant:acme-corp/workspace:prod/workflow:task-123 → $10
tenant:acme-corp/workspace:prod/workflow:task-123/agent:planner
tenant:acme-corp/workspace:prod/workflow:task-123/agent:executor
tenant:acme-corp/workspace:prod/workflow:task-456 → $10
tenant:acme-corp/workspace:prod/workflow:task-456/agent:planner
tenant:acme-corp/workspace:prod/workflow:task-456/agent:executorClient setup (TypeScript):
const plannerCall = withCycles(
{
estimate: 2_000_000,
tenant: "acme-corp",
workspace: "prod",
workflow: taskId, // dynamic per-task
agent: "planner",
},
async (prompt: string) => callLlm(prompt),
);When to use: Task-parallel systems where each task should have an independent budget ceiling.
Pattern 4: Tiered agents with differentiated limits
Give expensive agents (e.g. those using GPT-4) smaller budgets than cheap agents (e.g. those using GPT-4o-mini), reflecting their different cost profiles.
# Expensive planner agent — small budget ($5), large model
curl -s -X POST http://localhost:7979/v1/admin/budgets \
-H "Content-Type: application/json" \
-H "X-Cycles-API-Key: $CYCLES_API_KEY" \
-d '{
"scope": "tenant:acme-corp/workspace:prod/agent:planner",
"unit": "USD_MICROCENTS",
"allocated": { "amount": 500000000, "unit": "USD_MICROCENTS" }
}'
# Cheap executor agent — larger budget ($20), smaller model
curl -s -X POST http://localhost:7979/v1/admin/budgets \
-H "Content-Type: application/json" \
-H "X-Cycles-API-Key: $CYCLES_API_KEY" \
-d '{
"scope": "tenant:acme-corp/workspace:prod/agent:executor",
"unit": "USD_MICROCENTS",
"allocated": { "amount": 2000000000, "unit": "USD_MICROCENTS" }
}'Handling denials gracefully
In any multi-agent system, some agents will be denied budget. Design for this:
from runcycles import cycles, BudgetExceededError
@cycles(estimate=2_000_000, agent="executor")
def executor_call(prompt: str) -> str:
return call_llm(prompt)
def run_executor(prompt: str) -> str:
try:
return executor_call(prompt)
except BudgetExceededError:
# Options: use a cheaper model, return cached results,
# queue for later, or signal the orchestrator to stop
return use_cheaper_model(prompt)For a full treatment of degradation strategies, see Degradation Paths.
Monitoring shared budgets
Track budget consumption across agents to detect imbalances early:
# Check remaining budget across all agents in a workspace
curl -s "http://localhost:7878/v1/balances?tenant=acme-corp&workspace=project-alpha" \
-H "X-Cycles-API-Key: $API_KEY" | jq '.balances[] | {scope_path, remaining: .remaining.amount, spent: .spent.amount}'Set up alerts when any scope drops below 10% remaining with active reservations. See Monitoring and Alerting for detailed setup.
Key principles
- Reserve, don't read. Balance queries are informational. Reservations are authoritative. Never use a balance read to decide whether to proceed.
- Use broader scopes as shared admission ceilings. Per-agent ledgers provide individual limits; workspace/tenant ledgers constrain combined reservation estimates.
- Design for denial. Any agent can be denied at any time. Graceful degradation is not optional.
- Set the
agentfield. Always identify which agent is spending. This enables per-agent monitoring, debugging, and budget allocation.
Next steps
- Common Budget Patterns — per-user, per-workflow, and other scope recipes
- Concurrent Agent Overspend — the failure mode these patterns prevent
- Scope Derivation — how hierarchical scopes work
- Degradation Paths — handling denial gracefully