Software comparison

Auth.js vs Clerk vs Supabase Auth: free limits and a real session test

50 Auth.js JWT session reads, negative checks, Clerk MRU limits and Supabase’s default-email restriction. Hosted auth and Cloudflare deployment are not tested.

Published
Tested on
Prices checked

Test scope Auth.js core 0.41.3 Credentials/JWT fixture on Node localhost. Clerk signup only; Supabase hosted auth not tested.

What we did not test
  • Clerk application provisioning and end-user authentication; signup reached verification/new-app navigation only.
  • Supabase Auth account/project and end-user flows: documentation only.
  • OAuth, real passwords, email delivery, MFA, account linking, cross-device revocation, tenant isolation and Cloudflare deployment.
  • Every paid tier and quota exhaustion.

Our verdict

  • Buy account UI

    Clerk is the candidate when prebuilt UI and organizations save development work.

    Check MRU billing and feature gates, including MFA and organization size. Hosted authentication was not tested.

  • Own sessions

    Auth.js passed our local session and negative checks.

    50 reads had a 3.405 ms median. You still own account lifecycle, abuse controls and deployed runtime compatibility.

  • Plan real email

    Supabase Auth needs production delivery configuration.

    The default sender is limited to authorized team addresses and two messages/hour. This limit is documented, not tested.

At a glance: identity service or session library?

Clerk and Supabase Auth are hosted identity services. Auth.js is a library you integrate into an application and operate. Comparing only their free user counts hides the main purchase decision: whether you want a vendor to own account lifecycle and auth UI, or your team to implement and support those pieces.

We tested Auth.js core 0.41.3 locally with Web Request/Response APIs, a fixed test Credentials provider and JWT sessions. Fifty authenticated session reads had a 3.405 ms median and 5.761 ms p95. Wrong-password login, a corrupted session cookie and post-logout session reads all returned no session. The fixture establishes basic session behavior, not production identity security.

Hosted authentication was not tested. Clerk signup reached email verification and the new-application URL, but our browser flow ended before an application or user login test was completed. Supabase Auth was researched, not provisioned. We did not create a hosted auth application, send customer confirmation emails, configure OAuth or deploy this fixture to Cloudflare.

Which problem each option actually solves

Clerk is the first candidate when prebuilt sign-in/profile components and organization management would otherwise take development time. Its plan table includes both UI/API functionality and feature restrictions. Supabase Auth is a candidate when you want hosted accounts and JWTs to work alongside services you already use in Supabase; its Auth guide describes password, passwordless and social flows. This comparison is about identity and session integration, not database hosting.

Auth.js is a candidate when you already own the application and want a framework integration around providers and sessions. Its core reference describes the Request/Response entry point; the session guide explains JWT and database strategies. It does not supply a hosted identity dashboard, customer support process or automatic password-account implementation simply by being installed.

Which problem each option actually solves
DecisionAuth.jsClerkSupabase Auth
CategoryApplication libraryHosted identity and UIHosted identity service
Free unitNo hosted user allowance; you run the code50,000 monthly retained users/app50,000 monthly active users
UI ownershipYour app and chosen integrationPrebuilt auth/profile UI includedBuild/integrate UI around Auth APIs
Team organization modelImplement your own application rules100 retained organizations/app; up to 20 members eachDesign your app’s tenancy and authorization
Infrastructure responsibilityApp runtime, session secrets, provider config and any adaptersVendor service plus your app integrationVendor service plus your app integration
Hands-on coverage hereLocal Credentials/JWT fixtureSignup only; no app testNot tested; documentation only

Numeric allowances and organization restrictions come from Clerk pricing and Supabase pricing, checked Oct 1, 2026. The categories are our architectural interpretation of the documented products. The table is not a speed ranking.

Our Auth.js fixture and what the checks mean

The local Node 20.19.2 server passes HTTP requests into Auth(). It uses a random process-local secret, JWT session strategy, and one hardcoded test username/password. The provider returns a synthetic user only for the fixture’s valid credential. There is no password database, hashing service, signup, reset flow, email delivery, MFA or external OAuth provider.

const config = {
  secret: process.env.AUTH_SECRET,
  trustHost: true, // local fixture; evaluate proxy trust in production
  basePath: "/auth",
  session: { strategy: "jwt" },
  providers: [/* configured identity provider */],
};
const response = await Auth(request, config);

This sketch deliberately omits our fixed password stub. It is not a password-authentication recipe. Auth.js’ Credentials guide says you must provide your own credential handling. In production, validating passwords, rate limiting attempts, account recovery and safe enrollment remain application responsibilities when choosing that approach.

The actual built-in Auth.js Credentials sign-in page served by our local fixture. No hosted provider is shown.
The actual built-in Auth.js Credentials sign-in page served by our local fixture. No hosted provider is shown. Captured Oct 1, 2026.
Our Auth.js fixture and what the checks mean
TestObserved resultWhat was not established
Anonymous session read200 with null sessionProtected-resource authorization was not exercised
Wrong test passwordNo authenticated sessionNo brute-force resistance or password hashing test
Valid credential callbackAuthenticated synthetic userCallback response 14.281 ms; not OAuth exchange time
50 authenticated readsMedian 3.405 ms; p95 5.761 msLocal HTTP only; not provider latency
Changed last four cookie charactersNull sessionNo full cryptographic or penetration audit
Logout then session readNull sessionOther-device logout/revocation not tested
Session-token value size457 bytesOne synthetic user; cookie attributes/name add overhead

The 50 reads were sequential, using the same valid session, with p95 reported as the 48th sorted sample. The range was 2.434–6.313 ms. We excluded login and negative tests from that latency distribution. Request records retain status, timing and synthetic response bodies; CSRF values are redacted and encrypted session tokens were not committed.

Clerk’s current free unit is MRU, not MAU

Clerk’s February 5, 2026 changelog increased the free allowance to 50,000 monthly retained users. The current pricing page defines retained users around returning at least a day after signup. Supabase meters monthly active users. These are different populations: a signup that never returns can affect one count differently from the other. Do not assume equal headline allowances produce equal usage bills.

Clerk Hobby currently includes unlimited applications, up to three dashboard seats, a fixed seven-day session lifetime and one day of application logs. MFA and custom session lifetime appear in Pro. The free organization allowance is 100 monthly retained organizations per application, with up to 20 members each. A SaaS with small usage but a requirement for MFA or larger organizations may need paid features long before crossing its user allowance. These are documented restrictions; we did not hit them in a dashboard.

The price display we fetched shows Pro at $20/month billed annually, with 50,000 MRU included per app and graduated overages; the first displayed additional-user rate is $0.02 per month. It is not a quote for month-to-month billing or an all-in estimate for B2B add-ons. Pro and every other paid tier are not tested.

Supabase’s email boundary matters before its user ceiling

The Free plan includes 50,000 MAU and two active projects, with inactive free projects subject to pausing after one week. Its total-user count is not the same as MAU. We did not create a project or measure pausing, so these remain documented limits.

For email/password confirmation or magic links, the SMTP guide is the launch-critical source. Supabase’s built-in mail sender accepts only authorized team addresses and is currently limited to two messages per hour. The docs explicitly position it for non-production exploration. A 50,000-MAU free allowance therefore does not mean you can send signup confirmations to 50,000 customers using the default sender.

Supabase’s email boundary matters before its user ceiling
Supabase Auth operationDocumented current limitScope / caveat
Built-in email sending2 emails/hour per projectTeam addresses only without custom SMTP
New custom SMTP configurationInitial 30 emails/hourAdjustable; sending-provider costs and limits also apply
Signup/sign-in family30 requests / 5 minutes per IPToken bucket allows bursts; anonymous sign-in is separate
Token endpoint150 requests / 5 minutes per IPPassword, refresh, ID-token and PKCE grants
OTP repeat request60-second window per userEmail-delivery quotas still also apply
Anonymous signup30 requests/hour per IP by defaultSeparate configurable bucket

Rates come from the rate-limit reference and SMTP configuration, checked Oct 1, 2026; none was hit. When your server proxies auth requests, many users can appear to share an IP. The reference describes an explicitly enabled forwarding mechanism that requires a secret key. Do not copy that secret into browser code while trying to fix a rate-limit problem.

Supabase Pro starts at $25/month and includes 100,000 MAU before auth overages in the public pricing display. That subscription bundles more than identity; extra projects and services can affect the total. We did not test the plan or compare its whole platform to Clerk’s identity-only budget. Custom SMTP remains a separate delivery decision on either free or paid hosting.

Cloudflare compatibility: verify the entire dependency chain

The Auth.js edge guide says core functionality is designed around portable APIs but warns that database adapters and other dependencies can break in an edge environment. Our adapter-free JWT fixture uses Web Request/Response APIs; running that fixture on Node does not prove a Cloudflare Worker bundle will work. Provider callbacks, crypto dependencies, framework adapters and proxy headers still need a deployed test.

For Clerk, use the current backend SDK and the integration documented for your actual framework/runtime; the backend reference covers createClerkClient. We did not validate a Hono middleware package, verify hosted Clerk JWTs at the edge or measure JWKS fetching. Supabase’s HTTP-based auth APIs are usable from a fetch-based application, but cookies, refresh behavior and allowed redirect URLs are still your integration work. These are architectural options, not completed Cloudflare integrations.

With a static front end on Pages and an API on Workers, decide where sessions are checked and where cookies are set before choosing the vendor. Keep privileged keys in server bindings, validate authorization in the API and configure exact OAuth redirect URLs for production and previews. A user being signed in does not by itself grant access to another customer’s data. We did not test tenancy isolation.

JWT convenience, revocation and operational ownership

Our test used a JWT session because it avoids a session database in the fixture. The session-strategy guide explains the tradeoff: deleting the browser cookie signs that browser out, while early revocation of an already-issued token needs additional design. A fast local read is not a complete account-deletion or other-device logout strategy. Our logout check only established that the fixture client stopped presenting an authenticated session afterward.

If you choose Auth.js, budget work for secret persistence/rotation, provider setup, account linking, reset and verification flows, abuse controls, cookie policy and observability. Our random per-process test secret was intentionally disposable; a real deployment needs consistent secrets across instances and restarts. If you choose a hosted service, budget for SDK upgrades, exports/migration, provider configuration and handling service outages. Neither choice removes application authorization work.

Real user reports and maintenance signals

Auth.js issue #11999 reports a SvelteKit application working locally but failing on Cloudflare Workers. Issue #11184 reports a crypto-export error in a Cloudflare build. Both are older framework-specific reports; neither is proof that our current core version fails. They support our decision to keep deployed runtime compatibility explicitly untested rather than extrapolate from Node.

The Auth.js release page shows security maintenance in the v4 line; that is a different package line from our core fixture. The current docs also state the project is part of Better Auth. This review does not treat Better Auth as tested or interchangeable with Auth.js. We checked Supabase’s changelog and Clerk’s pricing changelog alongside current docs so historical plan numbers do not silently enter the comparison.

Our decision for an indie SaaS

Start with Clerk when the UI and user/organization management save work that you would otherwise build, and verify the feature gates you need. Start with Supabase Auth when it fits an existing Supabase application, but arrange real email delivery before opening registration. Start with Auth.js when you want to own the implementation and can support its account lifecycle and runtime integration. Our measured session checks make the library a credible local prototype option; they do not rank hosted reliability or security.

Before shipping any of the three, test real signup, duplicate-email handling, password reset or provider recovery, email delivery, OAuth state handling, logout across devices and a cross-tenant authorization attempt in your deployment. Those are the missing tests that would most change this recommendation. No commission-linked vendor URL is used on this page.

Who should not use this

Do not choose Auth.js as a shortcut around password storage, account recovery or abuse prevention. Do not launch public email signup on Supabase’s default sender. Do not assume Clerk Hobby includes every paid security or organization feature. Hosted performance and security are not ranked by our local tests.

On this page · 10 sections