"We'll add multi-tenancy once we have customers" is one of the most expensive sentences in software. It sounds prudent (don't build for scale you don't have yet) but multi-tenancy is not a scaling feature you bolt on later. It is a set of assumptions baked into your data model, your query patterns, and your billing logic from the first migration you write. Retrofitting it means touching almost everything, while the product is live and customers are on it.
The three platforms, itemised
We have taken three separate products through this retrofit in the last two years. The bill was different every time, but the categories were the same: data isolation, tenant-aware queries, and billing/metering. Here is roughly where the cost actually goes, not where people expect it to go.
- Data isolation: adding a tenant_id to every table is a day's work; auditing every query in the codebase to make sure it is scoped by that tenant_id, including the ones written by three former engineers, is weeks
- Query performance: indexes designed for a single-tenant access pattern degrade badly once you partition by tenant; expect to rebuild a meaningful fraction of your indexing strategy
- Noisy-neighbour isolation: one tenant's batch job should not be able to degrade another tenant's response times, which usually means rate limiting and resource quotas you never needed before
- Billing and metering: usage-based billing requires accurate, tenant-scoped event tracking from day one of the feature, not bolted onto an existing table after the fact
- Admin tooling: support and ops need tenant-aware views into the system, which is an entire internal application if it does not already exist
Why the early design is nearly free
Designing for multi-tenancy from the first sprint costs very little because you are making the same decisions you would make anyway, just with a tenant_id in mind instead of assuming a single owner. The expensive version is not the tenant column. It is the accumulated debt of every query, cache key, background job, and admin screen that was written without it, each of which now needs to be found and fixed individually, on a system customers are actively using.
If you are pre-revenue and genuinely might never have a second customer, this advice does not apply to you: build the single-tenant version and move fast. But if multi-tenant is the plan, even a plan for eighteen months from now, the tenant boundary belongs in the schema before the first row of real data goes in. It is the cheapest insurance policy in the entire architecture.
