You write a function that loads a record, checks a few settings, builds a response, sends an email and, for reasons lost to history, updates a timestamp. Somewhere in the middle it calls a helper with a name like doTheThing2(). You look at it, make a mental note and move on.
“I’ll tidy that up one day.”
The database field that stores a value as text because it was quicker at the time. The workaround for a bug in a library version nobody uses any more. The comment that says “remove this after launch”, even though launch was several years ago and the person who wrote it has since moved to another team.
Then there are the functions that have just grown and grown. One extra condition here, a special case there. Each change made sense when it went in. The result is a function that nobody wants to touch without checking the calendar and making sure there are no meetings for the rest of the day.
None of this happens because developers don’t care. It happens because the feature needs to ship, the bug needs to be fixed, or the person waiting for the report needs it before lunch. “I’ll clean it up later” feels like a reasonable bargain when later is a real place you can visit.
There’s a difference between code that looks untidy and code that is causing trouble.
I’ve seen perfectly respectable systems with bits of code that made me want to reach for the formatting tools immediately. I’ve also seen beautiful, carefully layered code that was so difficult to change that every small update felt like a hostage negotiation.
A long function isn’t automatically a crisis. A field with an unhelpful name isn’t automatically worth a migration. An awkward bit of logic might be the simplest way to deal with a genuinely awkward requirement. Sometimes the code looks odd because the problem is odd.
Refactoring because something offends your sense of elegance can be a great way to spend a day changing code nobody was having trouble with. You can emerge with cleaner names, a more satisfying folder structure and exactly the same behaviour, except now you’ve also introduced a regression.
That doesn’t mean we should leave everything alone. It means there should be a reason to change it beyond “I don’t like looking at it”.
A useful question is: Does this make the next change harder, riskier or more expensive?
If a function is difficult to test and it keeps breaking whenever somebody changes a nearby feature, that’s a reason. If the mysterious database field has different meanings in three parts of the application, that’s a reason. If nobody understands a workaround and it’s masking failures, that’s definitely a reason.
If it’s simply a bit lumpy, but it’s stable, understood and unlikely to change, perhaps it can stay lumpy. Software is not a furniture showroom. Nobody is coming round to inspect the joinery.
The best time to refactor is often when you’re already making a change in that area. You’ve got the context in your head. You know what the code is supposed to do. You can improve the structure as part of making the feature safer to change.
That’s a much better moment than opening a ticket called “tidy up old code” and hoping somebody can remember why any of it exists.
Sometimes the right thing is to leave the code alone and write down what you learned.
A short comment explaining why a workaround exists can save someone hours. A small ticket describing the actual risk is more useful than a vague promise to “refactor this later”. And if the code is genuinely dangerous, say what could go wrong and which change would make it safer.
“Needs refactoring” is not much of a plan. It’s a polite way of saying, “This makes me uncomfortable, but I haven’t worked out why yet.”
I’ve written that kind of note myself. I’ve also come back to it years later and discovered the code had outlived the problem it was solving. Occasionally, the note is still right. More often, it’s a tiny archaeological record of the day I didn’t have time to investigate properly.
There will always be messy code. New features, old decisions, urgent fixes and reasonable compromises all leave their marks. A working application is not a museum exhibit; it’s a record of people trying to get useful things done.
So yes, tidy things up when the mess is making work harder or putting the system at risk. Do it with a clear reason, keep the behaviour safe, and take the chance when you’re already working nearby.
And if you find a database field called temporary_value, check the creation date before you assume it’s temporary. It may have been there longer than you.
Software is not a furniture showroom.
Nobody is coming round to inspect the joinery.
A working application is not a museum exhibit.
It’s a record of people trying to get useful things done.
Page updated: 2026-10-14