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.
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 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.
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.
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).
- 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.
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.
- 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.
- 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.
- 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).
- 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 provider is deprecating its old signature format with a hard cutoff in eight weeks. The code change is about two days of work.
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 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 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 knowledge | Example in payments | What transfers it | What does not |
|---|---|---|---|
| What the code does | The webhook handler validates then enqueues | Reading the code; it is already there | A wiki page restating it, which then goes stale |
| Why it is like that | The retry window is 47s because the provider deduplicates within 45s | A comment at the constant, or a decision record | Anything not in the repository — chat, tickets, memory |
| How to change it safely | Which reconciliation path is load-bearing | Making a real change with review; pairing on it | A walkthrough, a demo, or a recorded talk |
| What it does in production | Which failure looks like a provider outage and which looks like ours | On-call rotation; reading real incidents | A runbook alone, which describes the anticipated failures only |
| Tacit judgement | When a discrepancy is worth stopping the release for | Time, several incidents, and someone to disagree with | Nothing else. This is the part that is genuinely slow |
A transfer that actually finishes
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.
- 1Inventory
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.
- 2Rank 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.
- 3Build 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).
- 4Record 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).
- 5Transfer 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.
- 6Prove 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
whyfor 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.
- 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).
- 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
- 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.
- 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).
- "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
- 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).
- 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.
- — 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.