Designing Projects That Don’t Need Janitors
You didn't build this disaster. You're just the poor bastard who has to clean it up.
The project was already on fire when you arrived. Maybe it's been burning for years. The architecture is a fever dream, the database is held together with duct tape and prayers, and the deployment process involves manually SSH-ing into servers and hoping for the best. The original developers are long gone—probably working at a FAANG company now, bragging about the "scale" they handled at their previous job.
And yet somehow, when you try to fix this mess, you're the problem.
The Audacity of Inheritance
Here's what nobody tells you about inheriting broken projects: you will be blamed for everything that was already broken. It doesn't matter that you've been on the project for three weeks and the technical debt has been accumulating since 2015. It doesn't matter that you're actively trying to make things better. The moment you touch anything, you own it in everyone's eyes.
Bug that's existed for two years? Your fault now.
Performance issue that predates your employment? Why haven't you fixed it yet?
Security vulnerability in a library that hasn't been updated since Obama was president? Clearly your responsibility.
The worst part? The people criticizing you the loudest are usually the ones who created this mess, or at least allowed it to fester. But they've got selective amnesia about that.
The Consultant's Dilemma
This is especially brutal if you're a consultant. You're brought in to "help," which is code for "fix everything we broke but didn't want to admit we broke." You have:
- No context for why anything was built the way it was
- No access to the people who made the original decisions (they're gone)
- A codebase that looks like it was written by six different teams with six different philosophies
- Stakeholders who want you to move fast and break nothing
- A budget that assumes you can work miracles
And when you inevitably discover that fixing the actual problems requires more than just "refactoring some code"—when you have to tell them that the entire foundation is rotten—you become the bearer of bad news. Nobody likes the bearer of bad news.
The Criticism Paradox
The people who criticize you the most are rarely the ones in the trenches with you. They're not reading the code. They're not debugging the production incidents at 2 AM. They're not the ones who discovered that the entire authentication system was built on a home-grown crypto implementation that would make any security professional weep.
They're in meetings. They're looking at Jira boards. They're asking why the velocity is down.
"Why is this taking so long?"
"Can't you just...?"
"The previous developer said this would be easy."
Yeah, the previous developer also left you a codebase with 47 God classes, zero tests, and database migrations that assume they'll never be rolled back. The previous developer lied.
What You Can Actually Do
First, document everything. Not for them—for you. When someone asks why something is broken, you need receipts. "This bug was reported in 2019, here's the ticket. It was marked as 'low priority' and never fixed." Paper trail. Always.
Second, communicate in writing. Verbal agreements vanish. Email and Slack messages don't. When you identify a critical issue, write it down. Send it to the stakeholders. Make them acknowledge it. When they ignore it and it explodes later, you have proof you warned them.
Third, pick your battles. You cannot fix everything. You will not fix everything. Some things are so broken that fixing them requires burning it all down and starting over, and nobody wants to hear that. So you triage. You fix what you can fix. You document what you can't. You make incremental progress.
Fourth, stop caring about their opinion. This is the hardest one. These people don't understand what you're dealing with. They don't want to understand. They want their feature delivered yesterday, and they don't care that the system is held together with string and wishful thinking. So let them criticize. You know what you're doing. You know what the actual state of things is.
Fifth, have an exit strategy. If you're a consultant, your contract ends eventually. Thank god for that. If you're an employee, start looking for something better. Life is too short to be the janitor at the shit factory forever.
The Bitter Truth
Sometimes projects fail not because anyone did anything wrong, but because the accumulated weight of past decisions makes success impossible. Technical debt compounds. Bad architecture metastasizes. Eventually, you reach a point where the cost of fixing things exceeds the cost of rebuilding from scratch.
And you can't fix that. You can only point at it and say "this is unfixable," and then watch as people ignore you because they don't want to believe it.
You are not a miracle worker. You are a developer. You can write code, you can refactor systems, you can improve things incrementally. But you cannot retroactively undo years of bad decisions made by people who are no longer around to answer for them.
The Only Way Out
Eventually, you realize that you're not going to save this project. You're going to do your best, you're going to fix what you can, and then you're going to move on. Because staying too long in a burning building doesn't make you a hero—it just means you're going to get burned too.
And maybe that's okay. Maybe the lesson here isn't about fixing unfixable projects. Maybe it's about recognizing when something is beyond saving, documenting your efforts, and walking away with your sanity intact.
You didn't create this mess. You tried to fix it. That's enough.
Let someone else be the next janitor.