Three counters, three questions
| Rate limit | Quota | Billing meter | |
|---|---|---|---|
| Question | Is this caller going too fast right now? | Has this customer used up what their plan includes? | What exactly did this customer consume this month? |
| Window | Seconds to minutes | Day, month, or contract period | Calendar month (the invoice period) |
| Accuracy needed | Approximate is fine; off by 2% nobody notices | Close to exact; visible to the customer | Exact; it is money |
| On breach | 429, retry later | Block, degrade, or flip to overage pricing | Nothing blocks; the invoice grows |
| Lives in | Gateway or middleware, in memory or Redis | Plan logic, backed by the meter or its own counter | A metering pipeline with idempotency and an audit trail |
| Data lifetime | Seconds; forgotten immediately | The period, then reset | Years; disputes and accounting need history |
Why one counter cannot do all three jobs
The rate limiter cannot bill. It is built to be fast and local: sliding windows in memory, token buckets in Redis, approximations everywhere. It forgets on restart, it double-counts across replicas or undercounts during failover, and none of that matters for its job - a 429 a moment early or late is harmless. Send an invoice from that counter and every one of those shortcuts becomes a billing error. There is also a subtlety worth knowing: depending on the provider, even rejected calls can consume something - see does a 429 count against your rate limit.
The billing meter cannot protect infrastructure. Metering pipelines are deliberately asynchronous: events batch, dedupe, and aggregate into rollups on a delay measured in seconds to minutes. That is the right design for money and exactly wrong for stopping a traffic spike that is melting your database right now. By the time the meter shows the burst, the burst already happened.
The quota needs both and is neither. A quota check is a read ("is August usage under 10,000?") that should reflect metered truth, plus an enforcement decision that runs synchronously like a rate limit. The clean architecture: quotas read from the meter's rollups (or a fast counter reconciled against them), and enforce at the gateway. When quota exhaustion should stop spend rather than serve overage, that is a policy choice - the mechanics of hard stops are covered in hard spend caps and usage kill-switches.
The failure modes of conflation
- Billing from the rate limiter. Symptom: invoices disagree with customer logs by a few percent, differently each month. Cause: approximate counters and restarts. Outcome: disputes you lose, because you cannot reproduce the number.
- Enforcing quota from the billing meter alone. Symptom: customers overshoot their plan during the aggregation delay, then either you eat the overage or you bill someone who thought they were capped. Cause: asynchronous pipeline used for a synchronous decision.
- Rate limiting as if it were quota. Symptom: a customer with plenty of monthly allowance gets 429s during a legitimate burst, or a customer with an exhausted plan keeps consuming happily below the per-second ceiling. Cause: per-second and per-month are unrelated dimensions.
What this looks like wired correctly
A request arrives. The gateway checks the rate limit in microseconds and, when relevant, the quota state. The request is served. The application then emits a usage event to the meter: which customer, which meter key, what value. The pipeline dedupes and aggregates it into the month's rollup, the rollup feeds both the invoice and tomorrow's quota reads, and the raw event remains queryable for the day someone asks why August was 12,431. One count becomes three views, each consumed by the system that needs it - the meter is the source of truth, the other two are enforcement caches. This is the same division of labor as the broader API monetization stack and, for LLM traffic specifically, the gateway as your cheapest cost lever.
The meter half of that wiring is what UsageBox provides: an ingestion endpoint for events, per-meter aggregation, monthly rollups queryable by meter and subscription, and the durable record the other two counters can be reconciled against. Your rate limiter stays fast and forgetful, your quota logic stays simple, and the money number has an audit trail.
The honest take
Nobody wins an award for implementing three counters where one "mostly works". The discipline pays off the first time a customer disputes an invoice (the meter answers), the first time a runaway script hits you (the rate limit answers), and the first time a free-tier user finds your expensive endpoint (the quota answers). Different questions, different clocks, different counters. Design meters properly first - here is how - and the other two become thin layers on top of trustworthy data.