When the Work Was Keeping a Legacy System Alive

Some engineers spend a long stretch on a system nobody chose. It predates them, it is load-bearing, it cannot be rewritten, and the year’s work was upgrades, patches, careful surgery, and a slow reduction in the number of ways it could fall over.

Written badly, that reads as “was in the wrong place”. Written properly, it reads as the hardest kind of engineering there is, because none of the usual escapes were available. The difference is almost entirely whether the constraints are on the page.

Why it reads badly by default

Legacy work produces bullets in the passive voice about nouns nobody recognises.

Default: Maintained and supported the legacy order management system. Fixed bugs and performed upgrades as required.

Every word of that is true and it conveys nothing. It has no problem in it, no decision, and no state change — the three things a reviewing engineer is reading for. Worse, “maintained” and “as required” both position you as a responder rather than someone who decided anything, which is the opposite of the impression the work should leave.

The other default failure is the apologetic frame: writing about the system’s age as if it were your fault, or leading with “unfortunately the codebase was…”. Reviewers are not judging the codebase. They are judging what you did inside it.

What legacy work actually demonstrates

It is worth being explicit about this, because people doing it routinely undervalue it.

You can read code you didn’t write. This is the single most useful trait in a new hire and the hardest to evidence. Anyone who has landed a correct change in a large, undocumented, test-light codebase has done the thing every new job starts with.

You work under constraints instead of around them. No rewrite, no framework change, no new dependency, an interface a dozen consumers rely on. Solving inside that box is more technically demanding than solving in an empty one, and everyone who has done both knows it.

You have a real sense of risk. Greenfield work is forgiving. Changing a system that processes money or inventory, with users who notice immediately, teaches sequencing, rollback, and verification in a way nothing else does.

You have seen the consequences of decisions. Most engineers only ever see the first year of a system’s life. You have seen year eight. That is a genuinely different education, and it is the reason experienced engineers get cautious about clever abstractions.

The vocabulary that makes it legible

Name the constraint, then the thing you did inside it. The constraint is what turns a maintenance sentence into an engineering one.

Illustration: Added per-tenant rate limiting to a request path shared by forty internal callers, without changing the public interface any of them depended on — introduced the limiter behind a feature flag, ran it in shadow mode for a fortnight, then enforced tenant by tenant.

Illustration: Took the reporting module off a database driver that had been unmaintained for years, by writing a compatibility layer for the three query patterns the module actually used rather than porting all of its call sites.

Both are recognisably careful work by someone who understood what they were touching. Neither needed a metric.

The five bullet shapes that work

The upgrade with the reason. Runtime, framework, or dependency upgrades are the archetypal legacy task, and the version really is the story — one of the few cases where naming versions helps rather than dating you, as name the problem, not just the tool argues. Say what blocked the upgrade and how you got past it: the abandoned library, the behaviour change, the test suite that had to exist first.

The safety net you built before touching anything. Characterisation tests, a shadow-traffic comparison, a reconciliation job proving old and new agreed. This is the most senior thing on the list, and it’s usually omitted because it feels like preparation rather than work.

The strangler increment. One route, one module, one table moved out, with the old path still live. Describing an incremental extraction — and the seam you chose — shows judgement that “migrated the monolith” never does.

The deletion. Dead code, unused endpoints, a scheduled job whose output nothing read. Say how you established it was safe to remove; that is the interesting half.

The knowledge you wrote down. A system diagram that didn’t exist, a runbook for the failure everyone handled from memory, an explanation of why a strange piece of logic is correct. Legacy systems live in people’s heads and moving some of that onto paper is real, valuable, and rarely claimed.

The stack-currency problem, honestly

The legitimate worry underneath all of this: your skills list now looks like an artefact. An older major version of a language, a framework that stopped being fashionable, a deployment model from before containers.

Two things help, and neither involves pretending.

Separate what you have operated from what you have kept current with. A short honest line does this without overclaiming — Also familiar with: Kubernetes, Terraform (side projects and a small internal service, not production ownership). Reviewers read that exactly as written, and it beats both silence and a padded list. The tech stack list problem covers the grouping.

Lead with the transferable half. Databases, queues, HTTP, concurrency, data modelling, and operational judgement do not go out of date. A bullet about diagnosing a lock-contention problem is current regardless of what language it was in. A bullet about a framework’s templating syntax is not. Weight accordingly.

The unhelpful move is hiding the old stack entirely. It is on the page in the form of your employer and your dates anyway, and an obvious omission invites the question you were trying to avoid.

The roles where this is the strongest resume in the pile

Postings that say modernise, consolidate, stabilise, migrate, or reduce operational load are describing exactly this experience, and most applicants will answer them with greenfield work. As what an engineering job posting tells you about the team sets out, those verbs are the honest part of a posting.

For those roles, put the legacy work first and describe it as a specialism rather than a circumstance. A positioning line does it in two clauses: Backend engineer, mostly on systems that were already running — upgrades, extractions, and making other people's code safe to change.

The check

Read your legacy bullets and ask whether a reader could tell that the work was hard.

If the answer is no, the missing element is almost always the constraint. You did not add a cache; you added a cache to a code path with no test coverage and four callers you could not modify. The second sentence is the same work and a different resume.