Decision 0003 Accepted
- Owner
- justin
- Reviewed
- 2026-10-13
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.