Tenants share one cluster and the largest is a thousand times the smallest. How do you place them?
Multi-tenant placement at scale should use measured resource cost, not tenant count. Keep the long tail in shared pools, move heavy tenants to reserved or dedicated capacity, and design tenant migration as a normal operation because every placement decision ages quickly.
What the interviewer is scoring
- Whether tenant cost is treated as several resources rather than one number
- Does the candidate notice that the biggest tenant may not fit on any single node, and say what follows
- That correlated peaks are considered, so the peak of sums is used rather than the sum of peaks
- Can they separate what placement bounds from what only a per-tenant quota can bound
- Whether moving a tenant is designed as a routine operation rather than an escalation
Answer
Short answer
Place tenants by actual CPU, storage, request rate and isolation needs: shared for small tenants, reserved for medium tenants, dedicated or internally sharded for whales, with cheap migration paths.
Counting tenants is placement by coin toss
Take the ratio at face value. If the smallest tenant costs one unit and the largest costs a thousand, then a node holding fifty small tenants carries fifty units, and a node holding forty-nine small tenants plus the large one carries a thousand and forty-nine. Both nodes hold fifty tenants. One is idle and one is on fire.
So the first thing to fix is the unit. Tenant count tells you nothing about load when the population spans three orders of magnitude, and any scheduler working from it is distributing names rather than work.
The unit is also not a single number. A tenant that stores two terabytes and serves ten requests a second is nothing like a tenant that stores two gigabytes and serves ten thousand, and they exhaust different things. Measure per tenant at least: request rate, write rate, stored bytes, working-set bytes and the shape of the expensive queries. Then place against whichever resource your nodes run out of first, and record the others so you notice when the binding constraint changes.
Three tiers, because one policy cannot span a factor of a thousand
The population is not uniform, and the honest design admits that by treating segments differently.
- The long tail goes in a shared pool. Hundreds or thousands of small tenants per node, densely packed, no reservation, cheap. This is where the economics of multi-tenancy live, and the tail is usually most of the customer list.
- The middle gets reserved capacity in a shared cluster. Still co-located, but with a floor guaranteed to them and a ceiling enforced against them. They are large enough to hurt neighbours and too small to justify their own infrastructure.
- The largest gets its own. Once a tenant's peak approaches a meaningful fraction of one node, co-location has no upside left: it cannot be packed with anything, and every incident it causes is somebody else's outage too.
The thousand-times tenant needs one more sentence, and it is the one candidates skip. If that tenant's load exceeds what a single node can serve, dedicating a node to it does not solve anything. It has to be sharded internally, across its own set of nodes, by some key inside the tenant. Isolation and scale are separate problems, and giving a tenant its own hardware only answers the first.
Pack largest first, and leave room to be wrong
Placement is bin packing, and the practical algorithm is unglamorous: sort tenants by cost descending and put each into the fullest node that still has room. Taking the big ones first works because a large tenant placed late has nowhere to go, whereas small tenants fit into whatever gaps remain. Doing it the other way around is how you end up with eleven nodes at ninety per cent and one tenant that fits nowhere.
Then refuse to pack to full. If nodes run at ninety per cent, a tenant doubling in a week forces an emergency move, and emergency moves are how shared clusters get their reputations. Targeting something closer to two thirds means the ordinary case of a customer growing is absorbed rather than escalated. The spare third is not waste. It is the budget for being wrong about next quarter, and it is cheaper than the alternative.
The peak of sums, not the sum of peaks
Two tenants whose traffic peaks at the same moment cost you the sum of their peaks. Two whose peaks fall twelve hours apart cost you barely more than the larger of the two. Placement that ignores the time dimension gets this wrong in a very specific way: it co-locates customers in the same industry and the same timezone, because they signed up together and look similar in the size column, and their peaks land on top of each other.
So keep a shape per tenant, not a scalar. An hour-by-hour profile over a week is enough. Place tenants whose profiles complement each other and you can run the same nodes hotter with less risk. A candidate who brings this up unprompted is usually one who has watched a cluster brown out at nine in the morning for three consecutive Mondays.
Seating a restaurant is the closest everyday version. Parties of two and parties of forty need different tables, and the good manager also thinks about when each party arrives. The analogy stops working at the end of the evening: diners leave and free their table, while a tenant occupies its capacity permanently, so every placement decision compounds instead of resetting.
Placement bounds the blast radius; only quotas bound the rate
Placement decides who suffers when a tenant misbehaves. It does nothing to stop the misbehaviour. A tenant in the shared pool that starts issuing expensive queries will consume whatever the node has, and the only thing standing between that and everybody else on the node is an enforced limit.
So the two mechanisms pair up. Per-tenant concurrency caps, request rate limits, query timeouts and a bound on connections keep one tenant from taking the whole node. Placement decides how many tenants are exposed if those limits are set wrong. Neither substitutes for the other, and a design with careful placement and no quotas is a design where the first badly-written report a customer runs becomes a shared incident.
Fair queueing is worth naming here rather than plain rate limiting. A shared pool wants each tenant to get service in proportion to its entitlement when the node is saturated, which is a scheduling property, not a threshold. Round-robin across per-tenant queues gets most of the benefit and is simple to explain, which matters when the behaviour has to be justified to a customer.
Every placement decision expires
The thing worth optimising is not the initial layout. It is the cost of changing it. Tenants grow, shrink, churn and change shape, so any static assignment is stale within a quarter, and a system where moving a tenant is a scary manual project will simply never rebalance.
Make tenant movement a routine, automated, reversible operation: copy the tenant's data to the destination, stream its changes, freeze that one tenant briefly, verify, flip its routing entry. The freeze affects one customer for a moment rather than a cluster for an hour. Once that primitive exists and is exercised weekly, placement stops being a decision you have to get right and becomes a control loop you can tune, which is the difference between a cluster that ages well and one that gets rebuilt every two years.
A shared cluster is not sized by how many tenants it holds. It is sized by the largest tenant it must absorb, the correlation between the peaks it hosts, and how quickly it can move a customer that has outgrown where you put them.
© 2026 Preptima. Originally published at preptima.com.
Likely follow-ups
- Two tenants on the same node both peak at 09:00 local time. What signal would have stopped you putting them together?
- A tenant grows tenfold in a fortnight. At what point does your system decide to move it, and who approves that?
- How do you charge for a shared pool where one tenant's queries cost twenty times another's?
- What does a tenant on dedicated infrastructure lose that a tenant in the shared pool keeps?
Related questions
- A customer reports seeing another company's records in your admin console. Walk me through the first hour, and then tell me what you change so this class of bug cannot happen again.hardAlso on tenant-isolation and multi-tenancy4 min
- How do you isolate tenants in a shared vector index?hardAlso on multi-tenancy and tenant-isolation6 min
- Your largest customer costs more to serve than they pay you. What do you do about that architecturally?hardAlso on multi-tenancy and capacity-planning6 min
- A maintenance script updates your permissions table and every user in one tenant can suddenly edit everything. What should have stopped that, and how would you have found out?hardAlso on multi-tenancy6 min