DEV Community

Cover image for Stop Calling Tribal Knowledge “Collaboration”
Valentyn Ivanov
Valentyn Ivanov

Posted on

Stop Calling Tribal Knowledge “Collaboration”

Developers have a strange relationship with documentation.

We love well-documented libraries.

We appreciate clear APIs, useful examples, configuration references, migration notes, architecture diagrams, and a README that tells us what we actually need to know.

Then we look at our own codebase and suddenly documentation becomes outdated.

“The code should explain itself.”

“If you need to know something, just ask.”

And sometimes teams take this even further.

They turn the lack of documentation into a virtue. The argument goes something like this:

We don’t document everything because we want developers to communicate with each other.

At first, this sounds reasonable. Software development is collaborative. People should talk. Knowledge shouldn’t live in isolated silos.

But there is a problem. Asking the same question for the tenth time is not collaboration. It is a missing database query.

Meet John and Jack

John is working on a service he hasn’t touched before. He sees this in the deployment configuration:

MAGIC_SERVICE_MODE=2

There is no comment. No documentation. No example. No explanation in the repository.

But Jack knows what it means. Jack implemented it three years ago. Unfortunately, Jack lives in another time zone. So John asks him on Slack. Then John waits. Maybe for an hour. Maybe for six.

Eventually Jack wakes up, reads the message, remembers what the variable means, and answers.

John continues working. Problem solved. Except it isn’t.

Two weeks later, Mary encounters the same variable. She asks Jack. A month later, Peter joins the team. He asks Jack. Then a production issue happens and someone from another team asks Jack.

At this point we should stop pretending this is a healthy communication culture.

Jack has become infrastructure.

More specifically, Jack has become a very inefficient distributed database with terrible availability characteristics. And Jack is constantly being interrupted by SELECT queries.

Communication Has a Cost

There is a tendency in software teams to treat communication as free.

It isn’t.

Every question has at least two costs.

The person asking has to stop what they are doing and wait for an answer. The person answering has to stop what they are doing and reconstruct the context.

Sometimes that cost is tiny. Sometimes it destroys half an hour of concentration. Now multiply this across a team.

“What does this environment variable mean?”

“Which database do we use in staging?”

“Why is this timeout set to 17 seconds?”

“Can I run this service locally?”

“Which of these three endpoints is still supported?”

“Why can’t this component be deployed independently?”

“Who owns this?”

If these questions are asked once, that is normal. If they are asked repeatedly, the problem is not communication. The problem is missing documentation.

Documentation Does Not Replace Communication

This is the part that often gets lost. Good documentation is not an alternative to communication. It creates space for better communication. There are things developers absolutely should discuss.

Should we split this service?

What consistency guarantees does this protocol need?

Should this API be synchronous or asynchronous?

What are the failure modes of this architecture?

How do we migrate this without downtime?

What trade-off are we making between latency and complexity?

These are valuable conversations because the answer does not already exist. The participants are creating something new together.

That is collaboration.

Asking someone what an environment variable means is not collaboration. It is information retrieval. And information retrieval should usually not require another human being.

Tribal Knowledge Feels Fast Until It Doesn’t

A poorly documented team can actually feel very productive for a while. Everyone knows everything. The original developers sit next to each other. Questions get answered in seconds. Decisions happen verbally. Nobody wastes time writing things down. Great velocity.

Then the team grows. People leave. People work remotely. A service moves to another team. Someone goes on vacation. Someone gets sick. A new developer joins. Now the invisible dependency graph becomes visible. Half the system depends on three people remembering why things work the way they do.

The organization discovers that what looked like velocity was actually borrowing against the future.

And now the interest is due.

“The Code Should Be Self-Documenting”

There is some truth in this idea.

Good names matter. Clear abstractions matter. Readable code matters. Comments should not explain what perfectly obvious code already says.

But code can only explain so much.

Code can tell you what it does. It often cannot tell you why it exists. It cannot always explain why another seemingly simpler approach was rejected. It cannot explain operational assumptions. It cannot explain which weird production incident caused that strange validation rule. It cannot tell a new developer which parts of the system are historical leftovers and which ones are intentional architecture.

And it certainly cannot explain what MAGIC_SERVICE_MODE=2 means to someone who does not already know.

The best code and the best documentation solve different problems.

“But Documentation Gets Outdated”

Yes.

So does code. So do tests. So do dependencies. So do deployment scripts.

We do not stop writing tests because they might become outdated. We maintain them because they are useful.

Documentation should be treated the same way.

The real question is not whether documentation can become stale. The question is whether the cost of maintaining it is lower than the cost of repeatedly rediscovering the same knowledge.

For important parts of a system, the answer is very often yes.

And documentation does not need to mean a thousand-page specification. Sometimes the right documentation is five lines next to the configuration. Sometimes it is a short ADR. Sometimes it is a diagram. Sometimes it is a README explaining how to run the service. Sometimes it is one sentence saying: MAGIC_SERVICE_MODE=2 enables compatibility mode for the legacy billing pipeline. Do not change it without coordinating with Billing.

That sentence might save hours of future interruptions.

The Goal Is Not More Documentation

This is important too.

The goal is not to produce documentation for its own sake. Nobody needs another abandoned wiki full of pages nobody reads.

The goal is to remove unnecessary dependence on human memory. Write down the things people repeatedly need. Write down the things that are surprising. Write down decisions whose reasoning will otherwise disappear. Write down operational knowledge that someone will desperately need at 2 AM. Write down information that crosses team boundaries.

And keep it close to the thing it describes whenever possible.

Documentation is not bureaucracy when it prevents the same question from being asked fifty times.

It is a productivity tool.

Let People Talk About New Things

A healthy engineering culture should absolutely encourage communication.

But communication is a limited resource.

Spend it well.

Do not spend your senior developer’s attention explaining for the twentieth time how to start the staging environment.

Do not make a new engineer wait until someone in California wakes up to understand a configuration flag.

Do not confuse access to tribal knowledge with collaboration.

Document the things we already know. Then use the time we saved to discuss the things we don’t know yet.

That is where communication becomes valuable.

Documentation doesn’t replace communication. It buys time for better collaboration.

Top comments (0)