Skip to content
Masab Qurban — home
Multi-Tenant SaaS Patterns with Next.js and PostgreSQL
SaaS Architecture

Multi-Tenant SaaS Patterns with Next.js and PostgreSQL

9 min read

As a Full Stack Architect, most of my production work at VendAxis sits inside multi-tenant SaaS - shared infrastructure, isolated customer data, and payment flows that can't drop events. This post is a field guide to the patterns I keep reaching for with Next.js, Node.js, PostgreSQL, and Stripe.

Tenancy that stays boring

For most B2B products, a shared PostgreSQL database with a tenantId on every business table is the right default. It's cheaper to operate than one-database-per-customer and scales farther than you'd expect when indexes and query habits are solid.

Rules that prevent late-night incidents:

  • Resolve the tenant once per request (subdomain, session, or API key) and never trust a client-supplied tenant id alone
  • Scope every Prisma query with tenantId - treat missing scope as a bug
  • Keep auth, billing, and tenant metadata in a small core schema; feature data can grow around it

Stripe webhooks as a reliability boundary

Subscriptions are a state machine: trial → active → past_due → canceled. Model that explicitly in your database, then let Stripe webhooks drive transitions.

Production habits that matter:

  • Verify signatures on every webhook
  • Make handlers idempotent - store event ids and skip duplicates
  • Acknowledge quickly; do heavy work asynchronously if needed
  • Reconcile periodically - webhooks will eventually miss something

I've shipped Stripe webhook pipelines designed for high availability for that reason: payments are not a place for "best effort" handlers.

TypeScript strict mode as a team contract

Strict TypeScript, PR reviews, and consistent deploy paths (Docker + Coolify in our case) sound process-heavy until you've inherited a loosely typed SaaS. Types catch tenant leaks and billing edge cases before users do. Prefer explicit DTOs at API boundaries over leaking Prisma models into the UI.

Frontend still counts

Multi-tenant backends often get all the attention, but product quality shows up in the UI: Next.js App Router for structure, careful client boundaries for interactivity, and performance work that keeps Lighthouse scores high. Fast APIs with a slow dashboard still feel broken.

Closing

Good SaaS architecture is mostly discipline: clear tenancy, idempotent billing, typed boundaries, and a stack you can operate. React, Next.js, Node.js, and PostgreSQL are enough - if you use them with production constraints in mind.

I'm Masab Qurban - open to roles, freelance, and collaborations. If this overlaps with a product you're building, reach out via the contact page.

More Posts