The short version NextAuth (now Auth.js) creates 4 tables in your database: users, accounts, sessions, and verification_tokens. The users and accounts tables have a one-to-one relationship via accounts.user_id. Sessions link to users via sessions.user_id. Verification tokens are short-lived and self-cleaning. The 4 tables users Column Type What it means id text / UUID Primary key. Generated by NextAuth. name text Display name from the OAuth provider (Google, GitHub, etc.) email text User's email. May be null if the provider doesn't share it. email_verified timestamp When the email was verified. Null if never verified. image text Profile picture URL from the provider. created_at timestamp When the user first signed in. updated_at timestamp Last profile sync from the provider. accounts This table links a user to an OAuth provider. One user can have multiple accounts (e.g., Google + GitHub). Column Type What it means id text / UUID Primary key. user_id text Foreign key → users.id. type text Always "oauth" or "oidc". provider text "google", "github", "discord", etc. provider_account_id text The provider's unique ID for this user. refresh_token text OAuth refresh token (encrypted in production). access_token text OAuth access token (encrypted in production). expires_at integer When the access token expires (Unix timestamp). token_type text Usually "Bearer". scope text Permissions granted by the provider. id_token text OIDC ID token (if using OIDC). session_state text Provider-specific session state. sessions Active sessions for each user. NextAuth creates a new row here on every sign-in. Column Type What it means id text / UUID Primary key. session_token text The session token stored in the user's cookie. user_id text Foreign key → users.id. expires timestamp When this session expires. verification_tokens Short-lived tokens for email verification, password reset, etc. Self-cleaning old tokens are deleted automatically. Column Type What it means identifier text Email or user ID the token is for. token text The actual token value. expires timestamp When this token expires. How they connect users ──1──1── accounts │ 1 │ ∞ sessions users ──1──∞── verification_tokens (via identifier) One user → one or more accounts (Google, GitHub, etc.) One user → many sessions (different devices/browsers) Verification tokens are temporary and don't have a foreign key What to change Add a role column to users if you need role-based access control. Add a phone_number column to users if you're using SMS auth. Encrypt access_token and refresh_token in production NextAuth doesn't do this by default. What to leave alone Don't modify the verification_tokens table it's managed automatically. Don't change the session_token format it's a signed JWT. Don't add indexes to provider_account_id unless you're querying it directly (it's already unique). FAQ Does NextAuth store passwords? No. NextAuth is an OAuth-first library. It doesn't handle passwords. If you need email/password auth, use next-auth/providers/credentials with bcrypt, or use a service like Clerk or Lucia. How do I see what's in my NextAuth tables? Use dbdiagramr paste your connection string and get a visual schema of your NextAuth tables in seconds. Can I add custom fields to the users table? Yes. Add columns to the users table directly. NextAuth will ignore columns it doesn't know about, so you can safely add role, phone_number, preferences, etc. What happens when a user deletes their account? NextAuth doesn't cascade deletes by default. You need to manually delete from users, accounts, and sessions. Or add ON DELETE CASCADE to your foreign key constraints. Is Auth.js the same as NextAuth? Yes. Auth.js is the rebranded version of NextAuth. The database schema is identical. If you're on NextAuth v4, you're using the same tables.