Originally published in September 2024! Updated with some minor edits plus a doodle.
Note: This article is about writing internal documentation, the documentation that you write for your teammates and perhaps other internal teams about the things you touch. It does not cover external documentation.
My first few years as a software engineer were all about learning fast and becoming as independent as possible. At some point I became the go-to team member for our support folks. This felt very good for awhile. Eventually my manager pushed me to document what I knew so that my teammates could benefit from it.
I didn’t want to do it. “I only know it so well because I had to figure it out”, I argued, “and I’m already behind on my own projects1”.
My manager patiently replied that, yes, sometimes we do learn best by doing and he understood that I was overloaded but that we would all benefit (myself included) by writing it down. I still didn’t do it. It took another year and an intense first experience leading a team for me to finally get it: Writing documentation is good and you should do lots of it. Today I’ll talk about why that is, how to do it well, and some common pitfalls you may encounter along the way.
Why bother?
Documentation benefits both the team and the writer. The benefits to the team are primarily that:
It increases team velocity. Engineers move faster when they don’t have to learn everything from scratch. New hires deliver their first tickets sooner. On-call issues are resolved earlier. Features are completed faster. The list goes on.
It improves the stability of your systems. Well documented systems are easier to support; the engineer on-call can find the information they need without calling the one person on their team who knows how The Thing works. Accurate documentation also enables more informed technical decisions which, in turn, contribute to more stable systems and features.
It’s a little easier to see how documentation benefits the team vs how it benefits the writer. There’s a reason, after all, that I didn’t start to invest in documentation until I took on my first team lead role. There are distinct benefits to the writer, though; I just didn’t appreciate them until I’d been doing it for awhile. Here they are:
It scales your impact. Your value isn’t just the code that you personally write. You have also enabled your teammates to write their own, better informed code. Likewise, you aren’t just supporting your team’s systems yourself; you are enabling others to do the same.
It’s high ROI. There are many ways to build knowledge on a team. Documentation is special, though, in that a one time investment (sit down and write for 15 minutes) can continue to yield returns well into the future. Documentation also tends to grow over time: future readers will find that one useful page you wrote about where all the log files live and then add to it as they go.
It frees you up to do other things. You don’t have to be pigeon-holed to a specific system because you’ve made it easier for others to learn it. You don’t have to be on-call 24/7 because other people can quickly find out what to do during an incident. You can take time off. You can focus on a new exciting project, switch teams or transition to a new role because folks will have access your knowledge without having direct access to you.
How to write useful documentation
Is it actually useful?
The first step to writing useful documentation is to determine whether it would, in fact, be useful. This part is fairly straightforward:
Did you have to learn this thing in order to do your job, either on your own or by talking to someone?
Is it anything short of breathtakingly obvious? Remember, something which is obvious to you may be news to your teammate. Write with the new hire in mind.
There are times when you shouldn’t document, though. Here are the big ones I can think of:
When the thing is already documented elsewhere. Link to existing documentation instead.
When it is against company policy. There are things you may not be permitted to document because the information itself is considered sensitive2. When in doubt, ask.
The thing you are documenting is in flux. Perhaps the thing you are documenting is being changed as we speak. By the time you finish writing your documentation, whatever you have written is simply wrong. If this is the case, hold off until the thing you are documenting reaches some stable point. “Stable point” doesn’t have to mean “end state”, by the way; it could be an intermediate state that is anticipated to last for a while. That is, long enough that someone will have need of your documentation before the thing changes again.
How will it be used?
Next, think about how the documentation will be used. This will determine how you structure the documentation and where you put it. The on-call engineer does not want to sift through a bunch of scattered pages and then slog through a fifty line paragraph in order to find the command that restarts your webapp.
Write individual playbooks for each distinct on-call scenario and then store them in a dedicated folder on your team wiki. Link to each playbook from whichever alert will wake your on-call engineer in the middle of the night. Document API’s in standard tools like Swagger. Maintain onboarding documentation in the home page of your team wiki with outgoing links to other resources. Put instructions to build, run and test your Git project in its README file.
How will people find it?
You will also want to make your documentation discoverable. No one will read the documentation if they can’t find it. Per above, put documentation where a reader would expect it to be. If you use a team wiki, make sure there’s some kind of search function and make liberal use of links. Once you write it, socialize it to your team (a quick Slack message will do the trick) so that they know about it and can add anything they think might be missing.
Pitfalls
Allowing perfect to be the enemy of good
The bar for useful documentation is low. It doesn’t have to be pretty. It doesn’t even have to be comprehensive. If all you have time for is three sloppily formatted lines of bash script with a quick note on when to use them, write it. Your documentation just has to help the reader do something faster and more accurately than they otherwise would. Your documentation will naturally become more complete (and probably prettier, depending on your readers’ aesthetics) as more people use it and then contribute to it.
Keeping personal notes vs the team wiki
Most engineers I know default to keeping their own personal documentation. Personal notes serve their purpose, but I recommend defaulting to team documentation. You may even have every intention of transferring your content from a personal note to the team wiki before running into the previous pitfall (“this is good enough for my notebook but I need to make it nice and shiny before I put it out there”).
Avoid this scenario by defaulting to shared documentation from the start. Have you figured out how to run integration tests against a local instance of your web app? Put it in your Git project’s README, not your Google Keep.
Duplication
Check if the thing is already documented somewhere else. Augment that existing documentation. If it was hard to find, link to it from some likely starting point.
Drift
Documentation drift is what happens when your documentation gets out of date. This can happen with duplication (see above) but it can also happen because the documentation itself is hard to maintain. Choose a platform that is easy to write and read in and keep documentation close to the thing itself.
Boy scouting
Have you ever worked on a system where the standard release procedure was to build the source code locally, zip it up, and sftp it to a single production machine? Perhaps you haven’t (kudos) but I have. Was it terrifying? Yes. Did I document it anyway? Also yes.
Of course, if you find a bad process or design then you should fix it. Who doesn’t want better, healthier systems? Wouldn’t it be preferable, after all, to replace the Bad Thing than to document it?
This depends on relative lift. Would it be almost as fast to simply fix it? If so, do it. Leave things better than you found them and then, of course, socialize and document the new state.
But you need to be honest with yourself here. Oftentimes the lift of replacing a Bad Thing with a Good Thing (or even an Okay Thing) is quite high. You may not realize this until you are deep in the weeds of your change. In this case it is better to document the current state and then work with your team to prioritize the fix3.
Putting it off
As with all forms of procrastination, the longer you wait, the bigger and less appealing this task will feel. As soon as you learn something relevant, write it up and share.
Conclusion
Documentation is good and good for you. It doesn’t have to be pretty or all encompassing, just useful. Document by default and remember that five minutes’ investment can yield returns for years to come.
Some foreshadowing here
A special note on a subset of sensitive information: secrets. Secrets (login credentials, security tokens etc) obviously have no place in your team wiki. Secret sharing, however, is a necessary practice in many settings. Use a secrets management tool (e.g. Dashlane, 1Password etc) for this purpose. This way you still manage to document important, useful information while protecting the secret.