Arcjet vs Unkey vs Upstash Ratelimit: Next.js rate limiting in 2026
The library everyone recommends has not shipped a stable release since January 2026, Arcjet has no free tier and bills per app, and the most-installed rate limiter in Node is absent from the entire first page. We read the registry, the repositories and the pricing pages.
A stream of requests meeting three different metering gates, an inline valve, a valve wired out to a remote datastore, and a keyed turnstile, with held-back requests queued behind each, ShipGarden, 2026
On this page
Quick answer (2026)
If you are protecting a Next.js app and you want the cheapest correct answer, use @upstash/ratelimit against Upstash Redis. It is MIT, the free tier is 500K commands a month, and it does the one job well. If you are selling an API and the limits are per customer rather than per IP, use Unkey, because the limit and the API key are the same object and you get 150K valid requests a month at no cost. If you want rate limiting bundled with bot detection and a WAF behind one SDK call, use Arcjet, and know before you start that it has no free tier: a 15 day trial, then $25 a month per app.
Two things we found that the first page of Google does not mention.
The library everyone recommends, @upstash/ratelimit, has not had a stable npm release since January 12, 2026. That is seven months. We want to be precise about what that does and does not mean, because the lazy version of this finding is wrong and we nearly published it.
And the most-installed rate limiter in the whole Node ecosystem is not any of these three. It is rate-limiter-flexible, at 12.07 million downloads a month, more than all three of these packages combined, and it does not appear anywhere in the search results for this question.
We run the ShipGarden gallery by self-hosting the building blocks we recommend, so this is a read of the repositories, the registry and the pricing pages rather than a paraphrase of a feature table. Every version, download figure, license and price below was read from the source on August 20, 2026.
What we are actually comparing
These three get compared constantly and they are not the same category. That is most of the confusion.
@upstash/ratelimit is a library. You install it, you point it at a Redis, you call limit(identifier), you get an allow or a deny. It has no opinion about who the caller is. MIT licensed.
Unkey is API key management that happens to include rate limiting. The limit is attached to the key, which means it is attached to a customer, which means per-plan limits are configuration rather than code you write.
Arcjet is an application security SDK. Rate limiting is one rule type among bot detection, a Shield WAF, email validation, PII detection and prompt scanning. You are buying the bundle.
So the question is not really "which of these three is best." It is "what is the shape of the abuse I am trying to stop, and who is the actor I am counting."
If you are counting anonymous IPs hitting a public form or an AI endpoint, that is Upstash's shape. If you are counting paying customers against their plan quota, that is Unkey's shape. If you are counting hostile traffic you have not characterised yet, that is Arcjet's shape.
The honest comparison table
Scroll to see more
Arcjet
Unkey
Upstash Ratelimit
Logo
Shape
Security SDK (bundle)
API key platform
Single-purpose library
Repo license
Apache-2.0
AGPL-3.0 (root)
MIT
npm license
Apache-2.0 (@arcjet/next)
MIT (@unkey/api)
MIT (@upstash/ratelimit)
Latest npm stable
1.10.0, August 11, 2026
2.5.0, July 21, 2026
2.0.8, January 12, 2026
GitHub stars
681
5,421
2,044
Open issues
4
157
6
npm downloads / month
275,808
455,835
8,488,342
Free tier
None (15 day trial)
150K valid requests, 1k keys
500K Redis commands, 256MB
First paid tier
$25 / mo per app
$25 / mo (250K requests)
$0.20 per 100K commands
Where the decision happens
Arcjet Cloud API (WASM locally for some rules)
Unkey API
Your Redis
Self-hostable
No
Yes (AGPL-3.0)
Redis yes, Upstash service no
Failure mode
Fails open by default
Your choice
Your choice
Stars, issue counts, licenses and release dates read from each project's GitHub repository and from the npm registry on August 20, 2026. Download figures are the npm registry's last-month totals for the window July 21 to August 19, 2026. Prices read from each vendor's own pricing page in August 2026. All of these move. Re-check before you commit a budget.
The Upstash release gap, stated accurately
Here is the raw registry state. The latest dist-tag on @upstash/ratelimit points at v2.0.8, published January 12, 2026. The previous stable, v2.0.7, was November 3, 2025. Nothing has landed on the stable channel since.
Meanwhile the upstash/ratelimit-js repository tagged a v2.1.0-rc on August 7, 2026 that has never been promoted, and the CI is publishing a dated prerelease to npm every single day. We checked five consecutive days, August 16 through August 20, 2026, and every one of them is built from the same commit hash, 91c0bad0. The version strings change daily. The code does not.
The obvious conclusion is that the project is dying. That conclusion is wrong, and we want to say so plainly because it is the kind of thing a comparison post gets lazily wrong and then a hundred people repeat.
Read the v2.1.0-rc changelog and it contains exactly three merged pull requests: adding skill files, moving releases to npm OIDC, and adding SDK telemetry. Not one of them touches the limiting logic. Fixed window, sliding window and token bucket all work the way they worked in January, because a rate limiter is a small, well-understood algorithm that does not need monthly attention. Six open issues against 2,044 stars is a healthy ratio, not an abandoned one.
So the accurate reading is: feature-complete, not dead. That is a genuinely fine thing for a dependency this small to be, and it is the reason 8.49 million installs a month is not a warning sign. The one thing we would actually flag is the SDK telemetry in the unreleased RC. If you have a view about your dependencies phoning home, form it before v2.1.0 ships, not after.
Arcjet: the bundle, and the price of it
Arcjet is the most actively developed of the three by release cadence. It shipped v1.10.0 on August 11, 2026 through a proper rc.0, rc.1, stable train, and the repository had a push the day we read it. Four open issues against 681 stars. The SDK is Apache-2.0 and the codebase is essentially all TypeScript.
The pitch is one protect() call that runs rate limiting, bot detection and a WAF together, which is a real ergonomic win over wiring three things yourself.
The architecture is worth understanding before you adopt it, and Arcjet documents it honestly, which we appreciate. The SDK ships a WebAssembly module that decides some rules locally: Shield, header-based bot analysis, email syntax, non-IP filters. Rate limit tracking is not one of them. Counting requests across instances requires the Arcjet Cloud API. Only decisions that have already been denied get cached locally, so a request that is going to be allowed pays the round trip. Arcjet's own figure for that overhead is typically 20ms to 30ms, with a 500ms production timeout.
That is not a criticism. Upstash also pays a network round trip, to your Redis. Any limiter that counts correctly across serverless instances has shared state somewhere, and shared state is a network hop. There is no local-only version of this that is also correct.
The part to decide deliberately is the failure mode. Arcjet defaults to failing open: if the Cloud API is unreachable, requests are allowed. For a login form that is the safe default. For a metered AI endpoint where each call costs you real money, "allow everything during an outage" is a bill, and you should know that is the default rather than discover it.
Then the pricing, which is where we expect most readers of this post to make their decision. Arcjet's pricing page lists a 15 day trial and then Individual at $25 a month per app, Startup at $299, Growth at $799. Note "per app." If you keep four side projects alive, the entry price is not $25, it is $100 a month, and the two alternatives here are $0 at that volume. Bot detection, email verification, PII detection, prompt scanning and content moderation carry additional per-usage fees on top.
Arcjet is a good product with a fair price for a funded team shipping one revenue-generating application. It is the wrong shape for a developer with a portfolio, and the entire first page of Google is written for the developer with a portfolio.
Unkey: it stopped being an API key manager
If your mental model of Unkey comes from a 2024 tutorial, update it. The repository now describes itself as "The Developer Platform for Modern APIs," carries deployment and gateway topics, and runs a frontline release train that tagged v1.0.22 on August 18, 2026. Its pricing page now sells two products: API Management, and Unkey Deploy, billed per vCPU-second, per GB-second of memory and per GB of egress. That is a hosting product. It is a bigger company than the one the tutorials describe, and worth pricing accordingly.
For the rate limiting question specifically, the API Management side is what matters, and the free tier is the most generous here: 150K valid requests a month and 1,000 API keys at $0. Paid starts at $25 a month for 250K and ladders up through $50, $75, $100, $250, $500 and $1,000 for 100M.
The structural advantage is not the price, it is the data model. When the limit lives on the key, "Free plan gets 100 requests an hour, Pro gets 10,000" is a field you set when you issue the key. With Upstash you write that mapping yourself, and you write the code that looks up which plan this caller is on before you can even pick a limit. If you are shipping a public API with tiers, that difference is a real amount of code you do not maintain.
Two honest caveats. The repository root is AGPL-3.0, not MIT. The packages/ directory is separately licensed and @unkey/api on npm is MIT, so the client SDK is not the issue, but if you plan to self-host the platform and you work somewhere with a copyleft policy, read the license before the architecture review, not after. And 157 open issues against 5,421 stars is a much busier tracker than the other two, which is what you expect from a platform rather than a library, but it is a larger surface to depend on.
The package nobody in this SERP mentions
We pulled last-month npm download counts for the window July 21 to August 19, 2026:
Scroll to see more
Package
Downloads / month
rate-limiter-flexible
12,071,785
@upstash/ratelimit
8,488,342
@unkey/api
455,835
@arcjet/next
275,808
rate-limiter-flexible is ISC licensed, has 3,582 stars, nine open issues, and backs onto Redis, Postgres, MySQL, Memcached, MongoDB or process memory. It has no vendor, no pricing page and no marketing site, which is exactly why it is invisible in a search result set made of vendor blogs and vendor docs.
If you already run a Postgres or a Redis, it is very likely the correct answer, and it costs nothing. It is worth knowing that the reason it is not in the conversation is not that it lost an evaluation. It is that nobody is paying to put it in the conversation.
We are not recommending it over the other three for every case. Upstash's ergonomics for serverless Next.js are better, and Unkey's per-customer model is something a raw library will not give you. But a comparison that pretends the most-installed option does not exist is not a comparison, it is a shortlist someone else wrote.
The Next.js specifics that actually bite
Three things decide whether any of this works, independent of vendor.
In-memory counters do not work. The single most common answer in the Reddit and GitHub threads that dominate this SERP is a Map in module scope. On serverless every instance gets its own map, so your "10 requests per minute" is 10 per minute per instance, and your instance count is not something you control. It also resets on cold start. This is the actual reason the vendors exist.
Getting the client IP is not free. Behind a proxy you are reading a forwarded header, and a forwarded header is attacker-controlled unless your platform overwrites it. Confirm which header your host guarantees before you key a limiter on it. Arcjet and Unkey do this for you; with @upstash/ratelimit it is your code.
Middleware and route handlers are different runtimes with different budgets. Limiting in middleware catches the request earlier and covers pages as well as routes, which is usually what you want, but it also runs on every matched request, and every one of those is a billable command or a billable API call. Match narrowly. A middleware matcher that accidentally covers /_next/static will produce a bill that has nothing to do with abuse.
One more, for anyone on Vercel or Cloudflare: both platforms sell WAF-level rate limiting that runs before your function is invoked. Platform-level limiting is strictly cheaper than application-level limiting, because a blocked request never costs you compute. It is also blunter: it cannot see who the authenticated user is or which plan they are on. The mature setup is usually both, a coarse platform rule for volumetric abuse and a fine application rule for per-customer quotas, not one instead of the other.
So which one
The decision collapses to three questions, and you can usually answer them in a minute.
Is the actor an anonymous IP or a paying customer? If it is an IP hitting a contact form, a signup route or an unauthenticated AI endpoint, use @upstash/ratelimit. It is MIT, the free tier covers a real hobby project, and the seven month release gap is feature-completeness rather than rot. If it is a customer on a plan, use Unkey and let the limit ride on the key.
Are you buying a limiter or a security posture? If rate limiting is genuinely one item on a list that also includes bot detection and a WAF, Arcjet's bundle is worth $25 a month for one production app, and its release discipline is the best of the three. If rate limiting is the only thing on the list, you are paying a bundle price for a single feature, and paying it per app.
Do you already run a datastore? If you have a Redis or a Postgres and no particular loyalty to a vendor, look hard at rate-limiter-flexible before you add a service. Twelve million installs a month is not nothing, and the absence of a marketing budget is not a technical finding.
Two boundaries worth drawing, because we watch people conflate them. A rate limiter is not authentication. It counts requests from an identity; it does not establish one, and if the actual question is which library issues and verifies the session in the first place, that is a separate decision we worked through across Better Auth, Auth.js and Supabase Auth. And a limiter you cannot observe is a limiter you will misconfigure. The first week after you ship one, the thing you want is a chart of 429s by route and by identity, so that you find out you throttled your own cron job from a dashboard rather than from a customer. That is error monitoring, and it is worth wiring in the same pull request.
Your move: open your package.json, find whichever limiter is already in there, and check whether its counter lives in memory. If it does, you do not have rate limiting. You have a comment.
Yui Tanaka curates the ShipGarden gallery, where we self-host the open-source building blocks we recommend so we can own the stack that funds the life.
Frequently asked questions
What is the best rate limiting library for Next.js in 2026?
For anonymous traffic on a Next.js app, @upstash/ratelimit against Upstash Redis is the cheapest correct answer: MIT licensed, 500K Redis commands a month on the free tier, and a stable v2.0.8 that has been unchanged since January 12, 2026. For per-customer limits on a public API, Unkey is structurally better because the limit lives on the API key, and its free tier is 150K valid requests a month with 1,000 keys. For rate limiting bundled with bot detection and a WAF, Arcjet is the most actively released of the three, but it has no free tier: a 15 day trial, then $25 a month per app. If you already run a Redis or a Postgres, rate-limiter-flexible is worth checking first, since at 12.07 million downloads a month it is the most-installed option in the Node ecosystem. All figures read on August 20, 2026.
Is @upstash/ratelimit still maintained in 2026?
Yes, but it is feature-complete rather than actively developed, and that distinction matters. Read on August 20, 2026, the latest stable on npm is v2.0.8 from January 12, 2026, seven months earlier. The repository tagged a v2.1.0-rc on August 7, 2026 that has not been promoted, and CI publishes a dated prerelease to npm daily from the same commit hash, 91c0bad0, verified across August 16 to 20, 2026. However the v2.1.0-rc changelog is only three pull requests: skill files, npm OIDC release plumbing, and SDK telemetry. None of them touch the limiting logic. With six open issues against 2,044 stars and 8.49 million downloads a month, this reads as a small algorithm that is finished, not a project that has been abandoned. The one thing to note is the unreleased SDK telemetry, if you have a policy about dependencies phoning home.
Does Arcjet have a free tier?
No. Read from arcjet.com/pricing in August 2026, Arcjet offers a 15 day trial, after which the entry plan is Individual at $25 a month per app, then Startup at $299 a month per app and Growth at $799 a month per app. The per app pricing is the part most comparisons omit: if you run four projects, the entry cost is $100 a month rather than $25, where both Unkey and Upstash are $0 at hobby volume. Bot detection, email verification, PII detection, prompt scanning and content moderation also carry per-usage fees on top of the base request cost.
Why does an in-memory rate limiter not work on Next.js?
Because on serverless there is no single instance to hold the counter. A Map in module scope gives every concurrently running instance its own independent counter, so a rule of 10 requests per minute becomes 10 per minute per instance, and you do not control how many instances exist. The counter also resets on every cold start and after every deploy. Any limiter that counts correctly across instances needs shared state, which means Redis, a database, or a vendor API, and that is a network round trip in every case. This is the actual reason Arcjet, Unkey and Upstash exist.
Does Arcjet fail open or fail closed?
Arcjet fails open by default. Per its own architecture documentation, rate limit tracking requires a call to the Arcjet Cloud API, only already-denied decisions are cached locally, typical overhead is 20ms to 30ms, and the production timeout is 500ms. If the API is unreachable, the SDK defaults to allowing all requests. For a login form that is the safer default, since an outage at the vendor should not lock out your users. For a metered endpoint where each request costs you money, such as an AI completion route, allow-everything during an outage is a bill, so decide the posture deliberately rather than inheriting it.
Should I rate limit in Next.js middleware or in the route handler?
Middleware catches the request earlier and covers pages as well as route handlers, which is usually what you want, but it runs on every matched request and each one is a billable Redis command or vendor API call. Match narrowly: a matcher that accidentally covers static assets under /_next produces a bill unrelated to any abuse. Also confirm which forwarded header your host guarantees before keying a limiter on client IP, since forwarded headers are attacker-controlled unless the platform overwrites them. Separately, platform-level WAF rate limiting on Vercel or Cloudflare is strictly cheaper because a blocked request never invokes your function, but it cannot see which authenticated user or plan the caller is on. Mature setups run both: a coarse platform rule for volumetric abuse and a fine application rule for per-customer quotas.
A curator's take on the three open-source auth picks for a Next.js SaaS in 2026 (Better Auth, Auth.js, Supabase Auth), and the one axis that decides which shelf you pull from.
Sentry vs GlitchTip vs Highlight for error monitoring in a Next.js SaaS in 2026: the license fork, what each costs to self-host, and honest where-each-loses.
Clerk, WorkOS AuthKit, and Kinde are the three managed auth providers Next.js teams weigh in 2026. We compare how each charges (MRU vs MAU), their App Router SDKs, enterprise SSO cost, and where each one loses.