
Who holds your users' passwords
Try to leave Auth0 and you find out who owns your users. The dashboard exports profiles happily enough, in NDJSON or CSV. It does not export password hashes. For those you open a support case, generate an RSA 4096-bit PGP key pair with an encryption subkey, prove you are the tenant administrator, and wait for someone at Okta to approve the request. Auth0 documents this process in detail and it works. But notice what it is: a human approval step standing between you and the credentials your users gave you.
The export is the tell
That flow exists for a good reason. Password hashes are the most sensitive thing in the system and encrypting them end to end before they leave is the responsible choice. The docs even tell you to set the key expiry at least seven days out and warn that recent GnuPG versions default to ECC, which their validation rejects. That is a team being careful with other people's secrets.
The cost shows up later, when you want to move. Bulk import caps files at 500KB, roughly a thousand users with fewer than ten metadata fields each, so a 40,000-user tenant becomes forty jobs you schedule and retry yourself. Auth0 recommends a job framework like Bull or Agenda and a finalizer job that collects the failures into a new file. None of that is hard. All of it is work you do because the data lives somewhere you cannot reach with a SQL client.
Compare that to auth in your own Postgres. Supabase Auth runs GoTrue next to your database and writes users into an `auth` schema inside it. Same server, same backups, same connection string as the rest of your data. Moving off Supabase means `pg_dump`. There is no case to open because there is nobody to ask.
What the meter does as you grow
The pricing is the other half. Auth0's free tier covers 25,000 monthly active users, which is generous and where most projects sit forever. Essentials is $35 a month for up to 500 MAU, and Professional, the tier where you can point logins at your own existing user database, is $240 a month for the same 500 MAU. Clerk prices differently: 50,000 monthly retained users free, then $20 a month on Pro with another $0.02 per MRU above the included 50,000, and $75 a month for each enterprise SSO connection past the first.
Run that against a B2B product with forty client companies each wanting SAML. On Clerk that is 39 extra connections at $75, about $2,925 a month, for a feature that is a library call in your own stack. Supabase charges $25 a month on Pro for 100,000 MAU and $0.00325 per MAU after, with SSO included on Team at $599. Whatever the exact figures are next quarter, the shape holds: platform auth bills you per user and per connection, self-hosted auth bills you per server.
The Stay World Class migration made this concrete. Webflow and Xano came out, Next.js, NestJS and Supabase went in, and a four-stage ETL mapped every legacy ID onto PostgreSQL UUIDs so no user lost their account. Lighthouse went from 55.91 to 91 out of 100 and LCP dropped 77%. The performance numbers get quoted more, but the part that changed day to day was having every user row in a database we could query and test against.
The session, the reset, the audit trail
Pricing you can model. What you cannot model is everything downstream of the session. The vendor decides how long a token lives, what the reset email says, which fields the audit log keeps and for how long. Clerk's Hobby tier fixes session lifetime at seven days and keeps application logs for one day; Pro gives you custom lifetimes and seven-day retention, Business thirty days. Reasonable tiering. Also a compliance conversation you have with a pricing page instead of your own code.
That surfaces at the worst moment. A security review asks how long a stolen token stays valid, or an auditor wants six months of sign-in events, and the answer depends on a plan you are on rather than a policy you wrote. Owning auth means the answer is a migration and a retention cron.
Getting there is less dramatic than it sounds. Auth is a users table, a sessions table, hashed passwords, and a handful of flows you write once. The genuinely hard parts, SAML and rate limiting on the reset endpoint, stay hard either way.
When renting auth is still right
If you are under the free tier and heading nowhere near it, this is a non-problem. Auth0 at 25,000 MAU and Clerk at 50,000 MRU cost nothing, and the thing you should be doing instead of building auth is finding out whether anyone wants the product.
If your app is consumer, high volume and low revenue per user, run the unit economics before you move. Clerk says this about its own pricing: per-MRU billing is easiest to justify when retention maps to revenue, and for a free ad-supported audience something like Supabase Auth is probably cheaper. And if you need SOC2 or HIPAA next quarter with no security engineer on staff, buy the compliance. Auth0 and Clerk have already been audited. You have not.
The case for moving is narrower than the internet suggests. It is strongest when auth has to join your own data in a query, when SSO connections are being metered one client at a time, or when a support case sits between you and your own credentials. If none of those describe you, stay where you are.
