Lesson 5 / 32

Tiering Tenants by Plan

Place tenants on different deployment models according to their plan, and route each tenant to the right resources through one lookup.

By · 15 years in web development

Different tenants, different homes

Most SaaS products do not choose one model for everyone. A common pattern is tier-based placement: free and small paid tenants live in the pool, because they are many, small and price-sensitive; enterprise tenants who pay more, or who need stronger isolation for compliance, get dedicated databases or even dedicated stacks. This works only if the product code does not hard-code where a tenant lives. Instead, a tenant catalogue (part of the control plane) stores each tenant's plan, placement and region, and a small routing layer looks it up on every request or caches it. Upgrading a tenant from pro to enterprise then becomes a data migration plus a catalogue update, not a code change. The price of tiering is that you now run several deployment shapes, so automation for provisioning and migrations must handle all of them.

Plan decides placement

A toy catalogue lookup. In a real system the mapping lives in a database table and the result is cached.

# Which deployment model does each plan get?
PLAN_MODEL = {
    "free":       "pool",    # shared app + shared database
    "pro":        "pool",
    "enterprise": "silo",    # dedicated database (and maybe compute)
}

def placement(tenant_id: str, plan: str) -> str:
    model = PLAN_MODEL[plan]
    if model == "silo":
        return f"db-{tenant_id}"       # one database per tenant
    return "db-shared-01"              # many tenants share this one

for tid, plan in [("t_acme", "pro"), ("t_bigbank", "enterprise"), ("t_zen", "free")]:
    print(tid, plan, "->", placement(tid, plan))

Output:

t_acme pro -> db-shared-01
t_bigbank enterprise -> db-t_bigbank
t_zen free -> db-shared-01

Keep the code paths identical

Silo and pool tenants should run the same application code; only the connection target differs. If enterprise tenants get special code branches, you are drifting towards maintaining separate products, which removes most of the SaaS advantage.

Quick check: Why should the tenant-to-database mapping live in a catalogue rather than in application code?

  • So tenants can be moved between tiers by changing data instead of redeploying code
  • Because databases cannot be addressed by name from code
  • So that every tenant must use the same database
  • Because catalogues make SQL queries faster
Answer

So tenants can be moved between tiers by changing data instead of redeploying code — A catalogue makes placement a data decision. Moving a tenant becomes migrate-then-update-catalogue, with no code change or redeploy.