SaaS

SaaS database schema with Prisma

We earn commissions when you shop through the links below.

How to model a small SaaS in Prisma: one User row, a plan column, and the two Stripe ids the webhook writes.

3 min read

A first SaaS schema has to answer three questions: who the person is, which plan they are on, and which Stripe objects belong to them. Everything else — teams, seats, invoices, feature flags — can wait. The Complete SaaS Starter Kit keeps that in one User model on PostgreSQL.

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id                   String   @id @default(cuid())
  email                String   @unique
  passwordHash         String
  name                 String
  plan                 String   @default("free")
  stripeCustomerId     String?  @unique
  stripeSubscriptionId String?
  createdAt            DateTime @default(now())
}

This is the whole production schema in the kit. If a column is not on this model, the first version does not need it.

What each field is for

email is the login identifier. It is unique so two accounts cannot share a mailbox. passwordHash is bcrypt; the plaintext password never hits the database. name is display-only.

plan is what your pages read. Default "free". Paid routes check user.plan === "pro". They do not call Stripe. Stripe remains the source of truth for money; this column is the copy your app can query on every request.

stripeCustomerId is unique so a second Checkout cannot attach a different customer to the same user by accident. Create the customer once, store the id, and pass it on the next visit. stripeSubscriptionId is how customer.subscription.updated and customer.subscription.deleted find the row.

createdAt is useful for admin lists and for “member since”. It is not used for billing.

Why there is no Organization table

There is no organization table and no membership table. One row is one account. That is enough for a personal SaaS and for most MVPs. If you later need teams, add Organization and Membership beside this model. Do not overload plan to mean both billing and permissions, and do not store a team name in name.

The kit is not multi-tenant. Tenancy is a separate product decision, covered in multi-tenant SaaS with Next.js.

Postgres locally

The Complete kit ships docker-compose.yml with PostgreSQL. DATABASE_URL in .env.example points at that container. After docker compose up -d:

npx prisma migrate dev
npx prisma generate

migrate dev applies the schema and keeps a history in prisma/migrations. Do not run db push in production; use prisma migrate deploy.

The Next.js SaaS Boilerplate uses the same columns on SQLite so you can start without Docker. The Prisma model is the same idea; only the datasource provider changes. Switch to Postgres before you take real payments.

What writes these columns

EventFields written
Sign upemail, passwordHash, name, plan: "free"
First CheckoutstripeCustomerId if empty
checkout.session.completedplan, stripeSubscriptionId
customer.subscription.updatedplan, stripeSubscriptionId
customer.subscription.deletedplan: "free", clear subscription id

The webhook path is in Stripe webhooks with Next.js and synchronizing Stripe subscription state. The Stripe-only view of these fields is the subscription schema article.

Do not update plan from the success URL. The browser tab can close. The webhook is the write.

What not to add yet

Skip Invoice, PaymentMethod, and a full audit log. Stripe already stores those. Skip Role until you have a second human in the account. Skip JSON settings columns until you have two settings that are not just name.

If you sell usage, as in the AI SaaS Starter, add a credits counter on the user or a small Usage table. Do not encode credits as a plan name.

The product shape around this schema is in building a SaaS with Next.js, Stripe, and PostgreSQL.

Product updates for developers shipping with Designyff kits.

Guides: Next.js, Stripe, and SaaS starter kits Professional website design for small businesses

Purchased source may be used in personal, commercial, and client projects. Do not redistribute or resell the original source. Terms of Service Privacy Policy

Designyff © 2026 | Starter kits for developers