# Symptom
A brand-new user signs up and immediately hits a "user not found" error in your app, even though the user exists in Clerk.

# Confirm the cause
1. Webhooks are asynchronous. user.created can arrive seconds after the user is already clicking around your app. Your first request raced the webhook and lost.
2. Check your logs: the failing request's timestamp vs the user.created delivery timestamp. If the request came first, this is the race.

# Fix
- Make the webhook handler an idempotent upsert keyed by the Clerk user id. Route user.created and user.updated through the same upsert so replays cannot create duplicates.
- On the read path, handle a missing row: lazy-provision the user on first request, or fall back to fetching the user from Clerk's Backend API by id.
- Key everything by the Clerk user id, never by email. Emails change; ids do not.

# Verify
Sign up a fresh test user and immediately open a protected page. It works whether or not the webhook has landed yet. Send the same webhook twice; you still have exactly one row.