Forecasting · 8 min read

Shrinkage: the number everyone configures wrong

Where it belongs in the calculation, why multiplying instead of dividing leaves you short by exactly the square of your shrinkage rate, and how to check yours in ten minutes.

Shrinkage is the least interesting number in workforce management and the one most likely to be quietly wrong. It is a single percentage, it sits in a config screen, nobody owns it, and it silently scales every requirement you produce.

There are three separate mistakes to make with it. Two are arithmetic and one is definitional, and most operations make at least one.

What shrinkage is, precisely

Shrinkage is the proportion of paid, rostered time that is not available to handle contacts. That is the whole definition, and the word “rostered” is doing all the work.

Erlang C and every other queueing model return a number of agents who must be productive and available during the interval. Nobody is productive and available for the whole of their shift. Shrinkage converts a productive requirement into a rostered requirement.

Rostered FTE = required productive agents ÷ (1 − total shrinkage)

It is a division, not a multiplication, and it happens outside the queueing maths, never inside it. Those two sentences are the entire article; everything below is why they matter and what it costs when they are broken.

Mistake one: multiplying instead of dividing

This is by far the most common, and it is seductive because it sounds right. “We lose 30% to shrinkage, so add 30%.”

Take the standard example: 250 contacts, 30-minute interval, 240s AHT, 80% in 20 seconds, 85% occupancy cap. The productive requirement is 40 agents.

MethodCalculationRostered FTE
Correct: divide40 ÷ (1 − 0.30)57.14
Wrong: multiply40 × 1.3052.00
Shortfall5.14 FTE (9.0%)

Five people short on a single half-hour interval, from an error that looks like a rounding preference. And it does not stay small:

ShrinkageCorrect (divide)Wrong (multiply)Short byUnderstated by
10%44.4444.000.44 FTE1.0%
20%50.0048.002.00 FTE4.0%
30%57.1452.005.14 FTE9.0%
40%66.6756.0010.67 FTE16.0%
50%80.0060.0020.00 FTE25.0%

Look at the last column: 1%, 4%, 9%, 16%, 25%. Those are the squares of 0.1, 0.2, 0.3, 0.4 and 0.5. That is not a coincidence; it falls straight out of the algebra:

1 − (1 + s)(1 − s) = 1 − (1 − s²) =

The rule worth remembering: multiplying instead of dividing understates your rostered requirement by exactly the square of your shrinkage rate. At 30% shrinkage you are 9% short, permanently, on every interval, in a way no amount of intraday heroics will fix.

This is why the error survives so long. At 10% shrinkage it is 1% and invisible. It only becomes structural at the shrinkage levels real contact centers actually run at, and by then it has been in the model for years and everyone has adapted around it by adding a fudge factor somewhere else.

Mistake two: applying it twice

The second arithmetic error is double-counting, and it goes the other way: it inflates.

It happens when shrinkage lives in more than one place: in the requirement calculation and again in the scheduling layer, or in a global setting and again in a queue-level override, or once by the forecasting team and once by the person building the roster. Each layer looks correct in isolation.

Same example. Correct rostered requirement is 57.14 FTE. Apply the 30% a second time and you get 81.63 FTE: you are now rostering 24.5 FTE more than the interval needs, a 43% over-roster.

Double-counting is easier to catch than the multiply error because it produces numbers that look obviously wrong to anyone with operational instinct. The dangerous version is a partial double-count: 30% in the requirement and 8% of “unplanned” shrinkage added in scheduling, where the total is wrong but not absurd, and it gets rationalised as conservatism.

Diagnostic: pick one interval and trace the requirement from raw forecast to rostered FTE, naming every place a percentage is applied. If you cannot enumerate them from memory, you have more than one.

Mistake three: not agreeing what is in it

The definitional error. Two people quote “30% shrinkage” and mean different things, so the number cannot be benchmarked, argued with, or improved.

The useful split is by whether the time was plannable:

CategoryTypically includesBehaviour
PlannedBreaks, lunch, training, coaching, team meetings, scheduled off-phone workKnown in advance, can be moved. Belongs in the schedule as events, and can be shifted intraday.
UnplannedAbsence, sickness, lateness, unscheduled aux, system downtimeStatistical. Cannot be scheduled around, only provisioned for.
Not shrinkageVacancy, attrition gaps, agents in nesting not yet taking contactsHeadcount problems. Putting them in shrinkage hides them from the people who can fix them.

That last row causes the most trouble. Rolling vacancy into shrinkage makes the requirement come out right, which is exactly why it is tempting, and it converts a recruitment problem into a planning parameter, where nobody will ever look at it again. Keep establishment gaps visible as establishment gaps.

A related trap: paid versus unpaid breaks. If lunch is unpaid it is not rostered time and does not belong in shrinkage at all; it is simply not part of the shift. Including it inflates shrinkage and over-rosters. This single item accounts for a large share of the difference when two centers compare shrinkage figures and cannot reconcile them.

One rate, or many?

A single global rate is almost always wrong, because shrinkage is not flat across the week. Monday morning absence is not Wednesday afternoon absence. Training is clustered. Breaks are concentrated in the middle of the day by definition.

The pragmatic ladder, in the order most operations should climb it:

  1. One global rate. Better than nothing. Wrong at both ends of the day.
  2. Rate by day of week. Cheap, and captures most of the absence pattern.
  3. Planned modelled explicitly, unplanned as a rate. The right answer for most operations: breaks, lunch and training exist as real schedule events at real times, and only the statistical part is a percentage.
  4. Interval-level profiles per queue or site. Worth it at scale or where sites genuinely differ.

Step three is the big one. Once planned shrinkage lives in the schedule as events rather than in a percentage, break optimisation becomes possible: you can move lunches off the peak, which is frequently worth more than any change to the rate itself.

Sanity-check yours in ten minutes

  • Reconcile top-down. Total paid hours for a past week, minus hours actually logged in a contact-handling state, divided by total paid hours. Compare to your configured rate. A gap over about three points means the config is stale or something is double-counted.
  • Check the divide. Take one interval’s productive requirement and its rostered requirement. Divide the second by the first. At 30% shrinkage that ratio must be 1.43, not 1.30. If it is 1.30, you have the multiply error.
  • Count the applications. Trace one interval end to end and name every place a percentage is applied. More than one is a bug.
  • Test the extremes. Set shrinkage to 0% and confirm rostered equals productive exactly. Set it to 50% and confirm rostered is exactly double. Any tool that fails these is not dividing.
  • Ask what is inside it. If vacancy or nesting is in there, pull it out and watch the rate drop to something you can actually benchmark.

How sensitive is it, really?

On the same 40-agent interval:

Shrinkage25%28%30%32%35%
Rostered FTE53.3355.5657.1458.8261.54

Five points of shrinkage (the difference between a well-run and an averagely-run operation) is 8.2 FTE on a single interval, and it compounds across every interval you staff. Shrinkage is the highest-leverage number in the model precisely because it is the one nobody defends in review.

Which is the real argument for getting it right: not that 30% is better than 32%, but that a number you cannot decompose is a number you cannot improve.

Check your own numbers

The calculator applies shrinkage where it belongs, and shows you it did.

Enter your interval and shrinkage rate and the free Erlang C calculator returns both the productive requirement and the rostered FTE, with the division shown, so you can check your own tool against it in about thirty seconds.

Open the Erlang C calculator

Related: Erlang C explained · running an intraday loop

calculation_trace · engine v2.4.1 · interval 11:00–11:30 volume 489 contacts (revised forecast) aht 312 s workload 84.8 erlangs target 80% in 20s (SL) · occupancy cap 0.88 erlang_c raw agents → 93 (SL 83.3%) occupancy_cap 0.88 → 97 (cap binding, 93 leaves 91.1%) shrinkage 0.27 applied → required 132.9 FTE scheduled 129 − OOO 4 → net 125 → 91 productive → predicted SL 73%