What Legacy Codebases Teach You That Greenfield Projects Never Will

软件 工程师 都柏林

软件 工程师 都柏林

工程师 精心 打造 可扩展

超越 代码 本身

他们 怎么说

一起 构建

消息 已收到

隐私 政策

使用 条款

Cookie 政策

免责声明

最新 动态

精选 作品

作品 展示

我们 提供 什么

服务 的行业

屏幕 之外

共同 构建

View View
Nben Malla
Nben Malla

Software Engineer

A software engineer who builds systems that scale, modernizes platforms that matter and ships code that holds up long after the project ends.

Based in Dublin, Ireland, with a presence across Bristol, Groningen and Kathmandu, the work spans FinTech platforms, SaaS products and open source contributions, collaborating with engineering teams across Nepal, Ireland, the Netherlands, New Zealand and the United States.

From leading legacy modernization for global banking clients to architecting microservices in Go, Java and Python, the focus has always been the same. Understand the problem deeply, build it right and make sure the people depending on it never have to think about it failing.

  • 阅读文章 阅读文章

    Blogs 7 mins

    What Legacy Codebases Teach You That Greenfield Projects Never Will

    Nben M. 02 May, 2025 7 mins

    What Legacy Codebases Teach You That Greenfield Projects Never Will

    Greenfield projects feel like freedom. You pick the stack, define the conventions, structure the repository the way the team agrees makes sense. Everything is intentional because everything is new. That feeling is also the problem. You never face the real conditions that most production software lives in.

    I spent the better part of two years working inside a legacy FinTech platform at Standard Chartered Ireland. The codebase was a decade old, built across multiple teams in multiple countries, running transactions worth hundreds of millions daily. There was no clean abstraction layer. Business logic sat inside database triggers. Deployment was a manual process gated by a release committee. Nothing about it resembled the software I had built before. Everything about it made me a better engineer.

    What I learned there did not come from documentation or design patterns. It came from necessity.

    You Learn to Read Code as Archaeology

    In a greenfield project, code reflects current intent. In a legacy system, code reflects every decision, compromise and misunderstanding that accumulated over years. Reading it is not just understanding what the code does. It is understanding why it does it that way, who was under pressure when it was written, and what the system looked like before this piece existed.

    A function with seventeen parameters is not ignorance. It is the result of six feature additions, two compliance requirements and one hotfix that had to ship before a regulatory deadline. The moment you start treating legacy code as stupidity rather than history, you stop learning from it.

    I developed the habit of reading commit history before touching any module. In one case, a block of code that looked like an obvious bug had been written that way to work around a third-party API that returned malformed responses. Removing it would have broken a payment integration in production. No test covered that path. No comment explained it. The commit message did.

    You Learn What Coupling Actually Costs

    Architecture discussions in greenfield projects tend to be abstract. You debate service boundaries, talk about cohesion and coupling, and draw boxes on whiteboards. In a legacy system, you feel what bad coupling actually means at the moment you try to change something.

    We had a reporting module that shared a database schema with the transaction processing engine. Changing a column name in the transactions table meant coordinating a deployment across three separate applications, running schema migrations in a specific order, and scheduling a maintenance window. Two teams had to be involved. One change, one afternoon of coordination.

    That experience taught me more about schema design than any book on domain-driven design. The cost of coupling is invisible until you try to move. In a legacy codebase, everything that was coupled incorrectly has already been moved at least once. You inherit the scar tissue.

    The Hidden Contract Problem

    Every system has contracts. In a well-maintained modern system, those contracts are explicit: typed interfaces, published API schemas, versioned endpoints. In legacy systems, contracts are often implicit, embedded in behavior that other systems depend on without acknowledgment.

    What Legacy Codebases Teach You That Greenfield Projects Never Will
    What Legacy Codebases Teach You That Greenfield Projects Never Will

    We discovered one such contract when we changed the format of a date field in an internal API response. The field was returned as a string in the format YYYYMMDD with no documentation anywhere. Three downstream systems were parsing that exact format with no validation. None of them failed loudly. They silently produced wrong output for four days before anyone noticed.

    You cannot find hidden contracts by reading code. You find them by changing things.

    You Learn to Respect Working Software

    There is a strong tendency among engineers to view legacy systems as something to be replaced. I had that tendency. Working inside one dismantled it.

    Software that has been running in production for a decade, processing real transactions under real load, has survived things you have not accounted for yet. Race conditions that only appear under specific load patterns. Edge cases introduced by regulatory changes. Data anomalies that accumulated over years of real-world use. The system knows about these problems implicitly because it was forced to handle them.

    Rewrites fail at a predictable rate not because engineers are bad but because rewrites discard implicit knowledge. The new system is clean and well-structured and completely unaware of every hard problem the old system quietly solved.

    When to Rewrite and When to Refactor

    The decision to rewrite should be treated as a last resort, not a reward for inheriting something ugly. The right question is not "is this code good?" but "does this code know things we do not know yet?"

    At Standard Chartered, we chose incremental extraction over rewrite. We moved bounded domains out of the monolith one at a time, keeping the core transaction engine in place until we understood it well enough to reproduce its behavior exactly. That process took longer than a rewrite would have. It also shipped without a single P1 incident during migration.

    The teams that chose rewrite on adjacent systems hit problems at month eight, when the new system encountered data formats from 2009 that no one had documented and the old system had silently normalized for years.

    You Learn That Tests Are Documentation

    Greenfield projects tend to have tests written by the same engineers who wrote the code, reflecting the assumptions those engineers held at the time. Legacy systems, when they have tests at all, often have tests written by people who were trying to understand the system as much as describe it.

    Those tests, even the poorly written ones, are a record of what the system was expected to do at a specific point in time. A test that looks redundant often exists because something broke without it. A test that covers an obscure input format exists because that input format arrived in production.

    I started treating test coverage gaps as risk maps. Where there were no tests, no one had been confident enough to formalize the expected behavior. That uncertainty was worth understanding before making changes.

    You Learn to Operate Under Constraint

    Greenfield projects give you the luxury of choosing your constraints. Legacy systems impose them without asking. You cannot change the runtime. You cannot upgrade the framework. You cannot alter the schema because eight other systems read it directly. You solve problems inside a box that someone else drew.

    That constraint is valuable. It forces a kind of creativity that open-ended problems do not require. Some of the most elegant solutions I have shipped were built inside severe constraints, because the constraints eliminated every option except the right one.

    In one case, we needed to add structured logging to a Java service running on a version of the JDK we could not upgrade without a six-month validation process. The solution was a thin wrapper around the existing logger that serialized log context to a format the log aggregator could parse. One class, zero dependencies, deployed without a runtime change. Clean solutions under constraint tend to be smaller and more targeted than solutions built with full freedom.

    Conclusion

    Greenfield projects build confidence. Legacy codebases build judgment. Confidence tells you that you can build something. Judgment tells you whether you should, how carefully, and what you are likely to break in the process.

    The engineers I have worked with who are most capable in production are almost always the ones who have spent significant time inside systems they did not build and were not designed for the conditions they operate in. That experience is not comfortable. It is not the kind of work that makes for impressive portfolio projects. It is, however, where most real engineering happens.

    If you have the choice between a greenfield project and inheriting a legacy system, take the legacy system. You will complain about it for the first three months. You will understand things about software by month six that you could not have learned any other way.