← Back to case studies

· 2 min read

Building a Multi-tenant CRM

A single Postgres-backed CRM serving multiple isolated tenants — schema-per-tenant isolation, shared application code, and zero cross-tenant data leaks.

Problem

An agency needed one codebase to serve several clients' sales teams, with hard data isolation between tenants, per-tenant configuration, and the ability to export/evict a tenant on demand.

Result

5 tenants on one codebase; isolation guaranteed by an automated property test on every PR; per-tenant export in one command.

Stack

  • TypeScript
  • Express
  • PostgreSQL
  • React
  • Drizzle ORM
  • Docker

TL;DR

Isolation strategySafetyOps costVerdict
Row-level security (RLS)One missed policy = leakLowRisky
Database-per-tenantSafestHighHeavy
Schema-per-tenantStrongMediumChosen

Architecture

Schema-per-tenant isolation on a shared Postgres instance, with a central tenants registry and a request-time resolver that sets the search path.

Request (Host / X-Tenant) → Tenant resolver → SET search_path

                                              Express handlers

                                  central DB (registry) ─┬─ tenant_a schema
                                                         └─ tenant_b schema

Interesting decisions

Lessons learned

Pros & cons

Pros: strong isolation, cheap per-tenant backup/restore, one codebase. Cons: migrations touch N schemas; a runaway tenant can still consume shared CPU/RAM.

Work with me

I build business software like this — fast, with AI-assisted delivery. Open to remote (US/EU) roles and freelance.

Get in touch · See my AI workflow →