Skip to content
Back to blog
·11 min read
Multi-tenant SaaS with Next.js: from template to production
WebSaaSNext.jsMulti-tenant

Multi-tenant SaaS with Next.js: from template to production

A multi-tenant Next.js SaaS reference from 2026: custom domains, RLS, per-tenant feature flags, and billing. No hand-waving.

Last verified
Dezső Mező
By Dezső MezőFounder, DField Solutions
ShareXLinkedIn#

Reviewed by:Dezső Mező· Founder · Engineer, DField Solutions· 10 Mar 2026

Past ~10 tenants, multi-tenant architecture isn't a luxury — it's survival. Here's the reference stack we run on Next.js with Postgres Row-Level Security. We ship this under our Web service.

1. Tenant detection: subdomain vs custom domain

Subdomain (acme.app.com) is the default. Custom domain (app.acme.com) ships in the Growth plan. Next.js middleware resolves the tenant and attaches it to the request.

// middleware.ts — tenant resolution
import { NextResponse, type NextRequest } from "next/server";

export async function middleware(req: NextRequest) {
  const host = req.headers.get("host") || "";
  const subdomain = host.replace(/\.app\.com$/, "");
  const tenant = await resolveTenantBySubdomain(subdomain);
  if (!tenant) return NextResponse.redirect(new URL("/404", req.url));

  const res = NextResponse.next();
  res.headers.set("x-tenant-id", tenant.id);
  return res;
}

2. Data isolation: Row-Level Security vs schema-per-tenant

Postgres RLS (PolicyScope) works well up to ~500 tenants. Above that, schema-per-tenant (or cluster-per-tenant for big customers). We default to RLS, and give dedicated schemas to critical accounts.

3. Per-tenant feature flags

Growth sees different features than Enterprise. We don't do if-elseif for this — PostHog feature flags + tenant group. The code stays clean.

4. Billing: Stripe + per-seat + usage

  • Stripe Subscription per tenant; customer = tenant.
  • Metered billing for usage-based products.
  • Webhook → Postgres → cache invalidation.

5. Background jobs per tenant

Don't run tenant jobs in one global queue. BullMQ per-tenant queues or a Temporal namespace. A noisy tenant then can't tip the rest over.

Summary

This architecture stands up in 2–8 weeks. If you're starting a SaaS today, start multi-tenant — retrofitting is always more expensive.

ShareXLinkedIn#
Dezső Mező

By

Dezső Mező

Founder, DField Solutions

I've shipped production products from fintech to creator-tooling — for startups and enterprises, from Budapest to San Francisco.

Keep reading

Would rather build together?

Let's talk about your project. 30 minutes, no strings.

Let's talk