How to develop unmaintainable software

I get paid to take on technical debt. In my work I see a lot of hard-to-maintain code, and I see many of the same avoidable problems over and over.

I specialize in debugging, fixing, maintaining, and extending legacy software systems. My typical client has a web site or internal application that works, more or less, but the original developer isn’t available. Business requirements have changed and the software hasn’t kept up. Or my client has something that is “almost finished” but they parted ways with the developer after using up their budget and schedule. Usually there’s a list of missing features and bugs.

My typical client usually has been told by other developers that they need to throw everything away and start from scratch. Most programmers don’t like maintaining code, and they especially don’t like maintaining someone else’s code. When writing code programmers often ask the wrong questions when they talk about maintainability—see Matt DuVall’s article The myth of maintainability for a good description of how that happens.

Here are some things you can do in your own software projects to keep me in business:

Don’t use version control

I’m always surprised to find big projects written in the last few years that aren’t under source code version control. When you don’t use version control the next programmer to come along has to figure out which files are part of the current system and which are obsolete or backups. The next programmer won’t have any commit messages or change logs to get the code’s history from. I covered how not to use version control in my article Introduction to Abject-Oriented Programming.

Customize your development environment. A lot.

Don’t make it easy for the next programmer to start working on the code. Require specific versions of languages and tools, and make sure they conflict with the versions that come with the operating system. Customize your Eclipse or VisualStudio or vim environment like crazy, then write macros and scripts that only work with that setup. Don’t have a disk image or scripts to replicate your development environment, and don’t bother writing any documentation—it will be intuitive.

Create an elaborate build and deployment environment

For a web site deployment to a staging or production server should look like one of these:

svn up
git pull
hg pull

Programmers can argue about simplicity and elegance in code, and then turn around and build the most elaborate and baroque build and deployment systems. This is one of the off-the-radar things that programmers do without their client or project manager reviewing or understanding it, so it easily gets out of control. While you’re chaining together eight different tools with various scripting languages remember to leave out the documentation.

Don’t set up testing/staging platforms

Changing a production system is exciting. Don’t bother with a testing/staging server. Instead have secret logins and backdoor URLs to test new features. Mix test data with real data in your database. Since you aren’t using source control keep copies of previous versions just in case. Don’t build logging into the code. Don’t disable outgoing emails, credit card authorizations, etc. during testing.

Write everything from scratch

Don’t bother with a well-understood framework like Django, Rails, or CakePHP. You can write a better templating engine, ORM, sort or hashing algorithm. I scratch my head when I see code with comments like “faster than native dictionary method” or “replacing PHP library function because parameter order sucks.”

Add dependencies to specific versions of libraries and resources…

Throw in as much third-party code as you can. Link to as many shared libraries as you need to. I’ve seen code depend on large external libraries just to get access to one function. Modify the source code of the third-party libraries so they can’t automatically be updated to a newer version, but don’t bother forking or keeping your modified versions under source code control. I will be able to diff your version with the original and figure it out.

 … But don’t protect or document those dependencies

I get more urgent calls because of updates and upgrades gone wrong than for any other reason. A seemingly innocuous WordPress upgrade, Linux package update, or new jQuery release will trigger a chain reaction of failures. Don’t make your code check for the specific version or modified copy of your external resources or third-party libraries. Don’t even add a comment to remind yourself.

Use a bunch of different programming languages and stay cutting-edge

Every day HackerNews and Reddit buzz with cool new languages. Try them out on your client’s time. Any decent programmer can learn a new language in no time, so if the next programmer who gets to work on your code is a newb that’s not your problem. The boundaries between the languages, the incompatible APIs and data formats, the different server configuration requirements are all fun challenges to overcome and post about on StackOverflow. I’ve actually seen PHP web sites with pieces of Ruby wedged in because everyone knows PHP sucks and Ruby is better. Half-baked caching, aborted Rails and Node.js projects, and especially NoSQL solutions (“It’s more scaleable!”) are my bread and butter.

Where’s the programming advice?

It won’t matter much if your code is beautifully object-oriented or shiny and functional—programmers pretty much always see spaghetti code when they have to maintain a legacy system. I am good with diff and grep and Ctags, tracing through code, refactoring, and debugging. I’ll figure out the code. The most beautiful, elegant code is still hard to work with if there’s no source control, too many dependencies and customizations, and no testing/staging facility. It’s like finding one clean and nicely-decorated room in a house straight out of “Hoarders.”

Related and possibly interesting: The joys of maintenance programming.

58 thoughts on “How to develop unmaintainable software

  1. mihai

    Great article and very applicable for consultants. Main point here… is that you have the ability to decipher others code and new developers should practice working on others code as a lesson. Even with the issues you mentioned you can get through it all, just more time is required thus higher costs, which works in your favor as a consultant 🙂

  2. Jon

    I recently was hired by a startup to finish an Android and iOS app that was initiated by a consulting company. After getting my hands on the source code, I was shocked by the poor quality of the code. There was commented out code everywhere, no source control, duplicated code everywhere, lack of any discernable design patterns, and perhaps worst of all, modified libraries that were not properly forked.

    I wasn’t completely sure that I made the correct call when I decided to start from scratch, but your article has me thinking it probably was for the best.

    Great read!

  3. greenone

    thats what it feels like programming magento… no documentation and horrible dependencies… often feels like what you describe

    1. http://www./

      At the moment I am busy decorating the room for my new baby girl (expected in November!). The basics are black & white and this blanket would be so so SO perfect for her crib! I totally love the print (and the hanging cradle is to die for as well!!!).

    2. registering a car in new mexico

      I’d like to know why creationism is so wrong to you, and scientific facts appear to you to be so right. I had ‘science’ pushed down my throat as a kid, as well as black history, and then my parents took me to church. Try reconciling that.Your parents have the money, the power to control your life, and tell them their views are wrong. I would just like the people who don’t agree with what I believe to just shut up, and leave my beliefs alone, and what i want to teach my children, without interfering with their science hocus pocus b

  4. Pingback: web technologist

  5. Michael Jones

    I liked the article. Excellent stuff, though frankly quite concerning 🙂

    Completely unrelated, I wanted to say that I found it very hard to find a visited link on your page. It blends in almost perfectly with the plain text. I can kind of see the logic in that but it was not helpful when I wanted to find the link again and was scanning for coloured text. All good though, just wanted to read more of your stuff!

  6. Gareth

    I used to do something similar… I ran into a super smart architect who had decided to re-write the IBM JVM garback collector to fix his app… he spent a morning describing the work to me.

    I stepped in that afternoon and within 1-day had reduced the garbage created by about 95%. The gc was not longer an issue!

  7. egocmsuser

    I would add:
    1. Do i18n with branching logic, because English, German and Turkish does it all.
    2. Use multi-tier infrastructure architecture to bill more. Then setup staging servers, but automatically sync every content to production, because WYSIWYG you know?!
    Workflow and versioning are hard, let’s go shopping…

  8. Lou Collins

    Loved it!
    I once had a client with a vital data analysis program written in FORTRAN by a user who’d learnt some programming. EVERYTHING was hard-coded, and every time the rates for any of their products changed, he would edit the program (in multiple places). The thing was full of magic numbers and COMPLETELY uncommented. After he died unexpectedly, I had to work out what the code did, working jointly with his former colleagues who I needed to recognise tables of apparently random numbers – “Oh, that looks like the prices for next-day interstate delivery for parcels under 500g”
    It was like being on a treasure hunt. I reckon that job had more “Ah-ha!” moments than any other I’ve had.

  9. Marshal

    In a wierd way, is it good for the economy and society to have some “spagatti” programmers in financial industry that can engineer wealth un-hoarding by top 1%? :). They might induce the company to create “new initiatives” new projects because old ones don’t work, decomissioning-projects, integration-projects etc that keeps more people in job [the middle/poor family have bread on the table]. Of-late I see finaincial industry kicking out old guys [i.e 35+ ] and getting in interns-with-peanuts – that’s a yearly ritual in many financial institutions. Hmm.. I know that this arguement sidelines the “clean code” concept, but can’t stop fathoming the other dimensions of life like greed/shut-down. Obviously we all like “efficient software that requires less people to maintain, and runs for decades”.

  10. Fill

    I inherited a failed project once that was written in Rails. It was developed full time for 3 years. They named methods, variables and etc. using nonsensical code-names. In spite of using a MVC framework, all the controller code was mashed into one giant controller! Views were stored in a database, and they caught all exceptions (including legit ones generated by bugs) and redirected the user in their own custom type of routing (I imagine due to some assumption that errors were the users’ fault).

    On the flip side, I’ve worked with brilliant programmers who take things to the extreme adding worthless overhead for no practical gain. For example, forking the code at every feature addition even though there’s only 2 programmers, or demanding daily scheduled ‘scrums’ even though, again, there’s just two programmers and they are in constant communication during the work day anyways.

  11. Maintenance Man

    It is very lucrative to have to clean up messes left by other programmers. Gets real fun when they are large systems. Been paying the bills for over 10 years doing this very thing.

  12. Paul Colombo

    I work at a digital agency that has inherited or updated no less than 6 websites in the past 2 years. Not to mention projects we’ve had to outsource and then maintain. I have seen everything on this list first hand, and thank you for posting it. I struggle to get our account, PM and finance teams to understand the importance of allocating time to do things right, and that cheaply outsourced projects cause long-term headaches.

    You sir, are my hero.

  13. Pingback: Typical Programmer – How to develop unmaintainable software | Alvaro Uribe

  14. Antti Hatinen

    I would like to add a specific programming style I’ve met with Indian spaghetti-code : avoiding bugs by catching all exceptions at all levels, and showing the pages to the user like nothing bad happened (like database connection is not available) . It works great if the testers / customers don’t really understand how the software should actually work, and the app just looks like it’s almost right (but in reality doesn’t do anything). I think it’s related to avoiding “loss of face” via having a “national?” strategy of putting more effort in hiding mistakes than actually writing code that works.

  15. Trevor Turton

    Great post, I recognised lots of the problems that you described. I’ve even written a few in my time. It would be very funny except it’s tragic. To call such code “spaghetti” is flattery, rather call it macaroni because it’s full of holes.

  16. PlainSimpleDeveloppper

    I jumped from a company in june because of this kind of ‘politics’ ; their products were such a mess, coding for them was a nightmare. For instance the guys who conceived the database didn’t use any relation between their 100 tables. why so sicne they could code their own sets of triggers to assume referential integrity ? :O try to play in a rdbms with more than 400 triggers ready to shoot at any move…
    some love to suffer

  17. Greg Jorgensen Post author

    @Henryk of course svn up (or equivalent) is not always the best way to deploy–I was use hyperbole to make a point. In fact a lot of web sites can be deployed with svn up (or svn export if you prefer), but there are things like database changes, possibly race conditions on a busy site, language translations, etc. that may require a more sophisticated build/deployment system. What I am complaining about is unnecessarily complicated and clever build/deployment systems that only one person understands. I’ve worked at software companies where a build/deploy was a half- or full-day operation.

  18. Greg Jorgensen Post author

    @Marshal It’s bad enough to find these things in older legacy apps, but I have seen some of these mistakes in code that is still under development. It’s a “first big system” problem, where a group of smart but inexperienced programmers get carried away and try to out-clever each other.

    @Fill I have a theory that programmers suffer from OCD at a much higher rate than the overall population. It makes us good at programming, but also makes us prone to ritual behavior like forking every change, obsessing over tabs vs. spaces, holding pointless scrums, etc.

  19. Greg Jorgensen Post author

    @PlainSimple I’ve written about RDBMS abuse. More than a few times I’ve been involved with projects where an RDBMS was rejected or abandoned because it was too slow or wouldn’t scale (theoretically). Some NoSQL replacement was introduced, but then the data quickly became inconsistent and corrupt. When I look at the abandoned “relational” solution I see every beginner mistake that made it slow and un-scaleable in the first place.

  20. carlo

    Or the opposite. Im working on a system that uses J2EE, JPA, JSF, Eclipselink, JMS and Oracle (in other words ‘prevalent frameworks’). It’s all ‘Java’ version controlled. We have a test server and standard IDE and build sequences. There’s even documentation.

    But its still a terrible piece of software.
    Why? Because its a monolithic hotchpotch with little to no architectural or design oversight.

  21. Richard

    We wrote a lot of stuff like ORMs back in the late 90s when the available platforms were somewhat more scant. It means we still have a lot of code on that basis, though it is documented and maintainable. We still build on it today. Going to something like Hibernate would be prohibitively expensive.

  22. Mr. Bear

    Oh, I love those NoSQL kool-aid drinkers. They think they are so incredibly brilliant because they have discovered a database table with a ‘key’ column and a ‘value’ column.

  23. davidwr

    Writing unmaintainable code is easy.

    The hard part is realizing why it is unmaintainable so you don’t do it again.

    This – or something like it – should be required reading for every new programmer and everyone in leadership/management/executive offices regardless of experience.

  24. Joe

    Great article. Could use some clean up. For example in the “svn up” section you break character. It would be great if you kept up the farce throughout so that a credulous reader thinks this a bona fide recipe for writing software. Do that and I’m sure some manager will mail this around as a codification of all his hopes that all that “fluff” his/her devs are busy with is an unnecessary waste of time.

  25. Greg Jorgensen Post author

    @Joe I already wrote that article: Introduction To Abject-Oriented Programming. Too many people took it seriously, I’m worried I did some damage to my profession.

  26. Greg Jorgensen Post author

    @Bear Wait until the NoSQL people (re)discover fixed-length records with fields at specific byte positions, and embedded pointers to the physical position of related records. That will rule because it’s fast and scales.

  27. Fill

    @greg Oh, I’ve definitely had my fair share of hires and friends who were OCD. I think that can help make for a good programmer/engineer, but it can also cause problems with staying on task and keeping a grasp of the big picture as they work. There’s what I call “going down the rabbit hole”, as we touched on, where somebody gets so entrenched in the details of something that they spend all their time over-engineering it and lose grasp of the bigger picture. I’ve also had a hire go home early sick with “OCD” (that was a new one, I had never heard of somebody doing that before). On the other hand, that hire would occasionally elect to do an all-nighter to crank out a project from soup to nuts, which was great.

  28. Pingback: Totally Unmanageable Code In 8 Easy Steps


    Hmm it seems like your site ate my first comment (it was super long) so I
    guess I’ll just sum it up what I had written and say, I’m thoroughly enjoying your
    blog. I too am an aspiring blog blogger but I’m still new to
    the whole thing. Do you have any suggestions for newbie blog writers?
    I’d certainly appreciate it.

  30. Alessandro Gasparini

    Hi Greg,
    I must tell you that your article is fantastic, really funny, to the point that I’d like to hire you to make a review of our product LogicalDOC. . Anyway I want to recommend you to add some social widgets to your site, such as Facebook like, Twitter or other, in order to increase (if possible) its popularity.

  31. Steve Nelson

    Great Article! I was shacking my head (up and down) and laughing at the same time only because I’ve seen the same thing so many times.

  32. Addinall

    “Don’t bother with a well-understood framework like Django, Rails, or CakePHP. ”

    Over the last decade I have seen some REALLY poor systems. Maintaining the stuff was just out of the question. The REALLY REALLY bad ones all used well known MVC Frameworks and produced a horrible complex mess then the result should have been some light footprint OOD/OOP PHP.

  33. Pingback: How to develop unmaintainable software

  34. Pingback: Ironic Programming How To Guide Teaches Programmers How Not To : Stephen E. Arnold @ Beyond Search

  35. Cristina

    Hi! I know this is kinda off topic nevertheless I’d figured I’d ask.
    Would you be interested in exchanging links or maybe guest authoring a blog article or vice-versa?
    My site discusses a lot of the same topics as yours and I feel we could greatly benefit from each other.
    If you happen to be interested feel free to send me an email.
    I look forward to hearing from you! Wonderful blog by
    the way!

  36. eugel

    Another case. Consider an established enterprise. All the code is documented and controlled for decades (25+ years). Somebody writes a function and it works for 10 years. Then a precision bug occurs in this function. One cannot change the code without impacting the previous behavior and data. So they fork. And another decade pass. The issue is documented but the people are gone. One day you decide to call the “new” function and discover that it is slow and its precision isn’t sufficient. However the “old” function gives you what you want though you know that once in 10 years it fails… It’s a true story from my real life.

  37. Zol

    One way to write unmaintainable code is use short names and no documentation, and print same content in logs from three different methods.

  38. Pingback: Jak pisać kod niemodyfikowalny | Dawcy Mózgu

  39. Pingback: Typical Programmer – How to develop unmaintainable software | pat o.

Leave a Reply

Your email address will not be published. Required fields are marked *