[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f16nlhpci9y2os":3},{"_id":4,"slug":5,"title":6,"subtitle":7,"kind":8,"cards":9,"tags":58,"categories":60,"source":62,"lang":65,"author":66,"audioState":69,"stats":70,"publishedAt":73,"renderer":74},"6ab9d6a4ca21c797c7e97245","nestjs-api-quota-management-meet-nestjs-quota-a5539036","NestJS API Quota Management: meet nestjs-quota","If you run a multi-tenant API on NestJS, you probably need more than a rate limiter.","news",[10,13,18,23,28,33,38,43,48,53],{"headline":6,"body":11,"imageUrl":12,"sourceImageUrl":12},"If you run a multi-tenant API on NestJS, you probably need more than a rate limiter. You need to answer \"may this request proceed?\"","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=1200,height=627,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzaj55eg7r16hjoecbmgf.png",{"headline":14,"body":15,"imageUrl":16,"images":17},"against several limits at once (per user per","against several limits at once (per user per minute, per tenant per day, per tenant per month) and \"how much has each tenant actually used?\" for billing and dashboards. nest-quota is an open-source package that does both. nest-quota is an open-source package that does both.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F1.webp",{"local":16},{"headline":19,"body":20,"imageUrl":21,"images":22},"It checks and consumes all the relevant quotas","It checks and consumes all the relevant quotas in one atomic operation, so you never end up with a half-charged request. It works across multiple servers using a single Redis Lua script per decision.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F2.webp",{"local":21},{"headline":24,"body":25,"imageUrl":26,"images":27},"It supports idempotent retries, reserve\u002Fcommit\u002Frelease for operations whose","It supports idempotent retries, reserve\u002Fcommit\u002Frelease for operations whose cost you don't know up front, plan-based dynamic limits, and configurable fail-open or fail-closed behavior. It ships with NestJS decorators, a guard, and an interceptor, and the core has zero runtime dependencies. Redis and NestJS are both optional layers on top. The rest of this post explains why it exists and how it works.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F3.webp",{"local":26},{"headline":29,"body":30,"imageUrl":31,"images":32},"Say you sell an API with three plans","Say you sell an API with three plans. Free gets 10,000 requests a month. Pro gets a million. Enterprise is custom. On top of that, you want to stop any single user from sending more than 100 requests a minute, and stop any single tenant from burning through more than 10,000 in a day. So one incoming request has to be checked against four buckets: The obvious implementation looks like this: This breaks in at least three ways.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F4.webp",{"local":31},{"headline":34,"body":35,"imageUrl":36,"images":37},"Race conditions. Two requests read used = 9999","Race conditions. Two requests read used = 9999 at the same moment, both pass the check, both increment. You just gave away extra usage. With 100 concurrent requests and 10 units left, you can easily let 30 through.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F5.webp",{"local":36},{"headline":39,"body":40,"imageUrl":41,"images":42},"Partial charges. With multiple buckets, you increment the","Partial charges. With multiple buckets, you increment the user\u002Fminute bucket, then discover the tenant\u002Fday bucket is full, and reject. But the user\u002Fminute bucket is already charged for a request that never ran. Now you need rollback logic, and rollback over a network is never truly atomic.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F6.webp",{"local":41},{"headline":44,"body":45,"imageUrl":46,"images":47},"Double charging on retries. A client times out","Double charging on retries. A client times out, retries with the same request, and you charge twice. Your customer notices on their invoice.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F7.webp",{"local":46},{"headline":49,"body":50,"imageUrl":51,"images":52},"On top of that, real APIs have costs","On top of that, real APIs have costs you don't know in advance. An LLM call might use 200 tokens or 8,000. You can only meter that after the handler runs.","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F8.webp",{"local":51},{"headline":54,"body":55,"imageUrl":56,"images":57},"That's the gap. Rate limiting answers \"is this","That's the gap. Rate limiting answers \"is this client too fast?\" Quota enforcement and usage metering answer a different set of questions, and they need real accounting semantics. How nest-quota handles it Atomic multi-policy consumption","\u002Fapi\u002Fmedia\u002Fposts\u002Fnestjs-api-quota-management-meet-nestjs-quota-a5539036\u002F9.webp",{"local":56},[59],"dev",[61],"Technology",{"name":63,"url":64},"Dev.to","https:\u002F\u002Fdev.to\u002Fsilentwatcher_95\u002Fnestjs-api-quota-management-meet-nestjs-quota-2fcd","en",{"handle":67,"displayName":68},"spots","Spots","queued",{"views":71,"likes":72,"saves":72,"shares":72,"completions":72,"opens":72,"skips":72,"depthSum":72},5,0,"2026-09-28T02:53:24.726Z","local"]