Greetings, traveler!
The bus factor measures how dependent a project is on a small number of people. If only one developer understands a critical feature, their absence can block maintenance, incident investigation, and further development.
Some teams try to reduce this risk through feature rotation. One team builds a feature, another implements the next change, and a third returns to it later. More developers work with the code, so knowledge should spread.
That assumption is often wrong.
The feature rotation solution
Feature rotation looks reasonable on paper. If the same team always works on the same domain, other developers have little reason to learn it. Over time, stable ownership can turn into dependency. Even a short absence may delay work because nobody else feels confident changing the code.
Rotation is supposed to prevent that. A new team takes the next task, studies the implementation, and learns enough to continue developing the feature.
In practice, the task is often completed without that learning taking place.
The incoming team finds an extension point, adds another condition or service, updates the tests, and moves on. They understand enough to deliver the ticket, but not enough to explain the feature as a whole.
The code has a new author. The project does not necessarily have another person who understands it.
Touching code is not knowledge sharing
A developer can change a module without forming a useful mental model of it. They may know which method to call, where to insert a new branch, and which test needs updating. That is enough for a local change. It is not enough to explain why the feature was designed this way or predict how the change will affect future work.
Understanding a feature means knowing which rules must always remain true, why certain boundaries exist, which compromises were intentional, and which parts cannot be changed in isolation.
Most of that context does not appear in a task description. It comes from design discussions, production incidents, failed approaches, business constraints, and years of small decisions.
The code alone rarely explains it.
How Frankenstein features appear
The damage usually accumulates through reasonable local decisions. The first team creates a model for the original requirements. Later, another team needs to support an exception. Reworking the model would take longer, so they add a boolean flag.
A third team introduces a similar scenario, but the existing flag does not quite fit. They add another state and handle it in a separate layer.
The next team cannot safely change either path, so it adds an adapter on top.
Each change may make sense when viewed through its ticket. The combined result is much harder to explain. State is now spread across an enum, several flags, server responses, and side effects hidden in different services.
Nobody intended to create a bad design. Every team chose the lowest-risk way to finish its own task.
The risk was simply transferred to the next team.
The ownership problem
Feature rotation often weakens long-term ownership. The incoming team is responsible for delivering the current change. It may not be responsible for the module next quarter. This changes the incentives.
A proper redesign costs the current team time. A quick layer on top creates most of its cost later. Under delivery pressure, the second option is easy to justify.
Stable ownership does not mean that one team must write every line of code. It means a stable team remains responsible for the feature as a coherent system, even when contributors change.
That responsibility includes its architecture, interfaces, behavior, technical debt, and direction of development. Other teams can contribute, but their changes still need to fit the existing model or replace it deliberately.
Without that continuity, every team arrives as a temporary contractor.
This does not improve the bus factor. It only distributes changes across more people.
Rotation is not the problem
Rotation can spread knowledge, but only when knowledge transfer is part of the work. Giving a task to another team is not enough. New developers need time to understand the domain, not only the requested change. Someone who already knows the feature should participate in design and review.
For larger changes, the teams may need to work together. An engineer can temporarily join the owning team, implement the change with them, and later bring that knowledge back.
This is different from handing over a ticket and expecting the codebase to teach itself.
A successful rotation should create another person who can reason about the system. Shipping a patch is only part of the result.
What actually improves the bus factor
A critical domain should have more than one engineer who can maintain it independently. That does not require removing stable ownership.
A practical model is to keep an owning team while ensuring that at least two engineers understand the domain well enough to investigate incidents, review significant changes, and design future development.
The second engineer should participate in meaningful work. Occasional small tickets are not enough. They need exposure to design discussions, production problems, tradeoffs, and architectural decisions.
Short documentation also helps. It should describe the module’s responsibilities, important invariants, domain boundaries, non-obvious decisions, and known constraints.
Documentation supports knowledge transfer, but it cannot replace direct involvement. A diagram does not transfer judgment.
Tests preserve expected behavior and make changes safer. They still cannot explain why the architecture looks the way it does. A well-tested Frankenstein feature is still a Frankenstein feature.
Measure understanding, not activity
Commit history is a poor measure of the bus factor. A better assessment is to ask who can explain how the feature works without relying on its original author. Who can investigate an unusual production issue? Who can review a significant change? Who understands which assumptions must remain valid? Who can design the next version of the feature?
If only one person can do these things, the bus factor is still one, even if ten teams have modified the code.
There is another possible outcome. After years of rotation, even the original owner may no longer understand the entire feature. Each team knows the layer it added, while nobody owns the complete model.
The organization has removed its single expert without creating several new ones.
A healthier balance
Teams need both knowledge distribution and architectural continuity. Too much concentration creates dependency on individuals. Too little ownership produces a codebase shaped by unrelated local decisions. Solving one risk by creating the other is not progress.
Feature rotation should leave the project with more people who understand the feature, not simply more names in its commit history.
New teams should not add code on top of an unfamiliar design and move on. They should understand the existing model, challenge it when necessary, and leave the feature easier to explain than before.
A codebase does not become safer because more people have changed it. It becomes safer when more people can change it without breaking the model that holds it together.
