RepoSCALE-SPECIFICDOMAIN-SPECIFICCONTESTED

Bus Factor

Critical knowledge living in one head is a design risk, not an HR risk. It shows up in the estimate for every change to that area, long before anyone leaves.

The requirement, the obvious build, and why it breaks

Every lesson starts where the work starts: someone asked for something, and the first implementation that comes to mind survives until the requirement changes.

The question

How many people would have to be unavailable before we could not safely change this part of the system, and what does the answer cost us today?

The requirement

The payments integration has one engineer who understands it. She is excellent, she is fast, and every change to payments goes through her. The team wants to know whether this is a problem.

The obvious build

It is fine. She is not leaving, and if she did we would read the code. Code is the documentation; anybody competent can pick it up.

Why it breaks

The cost is being paid now, not at departure. Every payments change already queues behind one person's calendar, and every estimate for payments work is really an estimate of her availability (Change Amplification).

How it breaks as requirements change
  • The cost is being paid now, not at departure. Every payments change already queues behind one person's calendar, and every estimate for payments work is really an estimate of her availability (Change Amplification).
  • Reading the code recovers what it does. It does not recover why the retry window is 47 seconds, which providers silently deduplicate, or which of the three reconciliation paths is load-bearing — and those are the parts that make a change safe.
  • It also distorts design. Nobody proposes restructuring payments, because nobody else can evaluate the proposal, so that area stops receiving the design attention every other area gets (Review as Design Feedback — and Why It Arrives Too Late).
  • The risk is not only departure. Holiday, illness, parental leave and a promotion into a different team all produce the same outage, and three of the four are certainties.
  • And it is unfair to her. Being the only person who can do something is a career trap: it makes you indispensable in the specific sense of being un-promotable and un-absent.
RequirementConstraintsInvariantsResponsibilitiesBoundariesInterfacesStateDependenciesFailureImplementationTestsFeedbackEvolution

What limits the solution, and what must never stop being true

This domain leads with these two. A design that ignores its constraints is not a design, and an invariant nobody named is one nothing is protecting.

Constraints
  • She is also the fastest way to ship payment work, so any fix costs throughput now against risk later.
  • The knowledge is genuinely hard: provider quirks, reconciliation rules, three years of edge cases discovered in production.
  • You cannot mandate that someone transfer tacit knowledge; you can only create situations where it transfers as a side effect of work.
Invariants
  • For any part of the system that must keep working, at least two people can safely make a change to it — where "safely" means they would notice if it broke (Characterization Tests).
  • The reasoning behind non-obvious decisions survives its author, in the repository rather than in a chat history (Decision Records).

Who owns what, and where the seams fall

Responsibilities decide boundaries; boundaries decide what an interface has to say.

Responsibilities
  • The team owns knowing where its single points of failure are. That is an inventory, and it takes an afternoon.
  • The expert owns transferring the reasoning as a side effect of work — pairing on the next change, writing the record for the next decision — not producing a documentation project.
  • The organisation owns making the transfer affordable, because it costs throughput and will not happen if the plan assumes her usual velocity (The Cost of Change).
  • The second person owns actually doing a real change in the area, because reading a walkthrough transfers very little compared with making one change and having it reviewed (Knowledge Sharing).
Boundaries
  • The seam that reduces bus factor is the same seam that reduces coupling: a module with a narrow, well-named interface can be used safely by someone who does not understand its internals (Designing a Module Interface).
  • Where the knowledge is genuinely irreducible — a provider's undocumented behaviour — the boundary to draw is around it, so that the un-transferable part is small and everything outside it is ordinary code (Encapsulation Radius).
  • Tests are a knowledge boundary too: a characterization test encodes "this is what the system does" in a form that survives its author, which is exactly what the code does not (Characterization Tests).

Pricing the second person

The argument for spreading knowledge is usually made as a risk argument — what if she leaves — and it loses, because the risk is speculative and the throughput cost is immediate. The stronger argument is that the cost is already being paid.

Price the same change under both arrangements and the queue becomes visible. It is not on any diagram, it does not appear in any estimate, and it is the largest term in the elapsed time for anything touching payments.

The payment provider changes its webhook signature scheme
The change

The provider is deprecating its old signature format with a hard cutoff in eight weeks. The code change is about two days of work.

One engineer understands payments; reasoning is in her head; no characterization tests around reconciliation
payments/webhookspayments/reconciliation
teststwo integration tests, both written by her, both asserting the current format
2 modules · 1 test file

Two days of work, and four weeks of elapsed time, because it has to fit around everything else she owns. If the cutoff had been four weeks instead of eight, this would have been an escalation. And if she had been on leave, the change would have been made by someone who could not tell whether reconciliation still worked.

Two engineers can change payments; the non-obvious reasoning is recorded next to the code; characterization tests pin reconciliation behaviour
payments/webhooks
testswebhook signature testsreconciliation characterization suite (unchanged, and that is the point)
1 module · 2 test files

Two days of work, done by whoever has capacity, in the week it arrives. The characterization suite is what makes the second engineer's change safe: they do not need to understand reconciliation, they need to know they did not break it.

what it cost Getting to the second state cost roughly one extra person-week spread over three previous payment changes, paid at a time when it bought nothing visible, plus a characterization suite that took four days and tests behaviour nobody is proud of. It also cost some quality: the second engineer's changes are, honestly, not as good as hers, and two of them needed a second review round. That is the real trade — you are buying survivability with throughput and a little craft, and pretending it is free is why the argument usually fails.

What actually transfers, and what does not

Knowledge about a system is not one substance. Different kinds move by different mechanisms at wildly different costs, and almost every failed knowledge-transfer initiative fails by picking the cheapest mechanism for the most expensive kind.

The last row is the one that matters most and is addressed least. It is also the only row where the transfer mechanism is a change to the code rather than an activity.

  • The cheapest mechanisms — documents and walkthroughs — address the kinds that transfer most easily anyway, which is why documentation sprints feel productive and change little.
  • Characterization tests are the one intervention that converts row three from tacit into mechanical: you no longer need to know which path is load-bearing if a test tells you when you broke it (Characterization Tests).
  • The last row does not fully transfer, and a design that requires it is a design with an irreducible bus factor. That is the argument for making the un-transferable part as small as possible (Encapsulation Radius).
Kind of knowledgeExample in paymentsWhat transfers itWhat does not
What the code doesThe webhook handler validates then enqueuesReading the code; it is already thereA wiki page restating it, which then goes stale
Why it is like thatThe retry window is 47s because the provider deduplicates within 45sA comment at the constant, or a decision recordAnything not in the repository — chat, tickets, memory
How to change it safelyWhich reconciliation path is load-bearingMaking a real change with review; pairing on itA walkthrough, a demo, or a recorded talk
What it does in productionWhich failure looks like a provider outage and which looks like oursOn-call rotation; reading real incidentsA runbook alone, which describes the anticipated failures only
Tacit judgementWhen a discrepancy is worth stopping the release forTime, several incidents, and someone to disagree withNothing else. This is the part that is genuinely slow

A transfer that actually finishes

LIFETIME-SPECIFICFor a system with a known short remaining life — being replaced next year, a campaign platform, an internal tool with a sunset date — a bus factor of one is often the correct economic answer, and spending three weeks spreading knowledge that will be discarded is waste. The calculation flips entirely for anything that must be maintained for a decade, where the expert will certainly not be there for all of it.

The reason most of these efforts fail is that they have no completion criterion, so they end when attention moves on. Every step below has an observable outcome, and the last one is the only proof.

The sequencing matters as much as the steps: building the safety net before the second person makes a change is what makes their first change survivable, and doing it in the other order is how a knowledge-transfer initiative causes an incident.

From one expert to a system that survives a holiday
  1. 1
    Inventory

    List each area and who has made a substantive change in the last year. Areas with one name are the candidates.

    fails by Using commit counts, which count dependency bumps and formatting as understanding.

  2. 2
    Rank by consequence

    Risk is consequence times concentration. A one-person module under active change outranks a more complex one that is stable.

    fails by Starting with the most interesting area rather than the most dangerous one.

  3. 3
    Build the net

    Characterization tests around the behaviours nobody dares change, written by the expert while she is still here.

    fails by Skipping it, so the second person's first change is made without any way to tell if it broke reconciliation (Refactoring Without Tests).

  4. 4
    Record the why

    Three lines next to each non-obvious constant and decision, written when someone asks rather than in a documentation sprint.

    fails by Producing a wiki page about what the code does, which was never the missing part (Documentation Decay).

  5. 5
    Transfer through real work

    The second person makes the next actual change, with the expert reviewing rather than driving.

    fails by A walkthrough or a demo, which transfers a fraction of what one reviewed change does.

  6. 6
    Prove it

    The second person ships a change while the expert is unavailable. Small, deliberate, planned.

    fails by Never running the test, so the whole exercise remains a claim until an emergency evaluates it.

Steps three and four are the only ones that leave something behind in the repository, and they are the ones that survive both people leaving. Everything else is an activity, and activities decay.

How to build it

Most important first.

  • Inventory it first. For each area, list who has made a substantive change in the last year. The areas with one name are the finding, and the list is usually shorter and more alarming than anyone expects.
  • Fix the highest-risk area first, and define risk as consequence times concentration — not by which area is most complex. A one-person module that no longer changes is a much smaller problem than a one-person module under active development.
  • Transfer through work, not documents. The second person makes the next real change, with the expert reviewing; that transfers the reasoning in the only way that reliably works (Knowledge Sharing).
  • Capture the non-obvious in the repository as it comes up. The why for a 47-second retry window is three lines next to the constant, written at the moment somebody asks (Docs Close to Code).
  • Build the safety net in parallel: characterization tests around the behaviours nobody dares change are what make a second person's first change survivable (Refactoring Without Tests is the failure this avoids).
  • Then check it, by having the second person make a change while the expert is on holiday. Everything before this step is a claim.

What the next change costs

The field this whole domain exists for. A structure is only better if it makes the change after this one cheaper — and it is worth saying which changes it does not help.

Cost of the next change
  • Today, with one expert: a payments change costs her time plus the queue in front of it, and the queue is invisible to planning because it is not a resource anyone tracks. Elapsed time for a small change is measured in weeks when she is busy.
  • During transfer: the next payments change costs roughly twice as long, because two people do it and one of them is learning. That is the price, it is real, and it should be planned rather than absorbed.
  • After transfer: a payments change costs one person's time, drawn from two, with the review giving a second pair of eyes that actually understands the change. Elapsed time drops because the queue disappears.
  • On departure with no transfer: the next change costs an archaeology project — reading three years of code, provider documentation and incident history to recover reasoning that was never written down. Weeks to months, at the worst possible moment (What "Legacy" Actually Means).
What the recommended approach costs
  • Spreading knowledge costs throughput, immediately and measurably, in exchange for reducing a risk that may not materialise this year. That is a genuinely hard trade and it is usually resolved by pretending the risk is zero.
  • Rotation costs specialisation. The expert who has held payments for three years is genuinely better at it than two people who each hold it half the time, and some of that quality is lost.
  • Written records cost maintenance and go stale, and a stale record about payments is more dangerous than none, because the next engineer will believe it (Documentation Decay).

What can go wrong

Failure modes
  • A documentation sprint is commissioned. It produces a wiki page describing what the code does, which was never the missing part, and everyone considers the problem addressed.
  • The second person is named but never makes a change, so the knowledge remains theoretical and evaporates in six months.
  • The expert, reasonably, keeps taking the payments work because it is faster, and the plan silently reverts to the original state within a quarter.
  • The transfer succeeds and creates a second expert, and now two people own it and nobody else — an improvement that stops one step short of the goal.
  • Bus factor is measured by commit counts, which mistakes typing for understanding: the person who merged the dependency bumps looks like a second owner and is not.
Dependencies, and their direction
  • Change velocity in this area depends on one person's availability, which is a scheduling dependency that does not appear on any diagram and shows up in every estimate.
  • The transfer depends on there being real work to transfer through. Manufacturing a training exercise transfers a fraction of what an actual change does.
  • It depends on the code being changeable at all: if the area has no tests, the second person cannot make a safe change, so the safety net has to come first (The Legacy Change Loop).
Misreads
  • "So document everything." Documentation captures the least valuable layer — what the code does, which the code already says. What is missing is why, and why is captured by decisions and by pairing on real work (Comments).
  • "Bus factor is an HR concern." It is priced into every estimate for that area today. The queue in front of one person is a design property of how the knowledge is distributed, and it exists whether or not anyone leaves.
  • "High bus factor everywhere is the goal." Spreading everything evenly is expensive and slow, and some areas genuinely warrant a specialist. The goal is that the areas where a gap would hurt have at least two people, not that everyone knows everything (Over-Design and Under-Design).
  • "We measured it — three people have committed there." Commit counts measure typing. The question is who could safely change it, which is a different and much smaller set.

Testing it, and how it ages

What to test, and at which boundary
  • The real test is an absence test: can the second person ship a change in this area while the expert is unavailable? Run it deliberately, with a small change, rather than discovering the answer during a leave.
  • Characterization tests around the behaviours nobody understands are simultaneously the safety net and a way of recording the knowledge (Characterization Tests).
  • A recurring review of the ownership inventory — which areas have one name — is the cheapest monitoring available for this risk (Revisit Triggers).
How this design ages
  • Bus factor concentrates naturally. The fastest person in an area gets given the work in that area, which makes them faster, which makes them the obvious choice next time. Nobody decides this (Bus Factor is the compounding of an entirely reasonable local optimisation).
  • It gets worse as a system ages, because the knowledge that matters increasingly consists of accumulated edge cases rather than structure, and edge-case knowledge is the least transferable kind.
  • A team that routinely rotates areas has a slower ceiling and a much higher floor, and which of those matters depends on how long the system has to live (Changeability Is the Goal).

Where this applies

This domain's advice is contested more than most. These labels say what each claim is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view rather than a caricature.

  • SCALE-SPECIFICAt four engineers, a bus factor of one on some area is unavoidable arithmetic and the useful response is narrow: write down the reasoning, get characterization tests around the scary parts, and accept the rest. At fifty, a bus factor of one is a choice that a rotation could have fixed, and it is usually a symptom of work routing rather than of expertise. Above a few hundred, the risk moves from individuals to teams — a whole team being reorganised produces the same outage — and the mechanism becomes service ownership rather than pairing.
  • DOMAIN-SPECIFICWhere knowledge is genuinely deep and slow to acquire — a compiler backend, a physics engine, a clearing-house integration, cryptographic code — a bus factor of two is realistic and two years of effort, while in ordinary CRUD code it is a fortnight of deliberate rotation. The advice is the same; the timescale differs by two orders of magnitude, and treating them alike produces either panic or complacency.
  • CONTESTEDThe strongest opposing view: deep specialisation is how hard problems get solved well, and the cost of spreading knowledge is not just throughput but quality — two half-experts produce a worse payments integration than one full expert, and the failure modes of a mediocre payments integration are worse than the failure mode of an inconvenient holiday. This argument is strongest exactly where the stakes are highest, and the honest resolution is that the second person is there to make the system survivable, not to replace the specialist's judgement.

Where the depth lives

This domain teaches the codebase-level structure and hands the rest off.

Domains that do not exist yet
  • Testing & Reliability Engineering — the safety net that makes a second person's first change survivable is a testing problem, and the quality of your characterization coverage is the real upper bound on how fast knowledge can be spread.