Your week is a queueing system, and you are running it at 100% utilization

> $ stat metadata
Date: 2026.03.15
Time: 5 min read
Tags: [time-management, productivity, queueing-theory, focus, software-engineering]

A familiar shape in any backend team: the most senior engineer’s calendar is solid meetings, their review queue is two days deep, and the design doc everyone is waiting on has been “almost done” for three weeks. Nobody is slacking. The person is saturated, and saturation has a math to it that applies to people just as brutally as it applies to servers.

I resisted writing about time management for a long time because the genre is quadrant diagrams and morning routines. But scheduling attention is a systems problem, and the systems vocabulary explains the failure modes better than any productivity framework I have tried.

Utilization is the whole story

The core result from queueing theory: as utilization approaches 100%, wait time goes vertical. For a simple M/M/1 queue, expected wait scales with utilization over one minus utilization. The shape is what matters:

def relative_wait(utilization: float) -> float:
    return utilization / (1.0 - utilization)

for u in (0.5, 0.7, 0.8, 0.9, 0.95):
    print(f"{u:.0%} busy -> queue delay factor {relative_wait(u):.1f}")

# 50% busy -> 1.0
# 70% busy -> 2.3
# 80% busy -> 4.0
# 90% busy -> 9.0
# 95% busy -> 19.0

Going from 80% to 95% booked does not make you 15% less responsive. It makes everything queue five times longer. This is why we run production services at 70 to 80% utilization and treat sustained 95% as an incident. Then we book engineers wall to wall and act surprised when a one-hour request takes two weeks to surface.

The unplanned work always comes: the flaky test, the incident, the “quick question” from the team that consumes your API. A calendar with no slack does not reject that work, it queues it, and the queue is invisible until someone escalates.

Context switches are cache evictions

A senior engineer holding a complex change in their head is a warm cache: the invariants, the half-finished refactor, the reason line 240 cannot be simplified. An interruption does not cost the two minutes of the question. It evicts the working set, and the reload is the expense. Gloria Mark’s interruption studies at UC Irvine put the cost of fully returning to a task after an interruption at roughly 23 minutes.

Operating systems solved a version of this with interrupt coalescing: instead of taking an interrupt per network packet, batch them and handle the batch. The human equivalent is fixed communication windows. Slack and email get processed at set times, a few slots a day, and outside those windows the notifications are off. Not because messages do not matter, but because taking them one at a time means paying the eviction cost per message instead of per batch.

graph LR
    subgraph "Interrupt per message"
        A[Deep work] -->|ping| B[Reload context, ~23 min]
        B -->|ping| C[Reload again]
        C -->|ping| D[Reload again]
    end
    subgraph "Coalesced"
        E[Deep work block] --> F[Comms window]
        F --> G[Deep work block]
    end

People adapt to your pattern within a couple of weeks. The ones with a genuine emergency will phone you, and the fact that almost nobody ever does is its own data point about how urgent the pings were.

Little’s law applies to you

Little’s law: items in the system equal arrival rate times time in the system, L = lambda W. Rearranged for a person at fixed throughput: every additional concurrent project stretches the cycle time of all of them. Three “half-time” projects do not each proceed at half speed; the context-switch tax between them means each proceeds at a third speed or worse, and everything ships late together.

The fix is a WIP limit, and it is uncomfortable because it means saying “not yet” out loud instead of letting the queue say it silently. One major item in flight, two at most. The backlog does not shrink either way; the difference is whether cycle time stays short enough that anything finishes.

Priority inversion, calendar edition

The classic scheduling bug: a low-priority task holds a lock a high-priority task needs, and the high-priority task starves. The calendar version is the week eaten by small urgent items, each individually reasonable, while the important work (the design doc, the migration plan, the thing that determines next quarter) holds no time slot at all and therefore always loses.

Urgency is a property of the requester. Importance is a property of the work. A scheduler that sorts by urgency alone starves its most valuable job, so the important work has to hold reserved capacity: real calendar blocks that the urgent stream cannot preempt. This is the one piece of the classic advice (important versus urgent) that survives translation into systems terms, and the translation makes the mechanism visible: without reservation, starvation is the default outcome, not bad luck.

The loop I actually run

Fifteen minutes of admission control at the start of the day: decide what gets in and in what order, before the inbox decides for me. Two reserved deep blocks that interrupts cannot preempt. Comms coalesced into three windows. WIP capped at two major items, and I am honest that the second one degrades the first. A weekly look at where the time actually went, because utilization drifts up silently and the only correction signal is measurement.

None of this packs more into the day. That is the point. The goal is the same as capacity planning for any system: enough headroom that latency stays sane, few enough context switches that the cache stays warm, and a scheduler that refuses to starve the work that matters.

Frequently Asked Questions

Why does being fully booked make an engineer slower?
Queueing theory. As utilization approaches 100%, wait time grows without bound, because there is no slack to absorb variance. A fully booked calendar means every unplanned request, and there are always unplanned requests, queues for days or weeks. Servers are deliberately run at 70 to 80% utilization for the same reason.
How expensive is a context switch for a developer?
Gloria Mark's interruption research at UC Irvine measured roughly 23 minutes to fully return to a task after an interruption. The cost is not the two-minute question; it is reloading the working state the question evicted. Batching communication into fixed windows amortizes that reload the same way interrupt coalescing does in an operating system.
What does Little's law say about work in progress?
Little's law, L equals lambda times W, ties the number of items in a system to their average cycle time. At a fixed throughput, every additional concurrent project directly increases how long each one takes. Capping work in progress at one or two major items is not discipline for its own sake; it is the only way to keep cycle time short.

[ RELATED_LOGS ]

TTFB: -- ms LOAD: -- s PAYLOAD: -- kb