System designJune 2, 20262 min read

Multi-tenant architecture: lessons from building a POS platform

Tenant isolation looks like one architecture decision. In practice it is a hundred small ones — here are the ones that mattered.

Building KRAAK — a multi-tenant loyalty and POS platform — taught me that "multi-tenant" is not a box on the diagram. It is a property every feature has to re-earn, from the schema to the report exporter.

Choose your isolation level with real numbers

The classic three options — database per tenant, schema per tenant, shared tables with a tenant column — get debated like religion. The deciding inputs are boring: how many tenants, how big is the biggest one, what does your ops team look like. A shared schema with a tenant_id on every row, enforced relentlessly, is the right default for hundreds of small-to-medium tenants. You revisit it when one tenant outgrows the herd — not before.

The tenant id must be impossible to forget

Anywhere a developer can write a query without a tenant filter, one day a developer will. The fix is structural, not disciplinary:

  • Resolve the tenant once, at the edge — from subdomain, token claim or header
  • Carry it in request context, never as a hand-passed parameter
  • Apply it in a repository layer or query middleware, so business code physically cannot skip it
  • Test cross-tenant leakage as its own test class, like you test auth

Branches make it a tree, not a list

Retail tenants are not flat: one client, many branches, staff scoped per branch, inventory sometimes shared and sometimes not. Model the hierarchy explicitly from day one. Bolting branch scoping onto a flat tenant model later touched every module we had.

Back office is a tenant too

The super-admin panel that operates across tenants is the most dangerous surface in the system. It gets its own roles, its own audit log, and the same query discipline — except its "tenant" is explicitly chosen per action, never implicit. Most real-world leaks are not hackers; they are an admin screen with a forgotten filter.

Enjoyed this one?

I write about what I build. Let's talk about yours.

Get in touch