# 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.