examples/MCP-tools Public
id: 0003-usage-counts-in-kv
type: decision
owner: justin
reviewed: 2026-10-13
status: accepted
0003 Usage counts in KV
Context
We want to see which tools get called and how often they fail, per day. Exact counting on Workers means a single writer: a Durable Object, or D1. Either adds a component and a hop on every call. KV is already the cheapest storage to bind and read, but it has no atomic increment and writes take time to spread.
Decision
Count in a KV namespace bound as USAGE, one key per tool per UTC day, with a read then a write inside ctx.waitUntil. Store the counts in the key's metadata so /stats reads a day with one list(). Keys expire after 90 days.
Consequences
- No extra hop on the request path, and a KV failure cannot fail a tool call.
- Counts can undercount when the same tool is called many times in the same second. We accept that: the numbers are for spotting trends, not for billing.
- Anything that has to be exact or enforced, such as a per-client limit, needs a single writer: a Durable Object, not this namespace. If counting itself ever needs that, this decision gets superseded.