# Trickle migration: convert users at login

## The shape

1. Keep the old provider running alongside Clerk. Both systems accept
   logins during the migration window.
2. At login, check whether the user exists in Clerk yet. If not, migrate
   them on the spot: verify credentials against the old system, create the
   user in Clerk (preserving password via hash or a forced reset, storing
   external_id), then continue the session in Clerk.
3. Route all new signups to Clerk only. The old system is read-only for
   authentication of existing users.
4. Pick a window length up front: weeks for small apps, months for large
   ones. The cost is literally running two auth systems plus the
   coordination overhead.
5. At the end of the window, bulk import the stragglers who never logged
   in (passwords will need resets), then decommission the old system.

## Why this beats big-bang for large fleets

- No single coordinated cutover event. Sessions convert one at a time.
- Data desync risk drops because each user is migrated with fresh data at
  the moment of login, not from a stale snapshot.
- Rollback is per-user, not per-company.

## The traps

- The stragglers. Users who never log in during the window still need
  migrating, typically via basic export/import at the end. Trickle does not
  eliminate the bulk path, it shrinks it.
- Dual session handling. Your middleware must know which system issued the
  session it is looking at, or post-migration users hit the old session
  checks and bounce.
- Feature parity. If the old system had capabilities Clerk handles
  differently (custom claims, MFA policies), resolve the mapping before
  the first user converts, not after.

## Checklist

- A dashboard metric: migrated users vs remaining users, updated daily.
  The window end date is a real decision, not a vibe.
- The decommission step has an owner and a date. Migrations that never
  officially end keep billing you for the old system.