Skip to content
Back to skills

1852 196 Dr Sops 02 Cost Caps 4fbebf73

ASecurity

**Production Playbook for Claude Code Plugin Developers** API costs can spiral quickly when running multi-agent workflows at scale. This playbook provides proven strategies for implementing cost controls, monitoring spend in real-time, and optimizing Claude API usage without sacrificing quality.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added June 1, 2026
businesstypescriptbashdebuggingcode-reviewapisecurityperformancedocumentation

Works with

  • claude code
  • api

Security analysis

A96/100
  • mediumUses curl or wget to download content

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 1852-196-dr-sops-02-cost-caps_4fbebf73 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1852 196 Dr Sops 02 Cost Caps 4fbebf73?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1852 196 Dr Sops 02 Cost Caps 4fbebf73
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1852-196-dr-sops-02-cost-caps-4fbebf73/badge)](https://www.skillsdirectory.com/skills/tools-only-1852-196-dr-sops-02-cost-caps-4fbebf73)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Cost Caps & Budget Management

**Production Playbook for Claude Code Plugin Developers**

API costs can spiral quickly when running multi-agent workflows at scale. This playbook provides proven strategies for implementing cost controls, monitoring spend in real-time, and optimizing Claude API usage without sacrificing quality.

## Table of Contents

1. [Understanding API Costs](#understanding-api-costs)
2. [Cost Tracking](#cost-tracking)
3. [Budget Enforcement](#budget-enforcement)
4. [Optimization Strategies](#optimization-strategies)
5. [Production Examples](#production-examples)
6. [ROI Analysis](#roi-analysis)

---

## Understanding API Costs

### Anthropic Claude Pricing (January 2025)

| Model | Input (per 1M tokens) | Output (per 1M tokens) | Context Window |
|-------|----------------------|------------------------|----------------|
| **Claude 3.5 Sonnet** | $3.00 | $15.00 | 200K |
| **Claude 3.5 Haiku** | $0.80 | $4.00 | 200K |
| **Claude 3 Opus** | $15.00 | $75.00 | 200K |

**Reality Check**: A single code review session can cost:
- Small file (500 tokens): $0.0075 (Sonnet)
- Large file (5,000 tokens): $0.075 (Sonnet)
- Full repository (50,000 tokens): $0.75 (Sonnet)

### Hidden Cost Drivers

```typescript
// ❌ This conversation costs $4.50
const response = await claude.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 4096,
  messages: [{
    role: 'user',
    content: `Review this entire codebase: ${fs.readFileSync('monorepo.txt')}` // 250K tokens
  }]
});

// Breakdown:
// - Input: 250K tokens × $3/1M = $0.75
// - Output: 4K tokens × $15/1M = $0.06
// - Total per call: $0.81
//
// Multi-agent workflow (5 agents):
// - 5 agents × $0.81 = $4.05
// - Daily runs: 10
// - Monthly cost: $4.05 × 10 × 30 = $1,215
```

---

## Cost Tracking

### 1. Real-Time Token Counting

```typescript
import Anthropic from '@anthropic-ai/sdk';

interface CostMetrics {
  inputTokens: number;
  outputTokens: number;
  inputCost: number;
  outputCost: number;
  totalCost: number;
  model: string;
}

class CostTracker {
  private costs: CostMetrics[] = [];

  // Pricing table (per 1M tokens)
  private pricing = {
    'claude-3-5-sonnet-20241022': { input: 3.00, output: 15.00 },
    'claude-3-5-haiku-20241022': { input: 0.80, output: 4.00 },
    'claude-3-opus-20240229': { input: 15.00, output: 75.00 },
  };

  track(usage: Anthropic.Usage, model: string): CostMetrics {
    const prices = this.pricing[model];

    const metrics: CostMetrics = {
      inputTokens: usage.input_tokens,
      outputTokens: usage.output_tokens,
      inputCost: (usage.input_tokens / 1_000_000) * prices.input,
      outputCost: (usage.output_tokens / 1_000_000) * prices.output,
      totalCost: 0,
      model
    };

    metrics.totalCost = metrics.inputCost + metrics.outputCost;
    this.costs.push(metrics);

    return metrics;
  }

  getTotalCost(): number {
    return this.costs.reduce((sum, c) => sum + c.totalCost, 0);
  }

  getCostByModel(model: string): number {
    return this.costs
      .filter(c => c.model === model)
      .reduce((sum, c) => sum + c.totalCost, 0);
  }

  getAverageCostPerRequest(): number {
    return this.getTotalCost() / this.costs.length;
  }
}

// Usage
const tracker = new CostTracker();

const response = await claude.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  messages: [...]
});

const cost = tracker.track(response.usage, response.model);
console.log(`Request cost: $${cost.totalCost.toFixed(4)}`);
console.log(`Total spent: $${tracker.getTotalCost().toFixed(2)}`);
```

### 2. Analytics Daemon Integration

The `@claude-code-plugins/analytics-daemon` emits cost events:

```typescript
// WebSocket event from analytics daemon
interface CostUpdateEvent {
  type: 'cost.update';
  timestamp: number;
  conversationId: string;
  model: 'claude-3-5-sonnet-20241022';
  inputCost: 0.0045;
  outputCost: 0.012;
  totalCost: 0.0165;
  currency: 'USD';
}

// Monitor costs in real-time
const ws = new WebSocket('ws://localhost:3456');
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.type === 'cost.update') {
    updateBudget(data.totalCost);
  }
};
```

### 3. Daily Budget Dashboard

Query costs via HTTP API:

```bash
# Get session costs
curl http://localhost:3333/api/sessions | jq '.sessions[] | {id, plugins, totalCost}'

# Get status including total spend
curl http://localhost:3333/api/status | jq '.watcher'
```

---

## Budget Enforcement

### Strategy 1: Hard Caps with Circuit Breakers

```typescript
class BudgetEnforcer {
  private spent = 0;
  private dailyBudget: number;
  private lastReset: Date;

  constructor(dailyBudgetUSD: number) {
    this.dailyBudget = dailyBudgetUSD;
    this.lastReset = new Date();
  }

  async executeWithBudget<T>(
    fn: () => Promise<{ result: T; cost: number }>
  ): Promise<T> {
    // Reset budget if new day
    if (this.isNewDay()) {
      this.spent = 0;
      this.lastReset = new Date();
    }

    // Check budget before execution
    if (this.spent >= this.dailyBudget) {
      throw new Error(
        `Daily budget exceeded: $${this.spent.toFixed(2)} / $${this.dailyBudget}`
      );
    }

    const { result, cost } = await fn();

    this.spent += cost;

    // Warn at 80%
    if (this.spent >= this.dailyBudget * 0.8) {
      console.warn(
        `⚠️ 80% of daily budget used: $${this.spent.toFixed(2)} / $${this.dailyBudget}`
      );
    }

    return result;
  }

  private isNewDay(): boolean {
    const now = new Date();
    return now.toDateString() !== this.lastReset.toDateString();
  }

  getRemainingBudget(): number {
    return Math.max(0, this.dailyBudget - this.spent);
  }

  getSpendPercentage(): number {
    return (this.spent / this.dailyBudget) * 100;
  }
}

// Usage
const budget = new BudgetEnforcer(50.00); // $50/day

try {
  await budget.executeWithBudget(async () => {
    const response = await claude.messages.create(...);
    const cost = calculateCost(response.usage);
    return { result: response, cost };
  });
} catch (error) {
  // Budget exceeded - halt operations
  console.error('Budget exhausted for today');
}
```

### Strategy 2: Tiered Budgets by Priority

```typescript
enum Priority {
  CRITICAL = 'critical',  // $100/day
  HIGH = 'high',          // $50/day
  MEDIUM = 'medium',      // $20/day
  LOW = 'low'             // $5/day
}

class TieredBudget {
  private budgets = new Map<Priority, BudgetEnforcer>([
    [Priority.CRITICAL, new BudgetEnforcer(100)],
    [Priority.HIGH, new BudgetEnforcer(50)],
    [Priority.MEDIUM, new BudgetEnforcer(20)],
    [Priority.LOW, new BudgetEnforcer(5)],
  ]);

  async execute<T>(
    priority: Priority,
    fn: () => Promise<{ result: T; cost: number }>
  ): Promise<T> {
    const budget = this.budgets.get(priority)!;
    return await budget.executeWithBudget(fn);
  }

  getStatus() {
    return Array.from(this.budgets.entries()).map(([priority, budget]) => ({
      priority,
      spent: budget.getSpendPercentage().toFixed(1) + '%',
      remaining: '$' + budget.getRemainingBudget().toFixed(2)
    }));
  }
}

// Usage
const tiered = new TieredBudget();

// Critical: Production incident debugging
await tiered.execute(Priority.CRITICAL, async () => {
  const result = await debugIncident();
  return { result, cost: 0.50 };
});

// Low: Non-urgent code reviews
await tiered.execute(Priority.LOW, async () => {
  const result = await reviewCode();
  return { result, cost: 0.05 };
});
```

### Strategy 3: Per-User Quotas

```typescript
class UserQuotaManager {
  private userBudgets = new Map<string, number>();
  private userSpent = new Map<string, number>();

  constructor(private defaultQuota: number = 10) {}

  setQuota(userId: string, quotaUSD: number) {
    this.userBudgets.set(userId, quotaUSD);
  }

  async executeForUser<T>(
    userId: string,
    fn: () => Promise<{ result: T; cost: number }>
  ): Promise<T> {
    const quota = this.userBudgets.get(userId) || this.defaultQuota;
    const spent = this.userSpent.get(userId) || 0;

    if (spent >= quota) {
      throw new Error(
        `User ${userId} quota exceeded: $${spent.toFixed(2)} / $${quota}`
      );
    }

    const { result, cost } = await fn();
    this.userSpent.set(userId, spent + cost);

    return result;
  }

  getUserStatus(userId: string) {
    const quota = this.userBudgets.get(userId) || this.defaultQuota;
    const spent = this.userSpent.get(userId) || 0;

    return {
      userId,
      quota: `$${quota}`,
      spent: `$${spent.toFixed(2)}`,
      remaining: `$${(quota - spent).toFixed(2)}`,
      percentage: `${((spent / quota) * 100).toFixed(1)}%`
    };
  }
}
```

---

## Optimization Strategies

### 1. Model Selection by Task

```typescript
// Cost comparison for 10K token input + 1K token output

const models = {
  sonnet: {
    input: (10_000 / 1_000_000) * 3.00,   // $0.03
    output: (1_000 / 1_000_000) * 15.00,  // $0.015
    total: 0.045                           // $0.045
  },
  haiku: {
    input: (10_000 / 1_000_000) * 0.80,   // $0.008
    output: (1_000 / 1_000_000) * 4.00,   // $0.004
    total: 0.012                           // $0.012 (73% cheaper!)
  },
  opus: {
    input: (10_000 / 1_000_000) * 15.00,  // $0.15
    output: (1_000 / 1_000_000) * 75.00,  // $0.075
    total: 0.225                           // $0.225 (5x more expensive)
  }
};

// Smart model selection
function selectModel(task: AgentTask): string {
  if (task.requiresReasoning) {
    return 'claude-3-5-sonnet-20241022'; // Best reasoning
  } else if (task.isSimple) {
    return 'claude-3-5-haiku-20241022';  // 73% cost savings
  } else {
    return 'claude-3-5-sonnet-20241022'; // Default
  }
}

// Real savings example:
// 1000 simple tasks/day × $0.045 (Sonnet) = $45/day
// 1000 simple tasks/day × $0.012 (Haiku) = $12/day
// Savings: $33/day = $990/month
```

### 2. Context Window Optimization

```typescript
// ❌ Expensive: Send entire codebase every time
async function reviewFile(file: string, codebase: string) {
  return await claude.messages.create({
    model: 'claude-3-5-sonnet-20241022',
    messages: [{
      role: 'user',
      content: `Codebase context:\n${codebase}\n\nReview:\n${file}` // 100K + 5K tokens
    }]
  });
}
// Cost per call: 100K tokens × $3/1M = $0.30

// ✅ Optimized: Send only relevant context
async function reviewFileOptimized(file: string, relatedFiles: string[]) {
  const context = relatedFiles.join('\n'); // 10K tokens
  return await claude.messages.create({
    model: 'claude-3-5-sonnet-20241022',
    messages: [{
      role: 'user',
      content: `Related files:\n${context}\n\nReview:\n${file}` // 10K + 5K tokens
    }]
  });
}
// Cost per call: 15K tokens × $3/1M = $0.045 (85% cheaper!)
```

### 3. Caching Strategy

```typescript
class ResponseCache {
  private cache = new Map<string, { response: any; cost: number; timestamp: number }>();
  private ttl = 3600000; // 1 hour

  async execute<T>(
    cacheKey: string,
    fn: () => Promise<{ result: T; cost: number }>
  ): Promise<{ result: T; cost: number; cached: boolean }> {
    const cached = this.cache.get(cacheKey);

    if (cached && Date.now() - cached.timestamp < this.ttl) {
      console.log(`Cache hit: $${cached.cost.toFixed(4)} saved`);
      return { result: cached.response, cost: 0, cached: true };
    }

    const { result, cost } = await fn();

    this.cache.set(cacheKey, {
      response: result,
      cost,
      timestamp: Date.now()
    });

    return { result, cost, cached: false };
  }

  getCacheStats() {
    const entries = Array.from(this.cache.values());
    return {
      entries: entries.length,
      totalSavings: entries.reduce((sum, e) => sum + e.cost, 0),
      hitRate: 0 // Track separately
    };
  }
}

// Usage
const cache = new ResponseCache();

const { result, cost, cached } = await cache.execute(
  `code-review-${fileHash}`,
  async () => {
    const response = await claude.messages.create(...);
    return { result: response, cost: calculateCost(response.usage) };
  }
);

// Real impact:
// 100 requests/day, 30% cache hit rate
// Without cache: 100 × $0.045 = $4.50/day
// With cache: 70 × $0.045 = $3.15/day
// Savings: $1.35/day = $40.50/month
```

### 4. Batch Processing

```typescript
// ❌ Process files individually
async function reviewFiles(files: string[]) {
  for (const file of files) {
    await claude.messages.create({
      messages: [{ role: 'user', content: `Review: ${file}` }]
    });
  }
}
// Cost: 10 files × $0.045 = $0.45

// ✅ Batch process
async function reviewFilesBatch(files: string[]) {
  const batches = chunk(files, 10); // 10 files per batch

  for (const batch of batches) {
    await claude.messages.create({
      messages: [{
        role: 'user',
        content: `Review these files:\n${batch.map((f, i) => `${i+1}. ${f}`).join('\n')}`
      }]
    });
  }
}
// Cost: 1 batch × $0.05 = $0.05 (90% cheaper!)
```

---

## Production Examples

### Example 1: Plugin Marketplace Review

```typescript
// Scenario: Review 258 plugins for security issues
// Average plugin size: 5K tokens
// Total tokens: 258 × 5K = 1.29M tokens

const budget = new BudgetEnforcer(10.00); // $10 budget
const cache = new ResponseCache();
const tracker = new CostTracker();

async function reviewPlugins() {
  const plugins = await getPlugins(); // 258 plugins
  const results = [];

  for (const plugin of plugins) {
    try {
      await budget.executeWithBudget(async () => {
        const { result, cost, cached } = await cache.execute(
          `security-review-${plugin.id}`,
          async () => {
            const response = await claude.messages.create({
              model: 'claude-3-5-haiku-20241022', // Use cheaper model
              max_tokens: 500,
              messages: [{
                role: 'user',
                content: `Security review:\n${plugin.code}`
              }]
            });

            const metrics = tracker.track(response.usage, response.model);
            return { result: response, cost: metrics.totalCost };
          }
        );

        results.push({ plugin: plugin.name, review: result, cached });
        return { result, cost };
      });
    } catch (error) {
      console.error(`Budget exceeded at plugin ${plugin.name}`);
      break;
    }
  }

  return results;
}

// Real metrics:
// - Cost without optimization: 258 × $0.045 = $11.61 (exceeds budget)
// - Cost with Haiku: 258 × $0.012 = $3.10 (73% savings)
// - Cost with 50% cache: 129 × $0.012 = $1.55 (87% savings)
// - Plugins reviewed: 258 (all)
// - Budget remaining: $8.45
```

### Example 2: Cost Attribution by Team

```typescript
interface Team {
  name: string;
  members: string[];
  monthlyBudget: number;
}

class TeamBudgetManager {
  private teams = new Map<string, Team>();
  private teamSpend = new Map<string, number>();

  addTeam(team: Team) {
    this.teams.set(team.name, team);
    this.teamSpend.set(team.name, 0);
  }

  async executeForTeam<T>(
    teamName: string,
    userId: string,
    fn: () => Promise<{ result: T; cost: number }>
  ): Promise<T> {
    const team = this.teams.get(teamName);
    if (!team) throw new Error(`Unknown team: ${teamName}`);
    if (!team.members.includes(userId)) {
      throw new Error(`User ${userId} not in team ${teamName}`);
    }

    const spent = this.teamSpend.get(teamName) || 0;
    if (spent >= team.monthlyBudget) {
      throw new Error(`Team ${teamName} budget exceeded`);
    }

    const { result, cost } = await fn();
    this.teamSpend.set(teamName, spent + cost);

    return result;
  }

  getTeamReport(teamName: string) {
    const team = this.teams.get(teamName)!;
    const spent = this.teamSpend.get(teamName) || 0;

    return {
      team: teamName,
      members: team.members.length,
      budget: `$${team.monthlyBudget}`,
      spent: `$${spent.toFixed(2)}`,
      remaining: `$${(team.monthlyBudget - spent).toFixed(2)}`,
      percentageUsed: `${((spent / team.monthlyBudget) * 100).toFixed(1)}%`,
      daysRemaining: 30 - new Date().getDate(),
      projectedOverage: spent / new Date().getDate() * 30 > team.monthlyBudget
    };
  }
}

// Usage
const manager = new TeamBudgetManager();

manager.addTeam({
  name: 'Engineering',
  members: ['alice@example.com', 'bob@example.com'],
  monthlyBudget: 500
});

manager.addTeam({
  name: 'QA',
  members: ['charlie@example.com'],
  monthlyBudget: 100
});

// Engineering team member makes request
await manager.executeForTeam('Engineering', 'alice@example.com', async () => {
  const result = await runTests();
  return { result, cost: 2.50 };
});

console.log(manager.getTeamReport('Engineering'));
// {
//   team: 'Engineering',
//   members: 2,
//   budget: '$500',
//   spent: '$2.50',
//   remaining: '$497.50',
//   percentageUsed: '0.5%',
//   daysRemaining: 7,
//   projectedOverage: false
// }
```

---

## ROI Analysis

### Cost vs. Value Metrics

```typescript
interface WorkflowMetrics {
  name: string;
  costPerRun: number;
  timesSaved: number;    // minutes
  errorsPrevented: number;
  manualCost: number;    // $ per hour equivalent
}

function calculateROI(metrics: WorkflowMetrics): number {
  const timeSavingsValue = (metrics.timesSaved / 60) * metrics.manualCost;
  const errorCostSavings = metrics.errorsPrevented * 100; // $100 per error

  const totalValue = timeSavingsValue + errorCostSavings;
  const totalCost = metrics.costPerRun;

  return ((totalValue - totalCost) / totalCost) * 100;
}

// Example: Automated Code Review
const codeReviewMetrics: WorkflowMetrics = {
  name: 'Automated Code Review',
  costPerRun: 0.50,           // Claude API cost
  timesSaved: 30,              // 30 minutes saved
  errorsPrevented: 3,          // 3 bugs caught
  manualCost: 100              // $100/hour developer time
};

const roi = calculateROI(codeReviewMetrics);
// timeSavingsValue: (30/60) × $100 = $50
// errorCostSavings: 3 × $100 = $300
// totalValue: $350
// totalCost: $0.50
// ROI: (($350 - $0.50) / $0.50) × 100 = 69,900%

console.log(`ROI: ${roi.toFixed(0)}%`); // 69,900% ROI
```

### Break-Even Analysis

| Workflow | API Cost/Run | Manual Cost/Run | Runs to Break Even |
|----------|--------------|-----------------|-------------------|
| Code Review | $0.50 | $50 | 1 |
| Test Generation | $2.00 | $200 | 1 |
| Documentation | $1.00 | $80 | 1 |
| Bug Triage | $0.25 | $25 | 1 |

**Key Insight**: Even "expensive" AI workflows pay for themselves in the first run.

---

## Best Practices

### DO ✅

1. **Track every API call**
   ```typescript
   const tracker = new CostTracker();
   // Log costs to analytics daemon
   ```

2. **Set hard budget limits**
   ```typescript
   const budget = new BudgetEnforcer(50); // Never exceed $50/day
   ```

3. **Use model selection**
   ```typescript
   const model = task.isComplex ? 'sonnet' : 'haiku'; // 73% savings
   ```

4. **Cache responses**
   ```typescript
   const cache = new ResponseCache();
   // 30% cache hit rate = 30% cost savings
   ```

5. **Monitor in real-time**
   ```bash
   ccp-analytics  # Watch costs live
   ```

### DON'T ❌

1. **Don't use Opus for everything**
   ```typescript
   // ❌ 5x more expensive than Sonnet
   model: 'claude-3-opus-20240229'
   ```

2. **Don't send full codebase every time**
   ```typescript
   // ❌ Wastes 90% of tokens
   content: fs.readFileSync('entire-repo.txt')
   ```

3. **Don't ignore token usage**
   ```typescript
   // ❌ No cost tracking
   await claude.messages.create({...});
   ```

4. **Don't run without budgets**
   ```typescript
   // ❌ Unlimited spending = surprise bills
   while (true) { await expensiveCall(); }
   ```

---

## Tools & Resources

### Analytics Daemon
Monitor costs in real-time:
```bash
cd packages/analytics-daemon
pnpm start
# Cost events: ws://localhost:3456
# Cost API: http://localhost:3333/api/status
```

### Anthropic Dashboard
Official cost tracking: [console.anthropic.com](https://console.anthropic.com/)

### Plugins with Built-in Cost Optimization
- `performance-engineer` - Automatic model selection
- `cost-optimizer` - Budget tracking
- `cache-manager` - Response caching

---

## Summary

**Key Takeaways**:

1. **Sonnet**: $3/1M input, $15/1M output - Production standard
2. **Haiku**: 73% cheaper - Use for simple tasks
3. **Context optimization**: 85% cost savings
4. **Caching**: 30% cost savings
5. **Budget enforcement**: Prevents runaway costs

**Cost Control Checklist**:
- [ ] Implement CostTracker
- [ ] Set daily budget limits
- [ ] Use Haiku for simple tasks
- [ ] Optimize context windows
- [ ] Enable response caching
- [ ] Monitor with analytics daemon
- [ ] Calculate ROI for workflows
- [ ] Set up team quotas

---

**Last Updated**: 2025-12-24
**Author**: Jeremy Longshore
**Related Playbooks**: [Multi-Agent Rate Limits](./01-multi-agent-rate-limits.md), [Performance Optimization](./08-performance-optimization.md)

Files in this skill

  • README.md937 B
  • skill.md20.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.