Practical notes on APIs, infrastructure, AI, integrations, developer tooling, and everything else we learn while building reliable products.

The client-side half of the 429 problem, measured: honoring Retry-After, exponential backoff with jitter, retry budgets, and the cases where retrying is simply the wrong move.

Sorower

The SecurityFilterChain setup that actually compiles on Spring Security 7, tested with curl, plus the measured per-request cost of HTTP Basic and the honest case for API keys on machine-to-machine traffic.
Sorower
Four ways to charge for an API, priced against rate cards read this week, each with the counter it forces you to build. Plus the break-even arithmetic that decides whether success-based pricing can work at all.
Sorower
A block isn't an error your API produced, it's another layer answering on its behalf. How to tell a WAF rule from a rate limit from a disabled key, using only what comes back in the response.
Sorower
Rotation, regeneration and revocation are three different operations, and only one of them keeps your traffic alive. What rotation actually means, how to pick a schedule you can defend, and what has to be true about a provider's API before any of it can be automated.
Sorower
The message never means your API key was rejected. It means nothing read it. Seven causes reproduced on one Spring Boot app, each with the curl that triggers it.
Sorower
A measured trace of every Fastify hook, which one your API key check belongs in, and what actually runs when a request never reaches your handler.
Sorower
An API credit is a unit of consumption the provider defines, not a rebranded request. Here is what limit, remaining, refill and overage actually mean, why one endpoint costs 1 credit and another 250, and what a failed request does to your balance.
Sorower
The plugin works in five lines, then quietly skips your earlier routes, your 404s, your other instances, and your second limiter. Five gaps, measured on Fastify 5.11.3.
Sorower
Next.js 16 renamed middleware.ts to proxy.ts. Here is the exact warning, the one command that migrates most projects, the case where that command silently does nothing, and where your API key check belongs afterwards.
Sorower
Google's deleted API keys kept working for up to 23 minutes. We measured what actually sets that window across eight independent caches, and why the number most teams would guess is half the real one.
Sorower
Run dotnet new webapi on .NET 10 and you get Minimal APIs with no controllers. The API key filter attribute every tutorial hands you does nothing there, and nothing warns you.
Sorower
The received wisdom is that a checksum lets you reject bad API keys without hitting your database. I benchmarked it, and the saving is not where anyone says it is.
Sorower
Your per-customer rate limiter sits behind authentication, so it never counts the requests you most want to stop. Here is the measurement, the fix, and the paying customer the fix locks out.
Sorower
Registering your API key check as a Fastify plugin can protect nothing outside that plugin. Three traps measured on Fastify 5.11.2, and what to do about each.
Sorower
The negative matcher in the Next.js docs excludes /api, so a key check in proxy.ts never runs on your API routes. Measured on Next.js 16.2.12, plus where the check actually belongs.
Sorower
Most “Unkey alternatives” lists hand you a reverse proxy and call it a swap. Here is what each option actually replaces, what it costs, and how much you would have to rewrite.
Sorower
The twelve-line Axum auth middleware works. Then route_layer quietly hands strangers a route scanner, and ServiceBuilder reverses your layer order. Four probes against Axum 0.8.9.
Sorower
A brand-new customer's very first API call came back 429, because somebody else had already spent the bucket from the same IP address. Four frameworks, four probes, and the fix for each.
Sorower
A fresh Laravel 13 install ships no routes/api.php. Then it gets worse: your throttle middleware runs before your API key middleware, so every customer shares an IP bucket.
Sorower
bcrypt turns API key lookup into a full table scan, and past 72 bytes it will verify the wrong key as the right one. Both failures measured, plus the pattern that replaces it and how to migrate when you can't rehash.
Sorower
Every NestJS tutorial puts API key validation in a guard and stops there. The layer you pick decides your status codes, your usage bill, and whether a stranger can map your routes.
Sorower
Checking an API key in a DRF permission class leaves request.user anonymous on a 200 response, which quietly turns your per-customer rate limit into a per-IP one. Here is the authentication class that fixes it, and the 401 you are probably returning as a 403.
Sorower
Declaring your API key filter as a @Bean registers it twice: once in your security chain and once with the servlet container. Measured results, the four-line fix, and the four things that break after your first customer.
Sorower
Most API pricing posts hand you a taxonomy of models and stop before the arithmetic. This is the seller's side: cost per route, the credit unit, whole-number weights, and the one margin number that actually protects you.
Sorower
The twelve-line API key middleware everyone ships is fine until customer number two. Here is what to build after it in Go, including the ResponseWriter wrapper that silently breaks streaming and the route label your auth layer cannot see.
Sorower
Six platforms priced against the same one million API requests a month, from each vendor's own page: Unkey, Kong, Zuplo, Moesif, Treblle and ReqKey. Same traffic, a 46x spread in bills.
Sorower
Every Express API key tutorial stops at an array of strings and a comparison. Here are the three Express-specific traps that break it before you reach the database, and the four things it needs to survive real customers.
Sorower
Every FastAPI API key tutorial ends at a hardcoded list and a warning not to ship it. This is the next paragraph: storage, lookup, revocation, and the FastAPI 0.122.0 change that breaks the tests those tutorials teach you to write.
Sorower
OAuth hands your MCP server a verified subject claim. It does not hand you a counter. What to meter, where to hang it, and why the model on the other end never sees your 429.
Sorower
Credits are deducted at the gate, before your handler runs. That one structural fact drives every refund ticket, double-charge and reconciliation gap in a metered API. Here is the policy, the code and the honest trade-offs.
Sorower
A Redis failover took eleven seconds. The API returned 500s for four minutes. Most teams never chose what their rate limiter does when its store is unreachable, and the ones who did chose it once, globally, for routes that need different answers.
Sorower
A customer on a 1,000-credit plan had somehow used 4,300, and nothing was broken. Where a multi-tenant API quota lives (the key, the user, or the account) decides what you can bill and what a key rotation breaks.
Sorower
Most 429 responses ship a bare status code and a guessed Retry-After. Here is what the header should actually say, the RateLimit fields that replaced the old three-header pattern, and when a 402 is the more honest answer.
Sorower
Most API key rotation advice is written for the side that consumes the key. This is the other side: how to rotate a key you issued to a customer, prove it is safe to revoke, and keep their usage balance intact.
Sorower
Most Redis rate-limiter tutorials embed the Lua in a Node or Python client. Here's the atomic sliding-window version — and how to run it at the edge in OpenResty, where a limiter belongs.
Sorower