# How to Analyze and Optimize Agent API Costs: A Complete Guide to Token Tracking

> Analyze and optimize agent API costs effectively. Implement automatic token tracking with TokenCost to monitor LLM usage, calculate real-time expenses, and identify costly models for smarter spending.

- Repository: [Bojie Li/ai-agent-book](https://github.com/bojieli/ai-agent-book)
- Tags: how-to-guide
- Published: 2026-07-26

---

**The most effective way to analyze and optimize agent API costs is to implement automatic token tracking using the TokenCost service, which wraps LLM calls to record usage, calculates real-time costs using LiteLLM pricing data, and provides actionable summaries to identify expensive models and limit runaway spending.**

The `browser-use-rpa` chapter in the **bojieli/ai-agent-book** repository provides a production-ready solution for analyzing and optimizing agent API costs through its lightweight cost-tracking subsystem. This system automatically measures LLM token consumption and converts those counts into precise monetary costs, giving you full visibility into where your budget is being spent.

## Understanding the TokenCost Architecture

The cost-tracking functionality centers around the `TokenCost` class in [`browser_use/tokens/service.py`](https://github.com/bojieli/ai-agent-book/blob/main/browser_use/tokens/service.py), which orchestrates pricing data loading, LLM call wrapping, and usage aggregation. Supporting Pydantic models in [`browser_use/tokens/views.py`](https://github.com/bojieli/ai-agent-book/blob/main/browser_use/tokens/views.py) define the data structures for pricing information, individual usage entries, and aggregated summaries.

### Core Components and Data Models

The system relies on several key classes defined in [`browser_use/tokens/views.py`](https://github.com/bojieli/ai-agent-book/blob/main/browser_use/tokens/views.py):

- **`TokenCostCalculated`** – Stores computed costs including prompt costs, cached read costs, cache creation costs, and completion costs.
- **`ModelPricing`** – Holds per-token pricing for input, output, cache reads, and cache creation (particularly relevant for Anthropic models).
- **`TokenUsageEntry`** – Records a single LLM invocation with model name, timestamp, and token counts.
- **`UsageSummary`** – Aggregates total tokens, total cost, and per-model statistics across all recorded usage.

### Pricing Data Management

The service fetches pricing data from the LiteLLM repository's [`model_prices_and_context_window.json`](https://github.com/bojieli/ai-agent-book/blob/main/model_prices_and_context_window.json) file. This data is cached in the XDG cache directory at `~/.cache/browser_use/token_cost` with timestamped files and a default **24-hour cache duration**.

When `TokenCost.initialize()` is called, the system executes `_load_pricing_data()`, which invokes `_find_valid_cache()` to locate recent cached data. If no valid cache exists within the 24-hour window, `_fetch_and_cache_pricing_data()` pulls fresh data using **httpx**, stores it in a timestamped file (e.g., [`pricing_YYYYMMDD_HHMMSS.json`](https://github.com/bojieli/ai-agent-book/blob/main/pricing_YYYYMMDD_HHMMSS.json)), and prunes old caches automatically.

## Implementing Cost Tracking in Your Agent

To begin analyzing API costs, you must instantiate the `TokenCost` service and register your LLM instances. This process is controlled by the `BROWSER_USE_CALCULATE_COST` environment variable or the explicit `include_cost` parameter.

### Enabling the TokenCost Service

Cost tracking is disabled by default to minimize overhead. Enable it by setting the environment variable or passing the flag directly:

```python
from browser_use.tokens.service import TokenCost

# Option 1: Environment variable

import os
os.environ["BROWSER_USE_CALCULATE_COST"] = "true"

# Option 2: Explicit flag

cost_service = TokenCost(include_cost=True)

```

The `TokenCost.__init__` method reads this configuration to determine whether to perform monetary calculations and sets up internal storage for usage history and registered LLM instances.

### Registering LLM Instances

Once the service is initialized, wrap your LLM using the `register_llm` method. This stores the original LLM's `ainvoke` coroutine and replaces it with a wrapper that automatically records token usage:

```python
from browser_use.llm.base import BaseChatModel

# Initialize your LLM (e.g., OpenAIChat, AnthropicChat)

my_llm: BaseChatModel = ...

# Register with cost tracking

cost_service.register_llm(my_llm)

```

The wrapper guarantees **zero-impact** on LLM functionality while asynchronously logging usage via `add_usage` and firing background tasks to write human-readable logs via `_log_usage`.

## Analyzing Usage and Costs

After your agent completes its tasks, retrieve detailed breakdowns of token consumption and associated costs to identify optimization opportunities.

### Retrieving Usage Summaries

Call `get_usage_summary` to aggregate all recorded entries into a comprehensive report:

```python

# After agent execution

summary = await cost_service.get_usage_summary()

print(f"Total tokens: {summary.total_tokens}")
print(f"Total cost: ${summary.total_cost:.4f}")

# Per-model breakdown

for model_name, stats in summary.by_model.items():
    print(f"{model_name}: {stats.total_tokens} tokens → ${stats.cost:.4f}")

```

This method processes the in-memory list of `TokenUsageEntry` objects, optionally calculating costs on-the-fly using the loaded pricing data, and returns a `UsageSummary` containing total tokens, total cost, and per-model statistics.

### Interpreting Cost Breakdowns

The `calculate_cost` method (called internally by the tracking system) computes four distinct cost components:

1. **New prompt cost** – Uncached prompt tokens × `input_cost_per_token`
2. **Cached read cost** – Cached prompt tokens × `cache_read_input_token_cost`
3. **Cache creation cost** – Tokens used to create caches × `cache_creation_input_token_cost`
4. **Completion cost** – Output tokens × `output_cost_per_token`

Monitor the per-model breakdown to identify expensive models (e.g., GPT-4) that might be candidates for replacement with cheaper alternatives where quality requirements permit.

## Optimization Strategies for Production

Implement these practical techniques to keep agent API bills under control while maintaining performance.

### Limiting Agent Steps to Prevent Runaway Costs

Configure a hard ceiling on the number of LLM invocations to prevent infinite loops from consuming unlimited tokens:

```python

# In your agent configuration (see examples/01_basic_task.py)

config = {
    "max_agent_steps": 10,  # Stop after 10 LLM calls

}

```

As shown in [`examples/01_basic_task.py`](https://github.com/bojieli/ai-agent-book/blob/main/examples/01_basic_task.py), this parameter ensures deterministic cost boundaries during both development and production runs.

### Leveraging Prompt Caching

Use LLMs that support prompt caching (such as Anthropic models) and monitor the cached-token breakdown (indicated by `💾` in logs). The `TokenCost` service tracks `cache_read_input_token_cost` separately from standard input costs, typically resulting in significant savings for repeated prompts.

### Managing Pricing Data Freshness

Keep calculations accurate and storage minimal with these maintenance operations:

```python

# Keep only the 2 most recent cache files

await cost_service.clean_old_caches(keep_count=2)

# Force refresh pricing data after model announcements

await cost_service.refresh_pricing_data()

```

The `clean_old_caches` method removes all but the specified number of recent cache files (default is 3), while `refresh_pricing_data` bypasses the cache to fetch current market rates from the LiteLLM repository.

## Summary

- **Enable cost tracking** only during profiling by setting `BROWSER_USE_CALCULATE_COST=true` or passing `include_cost=True` to `TokenCost`.
- **Register LLMs** with `cost_service.register_llm(my_llm)` to automatically wrap all invocations with zero performance impact.
- **Analyze spending** by calling `await cost_service.get_usage_summary()` to review total costs and per-model breakdowns.
- **Prevent runaway costs** by configuring `max_agent_steps` limits in your agent configuration.
- **Optimize with caching** by using models that support prompt caching and monitoring cached read percentages.
- **Maintain freshness** by periodically running `clean_old_caches` and `refresh_pricing_data` to ensure accurate calculations.

## Frequently Asked Questions

### How does TokenCost calculate API costs without impacting LLM performance?

The `register_llm` method in [`browser_use/tokens/service.py`](https://github.com/bojieli/ai-agent-book/blob/main/browser_use/tokens/service.py) stores the original `ainvoke` coroutine and replaces it with a thin wrapper that records usage metadata after the LLM call completes. This design executes the original LLM invocation without modification, then fires asynchronous background tasks to log usage and calculate costs, ensuring **zero latency impact** on the critical path.

### Where does the pricing data come from and how often is it updated?

The system fetches data from the LiteLLM repository's [`model_prices_and_context_window.json`](https://github.com/bojieli/ai-agent-book/blob/main/model_prices_and_context_window.json) file. By default, this data is cached for **24 hours** in `~/.cache/browser_use/token_cost`. The `_find_valid_cache` method validates cache freshness, while `_fetch_and_cache_pricing_data` retrieves updates automatically when the cache expires or when manually triggered via `refresh_pricing_data()`.

### Can I use TokenCost with multiple different LLM providers simultaneously?

Yes. The `TokenCost` service maintains a dictionary of registered LLM instances and aggregates usage across all of them in the `get_usage_summary` method. The `by_model` field in the returned `UsageSummary` object breaks down costs per specific model (e.g., `gpt-4`, `claude-3-opus`), allowing you to compare expenses across different providers in a single analysis.

### How do I prevent my agent from consuming unlimited tokens during debugging?

Always configure the `max_agent_steps` parameter in your agent configuration (as demonstrated in [`examples/01_basic_task.py`](https://github.com/bojieli/ai-agent-book/blob/main/examples/01_basic_task.py)). Additionally, enable cost tracking via the environment variable only during profiling runs—set `BROWSER_USE_CALCULATE_COST=false` in production to avoid the minimal overhead of usage recording when not needed.