# Agent Cost Monitoring with LiteLLM Budgets and Spend Logs

> Track token spend per key, user, and team on a LiteLLM proxy, enforce max_budget caps, and pull spend reports — distinct from tracing/evals.

Category: Multi-Model Routing  
Tags: litellm, cost, budgets, spend tracking, observability  
Setup time (estimate): 45-90 minutes  
Estimated cost: LiteLLM is open source; budgets and spend logs need a Postgres database. You still pay your providers' token prices; see each provider's pricing page. Optional Langfuse hosting or cloud plan if you also track per-trace cost.  
Last verified: 2026-10-15

Use LiteLLM's proxy as the single OpenAI-compatible gateway for your agents, then turn on database-backed spend logs and budgets so each run is attributed and capped. For span-level traces and regression evals, see the [Agent Tracing and Evaluation Setup](/blueprints/agent-observability/) blueprint; this one is about dollars and budgets. For failover routing only, see [LiteLLM Proxy with Fallbacks](/blueprints/litellm-fallback-router/).

## Requirements

- LiteLLM proxy with a Postgres database (`DATABASE_URL`); budgets do not enforce without a DB
- A master key and virtual keys for agents or teams

## config.yaml (spend + global budget)

```yaml
model_list:
  - model_name: chat-default
    litellm_params:
      model: openai/gpt-6-luna
      api_key: os.environ/OPENAI_API_KEY

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  database_url: os.environ/DATABASE_URL

litellm_settings:
  max_budget: 50          # USD across the proxy; example only — pick your own cap
  budget_duration: 30d    # reset window: 30s / 30m / 30h / 30d
```

```bash
export DATABASE_URL=postgresql://<user>:<password>@<host>:<port>/<dbname>
export LITELLM_MASTER_KEY=sk-...
pip install 'litellm[proxy]'
litellm --config config.yaml --port 4000
```

## Per-agent virtual key budget

```bash
curl 'http://0.0.0.0:4000/key/generate' \
  --header "Authorization: Bearer $LITELLM_MASTER_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{"max_budget": 10, "budget_duration": "30d", "metadata": {"tags": ["agent:support-bot"]}}'
```

Point the agent at `http://localhost:4000` with that key. After the key crosses `max_budget`, requests fail until the duration resets (or you raise the budget).

## Attribute spend on each call

```python
import openai

client = openai.OpenAI(
    api_key="sk-<virtual-key>",
    base_url="http://0.0.0.0:4000",
)
response = client.chat.completions.create(
    model="chat-default",
    messages=[{"role": "user", "content": "summarize the ticket"}],
    user="end-customer-id",  # optional customer / end-user id
    extra_body={
        "metadata": {
            "tags": ["agent:support-bot", "run:ticket-4821"]
        }
    },
)
```

Expect `x-litellm-response-cost` on the response headers. Rows land in `LiteLLM_SpendLogs` (key, team, end_user, model, spend, tokens, tags).

## Inspect spend

- UI: open `https://your-proxy/ui` → Usage
- Key / user info: `GET /user/info?user_id=...` or `GET /key/info?key=...`
- Paginated logs: `GET /spend/logs/v2?start_date=...&end_date=...&page=1&page_size=100`
- Daily breakdown: `GET /user/daily/activity?start_date=YYYY-MM-DD&end_date=YYYY-MM-DD`

## Optional: Langfuse for per-trace USD

If you already emit generations to Langfuse, it can record `usage_details` and `cost_details` (or infer cost from model definitions). That complements LiteLLM budgets; it does not replace proxy-side hard caps. See Langfuse's token and cost tracking docs.

## Sources (official docs, checked 2026-10-15)

- [LiteLLM spend tracking](https://docs.litellm.ai/docs/proxy/cost_tracking)
- [LiteLLM budgets and rate limits](https://docs.litellm.ai/docs/proxy/users)
- [LiteLLM virtual keys / DATABASE_URL](https://docs.litellm.ai/docs/proxy/virtual_keys)
- [Langfuse model usage and cost tracking](https://langfuse.com/docs/observability/features/token-and-cost-tracking)
- [OpenAI GPT-6 Luna model](https://developers.openai.com/api/docs/models/gpt-6-luna) (model id used in the sample `model_list`)

## Failure modes

- Budgets fail open without a database: litellm_settings.max_budget is skipped when DATABASE_URL is unset, so spend is not capped.
- Passing user in the request body tracks end-user (customer) spend, not the key owner; set user_id when generating keys if you bill internal users.
- Spend tracked under tags or custom metadata can be incomplete if clients omit metadata; require tags at the key or proxy layer for agent runs.
- This is spend and budget control, not full tracing; pair with the Agent Tracing and Evaluation Setup blueprint when you need spans and evals.
