DField SolutionsMérnöki stúdió · Budapest
Loading · Töltődik
Skip to content
Back to blog
·11 min read
Web··11 min read

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
Listen
Dezső Mező
Founder, DField Solutions
ShareXLinkedIn#
Multi-tenant SaaS with Next.js: from template to production

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'm a full-stack engineer and I build across the whole stack myself · AI agents, web and mobile apps, blockchain, backends, security, right down to the OS layer. If it's software, I've probably built it and broken it.

Keep reading
RELATED PROJECTS
Let's talk

Would rather build together?

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