NextAuth / Auth.js Database Schema Explained
The short version NextAuth (now Auth.js) creates 4 tables in your database: , , , and . The and tables have a one-to-one relationship via . Sessions link to users via . Verification tokens are short-lived and self-cleaning. The 4 tables users Column Type What it means text / UUID Primary key. Generated by NextAuth. text Display name from the OAuth provider (Google, GitHub, etc.) text User's email. May be null if the provider doesn't share it. timestamp When the email was verified. Null if never verified. text Profile picture URL from the provider. timestamp When the user first signed in. 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 text / UUID...
The short version NextAuth (now Auth.js) creates 4 tables in your database: , , , and . The and tables have a one-to-one relationship via . Sessions link to users via . Verification tokens are short-lived and self-cleaning. The 4 tables users Column Type What it means text / UUID Primary key. Generated by NextAuth. text Display name from the OAuth provider (Google, GitHub, etc.) text User's email. May be null if the provider doesn't share it. timestamp When the email was verified. Null if never verified. text Profile picture URL from the provider. timestamp When the user first signed in. 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 text / UUID Primary key. text Foreign key → . text Always or . text , , , etc. text The provider's unique ID for this user. text OAuth refresh token (encrypted in production). text OAuth access token (encrypted in production). integer When the access token expires (Unix timestamp). text Usually . text Permissions granted by the provider. text OIDC ID token (if using OIDC). 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 text / UUID Primary key. text The session token stored in the user's cookie. text Foreign key → . 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 text Email or user ID the token is for. text The actual token value. timestamp When this token expires. How they connect 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 column to if you need role-based access control. Add a column to if you're using SMS auth. Encrypt and in production NextAuth doesn't do this by default. What to leave alone Don't modify the table it's managed automatically. Don't change the format it's a signed JWT. Don't add indexes to 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 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 table directly. NextAuth will ignore columns it doesn't know about, so you can safely add , , , etc. What happens when a user deletes their account? NextAuth doesn't cascade deletes by default. You need to manually delete from , , and . Or add 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.