Shipping a login form is a weekend. Shipping a login form that a customer's IT department can wire into their Okta tenant is a quarter. That gap is the entire authentication-as-a-service market, and it is also why comparing these vendors on free-tier size tells you almost nothing about your eventual bill.
I priced all of this out on August 21, 2026 and wrote the long version on DevToolLab: Best Authentication Providers in 2026. Short version below.
The number that reframes everything
WorkOS hands you user management free up to 1,000,000 monthly active users. Auth0 cuts off at 25,000 MAU. Clerk cuts off at 50,000 monthly retained users.
Looks decisive. Then you scroll down the WorkOS page and find enterprise SSO at $125 per connection per month. Login is the loss leader; the SAML connection your first enterprise customer demanded is the revenue line. Every vendor here meters federation per connection for exactly that reason.
Side by side
| Provider | Free tier | Paid entry | Enterprise SSO | Self-host |
|---|---|---|---|---|
| Auth0 | 25,000 MAU | $35/mo at 500 MAU | 1 included on Free | No |
| Clerk | 50,000 MRU per app | $25/mo + $0.02/MRU | 1 on Pro, then $75/mo each | No |
| WorkOS | 1,000,000 MAU | $2,500/mo per extra 1M | $125 each, $65 at volume | No |
| Better Auth | Unlimited (MIT) | Your database bill | Plugin, you run it | Yes |
| Keycloak | Unlimited (Apache 2.0) | Your infra bill | Built in, unmetered | Yes |
Worth noting: machine identity has quietly become the third product line. Clerk sells API keys and M2M tokens as a plan feature, and Auth0 is running an "Agent as Principal" banner.
Auth0
Okta-owned since 2021, and it acts like the incumbent it is. Credit where due: the free tier now bundles one enterprise connection, self-service SSO, SCIM and five organizations, all of which used to sit behind a paywall.
The pricing needs reading carefully. That $35/mo B2C Essentials figure is priced at 500 MAU, and the plan is a step function keyed to your MAU band, so it climbs as you grow. Professional starts at $240/mo in the same band. Flip the B2C/B2B toggle and the schedule changes entirely: $150/mo for Essentials, $800/mo for Professional at that same 500-user band. Price your actual shape, not the headline.
Protocol coverage is the deepest of the three and Actions let you drop server-side logic into the login pipeline. Against that: the developer experience feels a generation behind Clerk, and teams tend to discover the free-tier-to-real-bill jump after launch rather than before.
Clerk
Still the fastest path to working auth in a Next.js app. Its billing unit is unusual and worth understanding: Clerk counts monthly retained users, defined in its pricing FAQ as someone who returns at least one day after signing up. The free first day is not an accident, it means a launch-day traffic spike does not bill the way a MAU meter would.
Hobby gives you 50,000 MRU per app with the tradeoffs printed on the same page: 1-day log retention, a fixed 7-day session lifetime, Clerk branding. Pro is $25/mo ($20 annual) plus $0.02 per extra MRU and unlocks MFA, custom session lifetimes and branding removal. First enterprise connection included, $75/mo for each one after, satellite domains $10/mo. Business at $300/mo brings a SOC 2 report and 30-day retention; HIPAA with a BAA and the 99.99% SLA live on Enterprise.
Organizations, invitations and roles are first-class here. You cannot self-host, protocol depth is narrower than Auth0, and the ecosystem is heavily React-shaped.
One thing to skip if you are copying an older tutorial. In @clerk/nextjs 7.x the createRouteMatcher middleware pattern is deprecated, because the path matcher can disagree with how Next.js actually routes a request and leave protected data reachable. Check at the resource:
// app/dashboard/page.tsx - @clerk/nextjs 7.8.0
import { auth, currentUser } from "@clerk/nextjs/server";
export default async function DashboardPage() {
await auth.protect(); // bounces unauthenticated visitors
const user = await currentUser();
return <h1>Welcome back, {user?.firstName ?? "there"}</h1>;
}
WorkOS
WorkOS approached this backwards relative to the other two: enterprise-readiness plumbing first (SSO, SCIM, audit logs), the login product AuthKit second. The pricing follows from that history. AuthKit is free to 1M MAU, then $2,500/mo per additional million. The money is in the connection ladder: SSO runs $125 per connection for the first 15, then $100, $80, and $65 in the 51-100 band. Directory Sync uses the identical ladder. Audit Logs is billed separately.
Run two scenarios and the ranking flips:
- Consumer app, 400,000 users, zero SAML customers. WorkOS: $0. Clerk: roughly $7,000/mo once you clear the 50,000 included MRU.
- B2B product, 8,000 users, 30 enterprise customers on SSO plus SCIM. User meter stays free, connections cost about $6,750/mo. The bands are graduated, so WorkOS's own calculator returns $3,375 for 30 SSO connections (15 at $125, 15 at $100), doubled because Directory Sync bills the same way.
The SSO implementation is genuinely the least painful in this category, which is the whole value proposition: every IdP interprets SAML slightly differently and WorkOS eats that variance for you. Admin Portal even hands connection setup to the customer's own IT admin. Not selling to enterprises? Then most of what you are paying for does not apply to you.
The open-source column
All repository figures read on August 21, 2026.
Better Auth reset expectations for TypeScript teams: MIT, 29,627 stars, v1.7.1 shipped August 18, 2026. It is a library, not a server, so it points at your existing database and owns the schema, the endpoints and plugins for organizations, passkeys and 2FA.
Keycloak is the heavyweight option: Apache 2.0, 36,325 stars, 26.7.2 released August 19, 2026, unlimited realms and SAML connections, no per-connection meter anywhere in it. You pay in operations instead. Zitadel (AGPL 3.0, 14,816 stars) sits closest to a hosted platform, Ory Kratos ships no UI at all, and Logto aims at smaller teams. Read the license carefully on authentik and SuperTokens, both split-licensed, before you assume a feature is free.
Better Auth on a laptop, and the one gotcha
I ran 1.7.1 against better-sqlite3 on Node 25. Mount auth.handler on any server and the endpoints exist:
// auth.ts
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
export const auth = betterAuth({
database: new Database("./auth.db"),
emailAndPassword: { enabled: true },
session: { expiresIn: 60 * 60 * 24 * 7 },
});
Twenty minutes went to one trap. The documented npx @better-auth/cli migrate resolves to @better-auth/cli@1.4.21, which npm marks unsupported and which writes a 1.4-era schema. Against 1.7.1 your first signup then dies with table account has no column named issuer. Skip the CLI: call getMigrations(auth.options) from better-auth/db/migration, which diffs the live schema and named the exact gap (account: issuer) before applying. After that, signup and signin work, the cookie comes back as better-auth.session_token, and get-session honors the 7-day expiry above. Set BETTER_AUTH_URL or your callbacks break, and generate BETTER_AUTH_SECRET with openssl rand -base64 32.
If you are self-hosting and signing your own session tokens, the JWT signing key generator will mint HS256 or RS256 keys, and the Base64URL encoder and decoder is handy for pulling apart a session JWT or a JWKS entry.
Picking one
Start from who your customers are, because that is the variable that moves the invoice, not which framework you chose.
- Consumers or small teams on Next.js: Clerk. The free tier covers pre-revenue and the retained-user meter forgives a launch spike.
- Enterprise contracts: WorkOS. Your auth cost then tracks deals closed, which is the right shape.
- Regulated industry or unusual protocols: Auth0, after you have modeled your real MAU band.
- Data residency requirements: self-host with Better Auth or Keycloak.
Do not decide on free-tier size. The per-connection fee and the MAU step function are what two years of invoices are made of.
Migrating without a flag day
Nobody wants to log every user out on a Tuesday. You do not have to.
- Inventory login methods and password hashes. bcrypt and argon2id normally import as-is. Anything homegrown means a forced reset for that cohort, so find out now.
- Run both providers in parallel behind a flag. Import profiles first, hashes second, so user IDs stay stable. New signups go to the new provider while existing sessions keep validating against the old one.
- Move returning users lazily. On a successful login against the old provider, write the credential into the new one in the same request. The active population migrates itself over a few weeks. Move enterprise connections one customer at a time, and test the unglamorous flows (password reset, MFA recovery codes, SCIM deprovisioning) before you delete anything.
The full DevToolLab guide goes deeper on the pricing arithmetic and the per-provider tradeoffs than I have room for here.
Wrapping up
Clerk if your users are people and your stack is React. WorkOS if your users are companies and a SAML connection is the last thing between you and a signature. Auth0 for protocol depth or compliance breadth. Better Auth or Keycloak if the user table has to stay on your network.
Free tiers have grown large enough that early-stage cost is no longer the deciding factor. What is new is that all three vendors now sell machine identity next to human login. If agents will be acting on behalf of your users, evaluate that part now, while it is still the least mature piece and the most likely to change what you pay.
References
- Best Authentication Providers in 2026: Auth0 vs Clerk vs WorkOS - the original, longer article on DevToolLab
- Auth0 pricing
- Clerk pricing
- WorkOS pricing
- Better Auth
- Keycloak
- JWT Tokens Security Guide
- Non-Human Identity Security





Top comments (0)