Internal Tools Are Your Worst Codebase
Scripts nobody maintains, CLIs with no docs, dashboards with no owners. Internal tooling kills DevEx silently — because it's nobody's job to fix it.
Every engineering team has a graveyard.
It's not in your main repo. It's the scripts folder on a shared drive. The bash scripts that live in someone's dotfiles and got Slacked around once. The internal admin dashboard that the engineer who built it left six months ago. The CLI that works if you use Python 3.8 specifically and run it from the right directory.
Nobody is responsible for any of it. And it quietly costs your team more than almost anything else you could fix.
What internal tooling actually is
Internal tooling is everything your engineers use that isn't the product. It includes:
- Deploy scripts and wrappers
- Database migration runners
- Seed data generators
- Admin consoles and dashboards
- Staging environment scripts
- Log search shortcuts
- On-call runbooks that are partially automated
- Report generators
- Internal CLIs
It's the stuff that makes the gap between "I want to do X" and "X is done" smaller. When it works. When it doesn't, it's the gap that consumes entire afternoons.
Why it rots
No owner. Product tooling has owners, roadmaps, and code review. Internal tooling was written by whoever needed it, merged without review, and forgotten. When it breaks, nobody's pager goes off.
No users spoke up. Engineers tolerate bad internal tooling because they assume it's their fault when it doesn't work. They find workarounds, ask colleagues, or do things manually. They don't file bugs.
No incentive to maintain. Fixing the internal deploy script won't show up in your performance review. Shipping a customer feature will. The rational actor ignores internal tooling until it's catastrophically broken.
It was written in a hurry. Internal tools get built in an afternoon, in the context of solving a specific problem, with no intention of becoming load-bearing infrastructure. Then they become load-bearing infrastructure. The code never got the second pass it needed.
The invisible DevEx tax
The tax is distributed and therefore invisible. Consider:
- An engineer spends 20 minutes debugging why the seed script failed before realizing it's Python version incompatibility. Once.
- Multiply by ten engineers. Multiply by the script breaking six times a year. That's 1,200 engineer-minutes per year on one script.
- They then work around it — running a manual SQL script instead — adding five minutes per use. If the seed script is used twice a week, that's another 520 minutes per year.
Total: ~28 engineer-hours per year for one broken internal tool. Your company has 15 of these tools. Do the math.
None of this shows up in a retro. It shows up as "things feel slower than they should."
What broken internal tooling does to culture
Engineers learn to distrust their tools. Once you've been burned by a script that does something unexpected, you approach every internal tool with suspicion. You run it in a test environment first. You add sanity checks. You Slack a colleague before running it. All of that is overhead that a trustworthy tool wouldn't require.
Senior engineers become single points of failure. Knowledge about how the internal tools actually work lives in the heads of whoever built them. New engineers have to ask. Senior engineers spend 30 minutes a week explaining the same quirks to different people.
Manual processes persist. If the automation is unreliable, teams do it manually instead. Manual processes are slower, more error-prone, and don't get better over time. The internal tool that was supposed to automate something instead becomes a reason nobody automated it.
The minimum viable ownership model
You don't need a platform engineering team to fix this. You need someone to care.
Create a "tools" or "devex" label in your issue tracker. When internal tooling breaks, it gets reported there. This makes the problem visible.
Assign an owner for each tool. Not "everyone is responsible" — a specific person. Usually whoever uses it most, or whoever is most familiar with the code. Doesn't need to be a full-time responsibility; five minutes per week of ownership is infinitely better than zero.
Add a README to every internal script. Minimum: what it does, how to run it, what can go wrong, who to contact if it breaks. Put this in the script itself if there's nowhere else to put it.
Deprecate explicitly. When a tool is no longer used, delete it or mark it deprecated loudly. The graveyard problem gets worse when dead tools coexist with live ones and nobody knows which is which.
Test the critical path quarterly. Whatever tooling would block a deploy if it broke — run it manually once a quarter. Find out if it still works before you need it.
What good internal tooling looks like
It's not beautiful. It doesn't need to be. It needs to be:
Documented at the usage level. --help actually works. The README has a real example. The error messages say what went wrong.
Testable locally. You can run it against a local or staging environment without affecting production.
Recoverable. If it fails halfway through, running it again doesn't make things worse. Idempotent operations, dry-run flags, clear rollback steps.
Boring. Shell scripts are fine. Python scripts are fine. The tool that works in 10 lines is better than the tool that's architecturally elegant and hasn't worked since the lead who built it left.
The platform engineering case
If your team is at the point where internal tooling is a significant time sink — multiple engineers per week losing hours to broken scripts, manual processes that should have been automated two years ago, on-call runbooks that require 45 minutes of prep before following — it's worth considering a dedicated investment.
Platform engineering exists to make engineers faster. Internal tooling is a core part of that. A team of two with a clear mandate to "make developer workflows 30% faster" will produce measurable ROI within a quarter.
But you don't need to start there. You need to start by naming the problem, making the failures visible, and assigning ownership. Tools don't maintain themselves. Someone has to care enough to.
Start with an audit
Spend 30 minutes listing every internal tool your team uses regularly. For each one:
- Who owns it?
- Does it have a README?
- When did it last break, and how long did it take to fix?
- Is there something manual that should be automated but isn't?
The list will be longer than you expect. The ownership column will be mostly blank. That's the gap. Close it deliberately, and your team's daily experience improves without changing the product at all.
Work with me
I consult with engineering teams on AI adoption, cloud architecture, and engineering effectiveness. If this post surfaced a challenge you're facing, let's talk.
Get in touch →Related posts
Explore more on these topics: