Multi-tenancy is not a single architectural decision — it is a family of decisions with compounding consequences. Pick the wrong model at the start and you will either pay too much to run a handful of clients, or spend six months refactoring when your biggest enterprise customer demands data isolation. Most tutorials gloss over this. Here is the honest breakdown.

The Three Models, Plainly Stated

1. Shared Schema (Row-Level Isolation)

Every tenant lives in the same tables. A tenant_id column on each row determines ownership. One database, one schema, millions of rows.

-- Example: shared schema pattern in PostgreSQL
CREATE TABLE invoices (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id   UUID NOT NULL REFERENCES tenants(id),
  amount      NUMERIC(12, 2),
  issued_at   TIMESTAMPTZ,
  ...
);

CREATE INDEX idx_invoices_tenant ON invoices (tenant_id);

Row-Level Security (RLS) in PostgreSQL makes this pattern far safer than it used to be. You set a policy once and the database engine enforces isolation — no risk of a missing WHERE tenant_id = $1 clause leaking data across clients.

Pros: Lowest infrastructure cost, simplest migrations, easy to aggregate cross-tenant analytics.
Cons: A noisy-neighbour tenant can degrade performance for everyone. Compliance requirements (GDPR, NDPR) get complicated fast. Backups restore all tenants or none.

2. Separate Schema (Schema-Level Isolation)

One PostgreSQL database, but each tenant gets their own schema — tenant_abc.invoices, tenant_xyz.invoices. The table structure is identical across schemas; only the namespace differs.

Pros: Stronger logical isolation without the cost of separate servers. Per-tenant backups are achievable with pg_dump --schema. Easier to meet audit requirements because data never physically coexists in the same table.
Cons: Schema migrations become an orchestration problem. If you have 200 tenants and you need to add a column, you run 200 ALTER TABLE statements. Tools like Flyway and Liquibase can help, but you will still need a reliable migration runner that handles partial failures gracefully.

3. Separate Database (Full Isolation)

Each tenant gets their own PostgreSQL instance — either on the same host or on dedicated infrastructure. Maximum isolation, maximum cost.

Pros: True data sovereignty. You can place a client's database in a specific region or jurisdiction. Performance SLAs are easy to honour. Disaster recovery is clean and independent.
Cons: Operational complexity scales linearly with client count. Connection pooling (PgBouncer, RDS Proxy) becomes critical. Infrastructure costs can make your unit economics unworkable at the SME price points common across West Africa.


Choosing the Right Model for an African SaaS Context

The African B2B SaaS market has a distinct profile: a wide spread between small-business clients paying $30/month and enterprise clients paying $3,000/month, persistent cost pressure from cloud egress fees and forex volatility, and an emerging but real compliance landscape (Nigeria's NDPR, Kenya's DPA, Ghana's DPA 2012).

Here is a practical decision framework:

Use shared schema when:

  • You are pre-product-market-fit and optimising for speed and cost.
  • All your clients are roughly the same size (e.g., a vertical SaaS for clinics or schools).
  • None of your clients currently have contractual data isolation requirements.
  • You enable PostgreSQL RLS from day one — do not skip this step.

Use separate schema when:

  • You have a mix of SME and mid-market clients but cannot yet justify per-client databases.
  • You need to offer per-tenant point-in-time restores as a paid feature.
  • Your compliance requirements are moderate — regulators want logical separation, not physical.
  • You invest in a migration framework before you have more than 20 tenants.

Use separate databases when:

  • You land a government contract or a financial institution that contractually mandates it.
  • A client's data must reside in a specific country (data residency).
  • A single tenant's query load would meaningfully affect other tenants.
  • Your pricing tier can absorb the infrastructure delta — this model only makes economic sense above a certain ACV.

The Hybrid Approach Most Production SaaS Products Actually Use

The cleanest real-world architecture is a tiered hybrid: shared schema for your self-serve and SME tier, separate schema for mid-market, and separate databases available as a premium add-on for enterprise. You abstract the routing layer — a central tenants table maps each tenant_id to a connection string and schema name. Your application code calls a get_connection(tenant_id) function that returns the right database handle, and the rest of your data layer stays unaware of the underlying model.

This approach lets you grow without a big-bang migration. A client upgrades their plan, you provision them a new schema or database, migrate their data, update the routing table, and flip the switch — zero downtime, no code change.


What Most Teams Get Wrong

Forgetting indexes on tenant_id. In a shared schema with 10 million rows and 500 tenants, a missing composite index does not just slow queries — it brings the entire application down during peak hours.

Skipping connection pooling. PostgreSQL has a hard ceiling on concurrent connections. In a separate-database model with 50 tenants each holding a connection pool of 10, you hit that ceiling fast. PgBouncer in transaction-pooling mode is not optional — it is load-bearing infrastructure.

Treating migration as an afterthought. Schema migrations in a multi-tenant environment need versioning, idempotency, and rollback capability. A failed migration that leaves 30 out of 200 schemas in an inconsistent state is a production incident, not a deployment hiccup.

Not modelling for compliance from the start. Adding audit logs, soft deletes, and data-export endpoints after you have 1,000 tenants is expensive. Build the hooks early — even if you do not need them yet.


Why This Matters for Your Project

The database tenancy model you choose in the first three months of a SaaS build shapes your cost structure, your compliance posture, and your ability to land enterprise deals for years afterward. Getting it right means understanding the trade-offs — not just picking the pattern that is easiest to explain in a README. If you are building a SaaS product for the African market, where clients range from a one-person shop to a government agency, a thoughtful hybrid architecture is almost always the answer.