# OpenCode Cost Tracking — Local Metering and the Proxy, Explained

opencode computes cost per call but never persists it. Two paths fix that: zero-credential local SQLite metering and the ACP proxy, priced server-side.

<div class="acp-shot-frame">
<img src="/assets/img/screenshots/session-trace-dark.png" alt="An ACP session trace: each model call priced with its token and cached-token counts, interleaved with the tool calls it drove — the cost X-ray for one run" style="width:100%;height:auto;border:1px solid var(--line-2);border-radius:10px;box-shadow:0 20px 50px -24px rgba(0,0,0,0.9);margin:8px 0;" />
</div>

<div style="margin:8px 0 28px;padding:20px 22px;border:1px solid var(--line-2);border-radius:12px;background:var(--color-accent-light,#f0effe);">
  <p style="margin:0 0 12px;font-size:15px;line-height:1.6;color:var(--acp-text);"><strong>Just want the answer?</strong> Local metering needs no account and starts recording the moment the plugin is installed:</p>
  <pre data-track="OpenCodeCost: Hero Config Copy" style="margin:0 0 12px;background:var(--color-surface,#faf9ff);border:1px solid var(--line-2);border-radius:8px;padding:12px 14px;overflow-x:auto;"><code>curl -sf https://agenticcontrolplane.com/install.sh | bash
npx acp-opencode report   # spend by model, cache hit rate, per-task cost</code></pre>
  <p style="margin:0 0 12px;font-size:15px;line-height:1.6;color:var(--acp-text);">For priced spend on the team dashboard, add the ACP proxy as a provider in <code>opencode.json</code> and set it as your model — see the config below.</p>
  <p style="margin:0;font-size:13px;color:var(--acp-text-dim);"><a href="/integrations/opencode" data-track="OpenCodeCost: Install Guide" style="font-weight:600;">Full opencode install guide →</a> &nbsp;·&nbsp; <a href="/cost-tracking" data-track="OpenCodeCost: Cost Xray Page">Turn on Cost X-Ray →</a> &nbsp;·&nbsp; free up to 5 agents</p>
</div>

opencode already computes a cost for every model call — it reads token counts off the response and prices them against its own [models.dev](https://opencode.ai) pricing data, in-process, no configuration required. What it doesn't do is keep that number anywhere. Close the terminal and the session's spend is gone with it; there's no cross-session total, no per-task breakdown, no team view. This is the reference for the two real ways to make opencode's cost data durable: a local SQLite database that needs no account, and a proxy that prices spend server-side and puts it on a dashboard.

## What opencode computes, and what it doesn't keep

Every LLM request opencode makes emits a `step-finish` part carrying that call's token buckets — input, output, cache read, cache write — and the cost opencode itself derived from its pricing data. That's a real, per-call price, not an estimate padded from a total. But it lives only in the running session's state. There's no file it's written to, no database, no history to query once the terminal closes. If you want to know what last Tuesday's session cost, or which task in a long session was the expensive one, native opencode has nothing to show you.

## Path one: local SQLite metering, zero credentials

`acp-opencode`'s `event` hook taps opencode's event bus directly and writes every model call and every tool call to SQLite at `~/.acp/opencode-local.db` (override with `ACP_LOCAL_DB`). This runs whether or not you've ever configured a workspace credential — local metering and policy enforcement are independent, and metering works with neither an account nor a network connection.

Two tables carry the record:

- **`model_calls`** — one row per LLM API request: model, provider, mode, input/output/reasoning tokens, cache read/write tokens, cost, and session/task/turn ids for grouping.
- **`tool_calls`** — one row per tool execution: tool name, status (`ok`/`error`), duration, result size.

Read it back with the bundled CLI:

```bash
npx acp-opencode report            # spend by model, cache hit rate, tool errors, per-task cost
npx acp-opencode report --json     # machine-readable — an agent can read its own economics
npx acp-opencode report --days 30  # widen the window (default 7)
```

(Install globally with `npm install -g acp-opencode` and the `acp-opencode` command is on PATH directly.)

**Pricing honesty is the point of this path.** The plugin maintains no price table of its own — every dollar figure comes straight from opencode's in-process pricing. When opencode reports a cost of zero (an unknown model, or subscription-included auth with no per-call price), the row is stored with `cost_usd` left `NULL` rather than a guessed number, and the report surfaces it plainly as "N calls have no price." Token counts stay exact either way. Turn local metering off entirely with `export ACP_LOCAL_METERING=off` (also accepts `0` / `false` / `disabled`); it also fails open on its own — a storage error disables it for the session with one warning rather than interrupting the agent.

**What this path is missing**, honestly: opencode 1.18.4 exposes the outgoing message array only through an unstable `experimental.chat.messages.transform` hook, so context composition — how much of a prompt was system, user, prior assistant turns, versus tool output — isn't populated. And per-request API duration isn't exposed per step; only message-level fallback rows carry wall-clock timing, with step rows recording zero. Both gaps are covered by the proxy path below for traffic routed through it.

## Path two: the ACP proxy, priced server-side

Local metering runs on your machine and stays there — useful, but per-developer and dashboard-free. The **cost X-ray** puts priced spend, prompt-cache hit rate, and the loop-vs-leaf breakdown on the team console instead, metered server-side rather than read back from a local file. Reach it by adding the proxy as an opencode model provider:

```json
// ~/.config/opencode/opencode.json
{
  "provider": {
    "acp": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Agentic Control Plane",
      "options": {
        "baseURL": "https://api.agenticcontrolplane.com/v1",
        "apiKey": "{env:ACP_BEARER_TOKEN}"
      },
      "models": { "gemini-3.5-flash": {} }
    }
  },
  "model": "acp/gemini-3.5-flash"
}
```

This is opt-in by design — it changes which model backend the request actually goes to, so it isn't something the installer does for you automatically. The proxy is multi-provider: it routes by model id (`gpt-*`, `claude-*`, `gemini-*`, and others) and forwards the request to the real provider unchanged, so responses are identical — only now the call is metered on the way through. The plugin's `chat.headers` hook stamps `X-GS-Session` on every model request regardless of which path handles cost, which is what ties proxy-priced spend to the tool-call audit rows for that same session on the dashboard — one view of what ran and what it cost, not two separate exports to reconcile by hand.

## Choosing between the two

They're not competing — they answer different questions. Local metering is the right first step: no account, no network dependency, works the moment the plugin is installed, and it's the only path that sees a call whose provider opencode itself has no price for (it just records the tokens instead of guessing). The proxy is the right step when you want that spend on a team dashboard, joined to the audit trail for the tool calls in the same session, with authoritative per-request duration for routed traffic — the two gaps local metering can't close until opencode ships a stable hook for them.

## Related links

- [/integrations/opencode](/integrations/opencode) — the install guide, both metering paths, and troubleshooting
- [/controls/opencode](/controls/opencode) — the permission-system reference
- [OpenCode permissions and hooks reference](/blog/opencode-hooks-reference) — the policy-side hooks, `permission.ask` and the backstop
- [Claude Code cost tracking reference](/blog/claude-code-cost-tracking-reference) — the transcript-priced equivalent for Claude Code
- [Codex cost tracking](/blog/codex-cli-cost-tracking) — the same question for Codex CLI
- [Turn on Cost X-Ray](/cost-tracking) — the proxy path across any harness

## Frequently asked questions



<!-- Sources: https://opencode.ai (opencode project, pricing data source models.dev); agenticcontrolplane.com/integrations/opencode and agenticcontrolplane.com/cost-tracking.md (this site's own reference and install pages, including the reused hero screenshot alt text); https://github.com/agentic-control-plane/opencode-acp-plugin (plugin source and README, cross-checked against the above) -->
