Mar 10, 2026 · 3 min read · Career Growth and Technical Leadership
Five Years Maintaining Enterprise Software
Most of what I learned came from changing systems that already had users, history and dependencies. I also stayed long enough to maintain some of my own earlier decisions.
I spent more than five years at Softcraft working on enterprise and government systems. During that time, I built new features, optimized slow workloads, modernized legacy code, improved deployment processes, supported production, reviewed code, and participated in architecture decisions. The variety was useful, but staying with these systems for years taught me more. Five years is long enough to see some of your own decisions come back as maintenance work. Not every awkward part of the code was inherited. Some of it was mine, and that changed how I think about engineering.
The Shortcuts We Maintained
A shortcut isn’t automatically wrong. Products have deadlines, teams have limited capacity, and sometimes the responsible decision is to deliver a smaller solution with known limitations. The problem is when everybody forgets the limitation, including the person who introduced it. A temporary condition becomes a permanent branch. A duplicated rule evolves differently in two places. An integration built for one consumer becomes an unofficial contract for several others. The cost usually doesn’t appear in one big failure. It adds a little more work to every future change. I became more deliberate about writing these trade-offs down. If we chose the faster path, we recorded what it didn’t solve and what would make us revisit it. Memory wasn’t a reliable maintenance strategy. Legacy code can be frustrating. I’ve definitely opened an old method and wondered why anybody would write it that way. More than once, the answer was that it contained years of business knowledge that the method name didn’t reveal.
Before changing an unusual rule, I learned to ask who depended on it and why it existed. Sometimes the behavior was accidental. Sometimes it protected an edge case discovered through a difficult production experience. Understanding first didn’t mean preserving every old decision. It meant modernizing with evidence instead of assuming newer code would automatically be more correct. This was especially important in systems that couldn’t simply be taken offline while we rebuilt them.
Production and Deployment
A design that looks clean in code can still be difficult to deploy, observe, or recover. Production support made me consider questions that a class diagram doesn’t show. How will we know this workflow is delayed? Can the operation be repeated safely? What happens to in-progress work during deployment? Does the team have enough context to respond without the original developer? CI/CD, containerization, observability, and infrastructure became part of my software engineering work because they shaped whether the application could be changed safely. One deployment automation effort reduced the manual work by roughly 70%. What I noticed day to day, though, was that releases became less dependent on somebody remembering a fragile sequence of steps. One of the platforms supported thousands of daily operations. When critical workflows slowed down, it was tempting to blame the framework or ask for more infrastructure. By tracing API and database behavior, we found focused changes that improved response times by more than 60% in important workloads. This reinforced something I try to do now: understand the current system before proposing a larger one.
The same principle applied beyond performance. Clear diagnosis prevented unnecessary rewrites, services, and abstractions.
Work That Didn’t Produce Much Code
In the later years, some days with very little code were still useful. A requirement became clearer before implementation, a review found a failure case or a pipeline change removed work from every future deployment. I still wrote plenty of code, but I stopped using the number of lines as a measure for the day. After more than five years, the systems weren’t finished or perfectly clean. They had more users, rules and integrations than when I started, and some old decisions were mine. I mostly wanted the team to keep enough understanding of them to make the next change without being afraid of everything around it.