KKKim Kakiiza
All posts
BACKEND · ARCHITECTUREMay 13, 20262026

Metering an API Platform Without Surprises

How I think about request counting, rate limits, and billing boundaries for a usage-based API platform built on FastAPI and Redis.

A usage-based API product lives or dies on one promise: the number on the invoice matches the number of requests the customer actually made. That sounds obvious. It is also the hardest part to get right, because counting is a distributed systems problem wearing a billing costume.

Three Numbers, Not One

Early on I stopped thinking about "usage" as a single value. There are three:

  1. The rate-limit counter — short-lived, per key, used to allow or reject a request right now.
  2. The usage counter — durable, per key, per billing period, used to build the invoice.
  3. The audit log — append-only, used when a customer disputes either of the above.

They have different durability needs, so they get different storage. Conflating them is how platforms end up unable to explain a charge.

Redis For The Hot Path

Rate limiting and live usage counting both happen on every request, so they run on Redis with atomic increments. The key design is boring on purpose:

ratelimit:{api_key}:{window}   -> INCR, short TTL
usage:{api_key}:{period}       -> INCR, no TTL until period rollover

Atomic INCR means concurrent requests cannot lose a count to a race. The rate-limit key expires on its own. The usage key is reconciled into durable storage on a schedule, not trusted as the only source of truth.

The Billing Boundary

The rule I follow: Redis is fast, the database is right. Redis holds the live count for speed, but the billing job reads from a durable, idempotent ledger. If Redis is flushed, the invoice does not change — it is rebuilt from the ledger.

That boundary is what makes the platform honest. The fast path can fail without the money being wrong.

Idempotency Everywhere

Every write that touches money carries an idempotency key. A retried request, a duplicated webhook, a client that fires twice on a flaky connection — none of them should double-charge. The platform treats "exactly once" as a property it has to engineer, not assume.

What This Project Is Really About

The API platform is a learning project, but the lesson is general: any system that turns events into money needs a clear story for what is fast, what is durable, and what is provable. Get those three boundaries right and metering stops being scary. Get them wrong and every invoice is an argument.