Benjamin J. Sunter
Queueing theory, pointed at operating model design

Half a Day of Nothing

When a support function should sit central, and when it should split into dedicated pods. Companies flip between the two every few years and the debate almost never has a number in it. So I worked one out.

Benjamin J. Sunter · 6 minute read

The question

I keep watching companies flip between these two setups every couple of years, and I do not think either side is being unreasonable. The debate just runs on instinct, so it ends up wherever the most senior person in the room already was. Nobody brings a number.

So I worked one out. On the setup below it comes to about sixteen people, which is more than I expected.

Picture ten clients, each with support written into the contract. Give every client a named person who learns their quirks. Or build one shared team that covers everything and shares what they learn.

TEN PODSone named person per clientONE SHARED TEAMeverything, shared context?How big this box needs to be is the whole question.Squares are clients. Circles are people.
Every client wired to one person, or every client wired to everyone. How many people that shared box needs is what the rest of this works out.

Both are defensible, and which one is right for you changes as you grow.

Before any of the math, the obvious objection, and it is a fair one. When a client has a real emergency, nobody wants to be handed to whoever happens to be free and start explaining from the beginning. A dedicated pod buys them somebody who already knows, and that is worth something real. The math below does not price it, which is why there is a section near the end that tries to.

It is still worth doing the math first, because it is the only way to find out what that is costing you.

Or skip the argument and go straight to the calculator →

The two numbers that decide it

It comes down to two numbers, and you probably know both of them roughly already. The first is how much work each client generates, counted in people rather than tickets. The second is how much slower a shared person is on anything that needs client-specific knowledge. That second one is the whole case for pods, so it is the one worth pinning down. Call it the context penalty.

So: how big does the penalty have to be before pods are actually cheaper?

0%25%50%75%100%125%150%What most teams guess: about 30%150%73%60%29%20%13%12481632How many people’s worth of work each client generatesPenalty needed for pods to winPOOLING WINS IN HEREPODS WIN UP HERE
Read it like a waterline. If your real penalty sits below the curve, pooling is cheaper. Above it, pods are. The dashed line is what people guess when you ask them cold. Modeled throughout at 80% of requests answered inside two minutes; move that target and every number here moves with it.

At two people's worth of work per client, a shared person would have to take 73% longer. Not on the awkward tickets. On every single request, all day, forever.

Here is where that comes from. Each client sends enough work to keep two people busy, but two people cannot cover it. Requests arrive in clumps, so somebody has to be free when three land at once. A pod needs four: two working and two in reserve. Ten of those is twenty working and twenty in reserve. Forty people.

Pool all ten clients and the reserve gets shared, because one client's quiet hour covers another client's bad one. The same twenty people's worth of work now needs four in reserve instead of twenty. Twenty-four people.

So pooling starts sixteen ahead, and every one of those sixteen is reserve you no longer buy ten separate times. The shared team only gives that back by getting slow enough to need forty anyway, and 73% is how slow that is.

So almost none of it is about how fast anybody works. It is ten small teams each buying their own reserve, against one team that buys it once.

Most estimates of that penalty land around twenty or thirty percent. Even at thirty, you are nine people better off pooling.

Context penalty
knows the clientdoes not+73%

How much longer the same request takes when you do not know the client. The 73% above.

Occupancy
one working dayhandlingwaiting

How full the day is, handling rather than waiting. The 50% and 83% below.

One is about length, the other about fill. They move independently: a team can be busy all day and still slow on a client it does not know.

Why the gap is so big

None of this is because pooled people work faster. Dedicated people just spend more of the day waiting.

Those sixteen people were reserve, sitting in ten separate places waiting for a clump that mostly did not come.

0306090120301333%77%1 per client402450%83%2 per client704557%89%4 per client1108673%93%8 per clientTotal people needed, ten clientsTen pods added togetherOne pooled team of that sizeThe % inside each bar is how much of the day those people spend handling something.
Same work, same service level, two structures. The percentage inside each bar is how much of the day those people are actually handling something.

Which shows up as occupancy. The pod runs at 50%, the pooled team at 83%. Put that on a clock and it stops being a percentage.

A single eight hour day, one hour per blockIn a pod of four50% busy4h working, 4h waitingIn a pooled team83% busy6h 40m workingTen pods buy that empty half ten times over.Same clients, same service level, same work. The difference is what you pay for nobody to be doing.
This is not slack anybody enjoys. It is spread thin across the week as gaps between tickets, which is the worst form to receive it in.
If you run pods

Pods only cost you when the gap is empty. Give a pod a roadmap and hold them to it, and that 50% becomes the other half of their job. A BI pod with its own build queue is not idle between tickets, and most of the case for pooling them goes away. The pod that costs you is the one with nothing to do while it waits. Minimize shrink, not headcount.

Where pooling stops helping

Pooling works by covering one client's bad week with another client's quiet one. That only holds if the bad weeks fall in different places.

EVERY CLIENT PEAKS AT QUARTER ENDstaff to herePooling saves 31%PEAKS FALL IN DIFFERENT WEEKSstaff to herePooling saves 56%Gray lines are the ten clients. The teal line is what the pooled team actually sees.
The gray lines are the ten clients. The teal line is what the pooled team actually sees.
Check the calendar

Check the timing before you bank the saving. Good clients know their own seasonality and will tell you if you ask. If everyone spikes at quarter end you staff the peak either way, and about half the pooling advantage is gone before you hire anyone.

The burnout tax

I would not pool past about 85% occupancy. The math will take you to 93% and the service level still looks fine on paper. You pay in attrition instead of headcount, which is slower to spot and dearer to fix.

The second force, which is bigger

There is something else going on, and in some functions it dwarfs everything above.

Think about a reporting team. Somebody structures the query once and builds the report once, then filters it per client, so the second client costs almost nothing and neither does the tenth. Split that into pods and ten people end up building the same thing.

ONE CENTRAL TEAMbuilds each report once375 hoursTEN PODSeach build the same fifteen reports3,075 hours8.2xOne square is one report, built once by one person.
Fifteen reusable reports, twenty hours to build each, half an hour to run per client. Every pod you add rebuilds all fifteen.

Eight times the hours, for the same fifteen reports. And it turns up anywhere there is a build step: reporting, templates, playbooks, onboarding material, QA rubrics, tooling, the deck somebody rebuilds every quarter.

The standard failure

Centralize the build, not the queue. Central teams turn into backlogs where everything is urgent, and account teams quietly go back to their own spreadsheets. Two things stop it. Push the reusable layer out as self-serve, so the team builds capability instead of filling orders. And agree in writing who can jump the queue and who says so, with every function signed up. Skip that and centralizing just moves the arguing onto one team who now have to referee it. Worth its own piece, which it will get.

Where the two forces meet

Put the two together and you get one number you can do in your head. Reusable work does not carry a context penalty, because a query does not care whose data it is filtering. The slowdown only ever applies to the one-off part.

WORKING OUT YOUR REAL CONTEXT PENALTYan example team, 70% of whose work is reusableBuilt once, reused · 70%One-off · 30%only this part is slower30%of the work×40%slower on it=12%your real penalty
Only the one-off slice is slower, so that is the only slice the penalty applies to.

Say a third of the work is one-off, and a shared person is 40% slower on that part. Then the penalty you actually pay is 40% of a third. About 12%.

The crossover for a client this size was 73%. Twelve is nowhere near it, so you pool. That is the whole calculation, and it is what the sliders below are doing.

Try it with your numbers

Which side of the line are you on?

Everything runs in your browser. Nothing is sent anywhere.

Pool it
Ten pods
40
Pooled
26
Your real penalty
12%
Crossover
73%

What the math cannot price

Everything above is about cost, and cost is the easy part to measure. Three things sit outside it, and any one of them can be worth more than the headcount it saves.

Somebody to call. When a deal is on the line, nobody wants to start from the beginning with a stranger. A pod buys a named person, for the client and for your own account team. That is worth something real even when it is worth nothing on a spreadsheet.

Switching cost. The model assumes a request takes the same time whatever came before it. A pooled operator jumping from a regulatory edge case to an onboarding setup to a broken pipeline before lunch is paying a recovery penalty. Handling time never moved. It shows up as errors and rework, and there is no line for either.

Whose emergency wins. In a pod, priority is local and obvious. You have one client, so you work on their most urgent thing. In a pool, two critical requests arriving together is a judgement call somebody makes in public, every time.

If you want the pod

Buy the pod as a premium, with a number on it. None of this makes pods cheaper. It makes cost one axis instead of the only one. Work out what pooling saves you in people, then what one churned account is worth. If the saving is sixteen people and one account is worth more than sixteen, the numbers have told you to buy the pod. Then call it insurance and budget it as insurance. Argued as efficiency, it loses.

The second queue

Whoever picks it up should be able to decide it. The model counts handling time and nothing else. It cannot see a pooled person going off to find whoever owns the client before they can answer. That is a second queue behind the first, and it bites hardest on the calls you most want made fast. Either the person holding the ticket can decide, or your real penalty is well above what a stopwatch shows.

The whole argument, on one chart

Two questions put any function somewhere on this. How much work does one client generate, and how much of the work gets built once and reused. The line between the two regions is the crossover math from earlier rather than my opinion.

0%25%50%75%100%12481632POOL ITone team, shared contextDEDICATEa named pod per clientReporting & dashboardsTier-1 questionsBilling operationsOnboardingIncident responseRegulatory filingsEnterprise escalationCustom integrationHow many people’s worth of work ONE client generatesShare of the work that is built once and reusedTWO THINGS THAT OVERRIDE THE CHARTDoes the pod have a roadmap?If the gaps are filled with real work, the pooling saving shrinks and you can sit further right.Can you afford to lose the account?If not, buy the pod anyway. Call it insurance, put a number on it, and stop arguing efficiency.
The boundary is computed. The dots are illustrative, so put your own functions on it rather than trusting mine. Most of the field says pool. Dedicating only pays when one client is big enough to keep a team busy and almost nothing you do for them is reusable, which is a narrower corner than the argument usually assumes.

How to actually run this

This is roughly an afternoon if your ticket data is not a disaster, and most people can stop at step three.

  1. Pull 90 days of requests by client. Your ticket system already has this. Resolved items, grouped by account.
  2. Turn volume into people. Count times average handle time, divided by the hours one person actually works in that window. That is the bottom axis of the chart above.
  3. Tag fifty tickets reusable or not. Fifty, not ninety days of them. Enough to tell 20% from 70%. If reuse comes back high, stop here, centralize the build, and the rest of this barely matters.
  4. Estimate the penalty on the bespoke part. Compare handle time when somebody who knew the account picked it up against somebody who did not. If assignment has always been dedicated you will have to guess, which is fine. Move the slider above and see whether your guess even changes the answer. Usually it does not.
  5. Put each client on the chart. Load along the bottom, reuse up the side. Most will land well inside pool, and the ones that do not will be obvious.
  6. Price the premium on the ones that do not. Headcount difference times loaded cost, against the revenue on the accounts you would be moving into a queue. That is the number you take into the room.

There is a harder question sitting under all of this. Is the work genuinely bespoke, or has nobody ever built anything twice? That one is answerable from your own ticket history, and it is where I would start.

How the numbers were produced

Standard Erlang C, which is the queueing model contact centres are staffed with. Fifteen minute average handle time, a target of 80% of requests answered within two minutes, ten clients unless the slider says otherwise. Load is expressed in Erlangs, so "two per client" means each client generates two people's worth of pure handling time.

  • The crossover is found by raising the pooled handle time until pooled headcount matches ten pods at the same service level.
  • Staffing is integer, which makes the curve slightly lumpy at small loads. At 0.75 per client the crossover reads lower than at 1.0, purely because a pod cannot hire two thirds of a person. The chart plots the doubling scale to avoid implying a smoothness that is not there.
  • Erlang C assumes phone-shaped work: arrivals at random, no abandonment, service the moment somebody is free. Ticket and email work is deferrable, and deferrable work pools better still, so these figures understate the case for pooling in most support functions.
  • Shrinkage is excluded. It raises both structures by roughly the same proportion and does not move the crossover.