Everyone Told Us ‘Don’t Touch That Code.’ We Touched It. Here’s What Happened.

Everyone Told Us 'Don't Touch That Code.' We Touched It. Here's What Happened.

Touching fragile legacy code is risky, but sometimes it’s unavoidable. For us, leaving it untouched was no longer an option – it was blocking growth, frustrating customers, and wasting resources. Here’s how we tackled it step by step, minimized risks, and turned a mess into measurable results:

  • The Problem: The system was outdated, undocumented, and riddled with technical debt (40% debt ratio vs. 5% healthy benchmark). Critical functions were tangled, dependencies were obsolete, and performance was dragging.
  • The Plan: We used AI to assess the codebase, prioritized fixes with a "Traffic Light Roadmap", and implemented changes incrementally to avoid disruptions.
  • The Process:
    • Stabilized the system with isolated testing environments and reverse proxies.
    • Modernized gradually using strategies like dual-write architecture and feature flags.
    • Monitored and managed risks with quarterly reviews and automated tools.
  • The Results: Median latency dropped by 97%, error rates fell by 98%, and operating costs were slashed by 81%. Teams became 20–30% more productive, and new business opportunities opened up.

Key takeaway: Ignoring legacy code only delays the inevitable. By focusing on critical areas, using phased updates, and leveraging AI tools, you can modernize without breaking what works.

The Starting Point: What We Found

What the AI-Agent Assessment Revealed

Before diving into the code, we ran our proprietary AI-Agent Assessment to get a comprehensive look at the system. What we found was nothing short of alarming.

The technical debt was overwhelming. Files stretched over 6,000 lines, packed with overly complex conditional logic. The Technical Debt Ratio hit an eye-popping 40% – far beyond the healthy 5% benchmark [4]. Even worse, critical functions like payment processing were tangled up with unrelated processes like fraud detection. The assessment uncovered and pieced together more than 5,000 undocumented business rules buried in the codebase, rules that existed without any documentation elsewhere.

The codebase was riddled with outdated dependencies. Compatibility layers for Internet Explorer 11 – a browser long retired – were still in use. Frameworks like AngularJS, which no longer receive security updates, were scattered throughout. We also found bloated libraries like Moment.js (290 KB), which could be replaced with slimmer options like date-fns (89 KB). Performance monitoring revealed sluggish Interaction to Next Paint (INP) times and tasks lasting over 50ms, both of which dragged down user experience [2].

Hidden dependencies added even more risk. Our AI-driven audit uncovered deeply interconnected logic that manual reviews would have likely missed. For example, in June 2025, a government agency used a multi-agent GenAI framework to analyze over 3 million lines of legacy code in under three days – 225 times faster than a traditional human-led process [8].

"Using AI solely for code generation is like using a Swiss Army knife as a can opener. Sure, it works, but it ignores the far more capable tools right in front of you."

These discoveries allowed us to organize and prioritize the issues systematically, ensuring no time was wasted on guesswork.

How We Prioritized with the Traffic Light Roadmap

With these insights, we designed a remediation plan using a straightforward, three-tier prioritization system. By applying essential business context, our Principal Council classified issues into Critical, Managed, and Scale-Ready categories, all guided by a strategic framework.

Critical issues needed immediate action. These included high-traffic areas like checkout flows, security vulnerabilities, and performance bottlenecks such as tasks exceeding 50ms. Using an Impact vs. Effort Matrix, we homed in on high-value areas that directly affected customers and revenue [2].

Managed issues required a phased strategy. These were stable but outdated components, like older libraries and non-critical technical debt. To address these, we allocated 10–20% of our development capacity to ongoing improvements, ensuring they didn’t snowball into larger problems [2].

Scale-Ready areas were already optimized. Modules with low interdependencies and proven readiness for full-scale deployment became the foundation for gradual modernization. This approach showed that meaningful updates could happen without the need for a complete system overhaul.

For instance, in February 2026, IBM Consulting helped a major Brazilian bank reduce its modernization scope by 30%, cut migration time from 90 to 56 hours per application, and process over 55 applications per month [7]. We adopted a similar mindset: focus on what matters most and trim unnecessary efforts.

The Traffic Light Roadmap gave us a clear, disciplined path to stabilize the system – no panic, no overhauls, just targeted, effective action.

Refactoring Legacy Code: STEP BY STEP (Part 1)

How We Approached It: Reducing Risk While Moving Forward

With a clear roadmap in hand, we tackled risk reduction through a carefully phased strategy.

Phase 1: Stabilizing the System

Our first step was setting up a dedicated development environment where we could safely validate changes without impacting live customer transactions. This allowed us to test updates in isolation, avoiding unnecessary disruptions [9].

Next, we addressed runtime errors, deprecated functions, and dependency conflicts systematically. For instance, when a Laravel-based marketplace faced production failures after a PHP upgrade in February 2026, we stabilized the system by gradually upgrading the framework over 6–8 weeks. The project, costing under $20,000, resolved runtime errors while keeping the platform operational [9].

To further reduce risk, we implemented a reverse proxy to route requests between old and new components. This setup let us test new code in "test mode", where behavior was logged without affecting live traffic. Critical workflows, such as payment processing, were continuously monitored and validated [10].

"The safest upgrades look uneventful on the outside and disciplined on the inside."

Phase 2: Gradual Modernization

Once the system was stable, we shifted to incremental updates using our Variable-Velocity Engine (V2E) framework. This phased approach allowed us to modernize without halting feature development or disrupting daily operations.

We started with UI/UX updates in less critical areas, like footers and modals, to test our modernization strategy. These changes served as a proving ground before tackling core system logic [2].

For sensitive data workflows, such as pricing and payments, we adopted a dual-write architecture. Both legacy and modern systems processed the same data simultaneously, while an automated reconciliation loop compared outputs. For example, during the migration of a pricing engine from VB6 to .NET 8 (February 2024–April 2025), the reconciler handled 12.4 million events, identifying only 847 mismatches (0.007%). This approach prevented an estimated $4.2 million in pricing errors [10].

We also used canary rollouts and feature flags to gradually shift traffic – starting with 5%, then 15%, and eventually 100%. This allowed for quick rollbacks if any issues emerged. AI workflows were integrated cautiously, with a secondary model acting as an "LLM-as-Judge" to validate the primary model’s responses within our CI/CD pipeline [10][2][11].

"Incremental migrations minimize risk, improve the time to validating the business value of a change, and eliminate planned downtime."

Phase 3: Ongoing Risk Management

After completing the modernization phases, we put systems in place to monitor and manage risks continuously.

We conducted quarterly Principal Council reviews to assess system health and maintain stability as the business scaled. These reviews tracked the Technical Debt Ratio (TDR), keeping it below 5%, and used automated tools to manage dependencies [2][4].

To ensure long-term success, we allocated 10–20% of each sprint to reducing technical debt and enhancing the platform [2][4]. For example, the insurance pricing engine’s legacy components were decommissioned only after achieving four consecutive weeks of zero mismatches – a strict benchmark that guaranteed the new system’s readiness [10].

What We Achieved: The Results

Legacy Code Modernization Results: Performance and Cost Improvements

Legacy Code Modernization Results: Performance and Cost Improvements

By taking bold steps to modernize legacy systems, we demonstrated how calculated risks can lead to transformative outcomes. The targeted updates not only delivered faster and more efficient systems but also cut costs and opened new revenue opportunities. Ultimately, these technical upgrades directly enhanced overall business performance.

Technical Improvements

The migration of the insurance pricing engine, completed between February 2024 and April 2025, resulted in massive performance improvements [10]. Here’s what changed:

  • Median latency dropped by 97.4%, from 1,247 ms to just 32 ms.
  • Peak latency (P99) improved by 98.4%, going from 4,820 ms to 78 ms.
  • System throughput skyrocketed by 1,233%, increasing from 180 to 2,400 requests per second.
  • Error rates fell by 97.8%, from 0.18% to 0.004%.
  • Deployment frequency jumped from 4 to 52 times per year.
  • Annual infrastructure costs plummeted by 81%, dropping from $840,000 to $160,000.
  • Memory usage per request decreased by 88%, from 18 MB to 2.1 MB.

Additionally, the legacy Laravel marketplace underwent a modernization process that lasted just 6–8 weeks and cost under $20,000. Despite its quick turnaround, the project achieved zero downtime and resolved all production issues [9].

Business Results

The technical advancements translated into equally impressive business outcomes. For example, Kennect’s ETL platform broke free from Excel’s 1-million-row processing limit, enabling the company to scale from 3 to over 20 pharmaceutical clients, including major players like AstraZeneca, Sanofi, and GSK. This project paid for itself within a year, delivering a 100% ROI by enabling the onboarding of two clients immediately after completion [12].

"You guys were godsent for us. Your timing couldn’t have been more crucial."

  • Prakhar, Founder and Head of Product, Kennect

The pricing engine’s automated reconciliation loop performed 12.4 million calculations during the migration, identifying 847 mismatches (just 0.007%) and preventing an estimated $4.2 million in pricing discrepancies [10]. Teams working with the updated systems reported productivity boosts of 20–30% and operating cost reductions of up to 30%, allowing them to shift their focus from troubleshooting to developing new features [2].

These results offer valuable lessons for founders and CTOs looking to tackle their own modernization projects effectively.

What We Learned: Advice for Founders and CTOs

Our work has shown that letting fragile, undocumented code linger only leads to faster decay, eventually making it impossible to develop new features. Avoiding intervention doesn’t solve the problem – it just delays it. The real question isn’t whether you should modernize, but when and how to do it without disrupting what already works.

When You Should Touch Untouchable Code

The right time to modernize isn’t just when the code feels outdated. It’s when the cost of maintaining it outweighs the risk of changing it. Undocumented or untested code becomes a liability when it starts draining resources. For example, jQuery, which still powers 72% of websites in 2026, is a prime example of legacy tech that many teams struggle to manage effectively[2].

Focus on the code that matters most: modules critical to revenue and frequently updated. If a module is both essential to your business and gets modified every sprint, it’s a clear candidate for modernization. On the other hand, messy but rarely touched code can usually be left alone. This targeted approach is crucial because roughly 70% of complete system rewrites fail to deliver the results organizations expect[1].

Ignoring legacy code doesn’t save money – it just adds to the bill. Companies typically spend 70% to 80% of their IT budgets maintaining existing systems, and technical debt costs the average global enterprise over $370 million annually[1,5]. Letting the problem fester only makes it more expensive in the long run.

How to Reduce Risk

Once you’ve decided to modernize, managing risk becomes your top priority. The biggest threat isn’t choosing the wrong framework – it’s breaking undocumented business logic. To avoid this, start by creating a safety net. Write characterization tests to capture the current behavior of the code. These tests act as guardrails: if they pass, you know you’ve preserved the logic[13].

Modern AI tools can be a huge help here. Developers can only hold a limited amount of information in their working memory, and undocumented legacy code often exceeds that limit[14]. AI assistants can quickly explain complex functions or identify hidden business logic. For instance, Salesforce used AI-driven refactoring in 2024 to condense a two-year migration project into just four months. They achieved this by generating object-oriented service layers and dependency injection patterns[14].

To keep old and new systems from interfering with each other, use bridge layers. These are explicit files that translate requests between legacy and modern components, preventing a messy hybrid system. A good example is Airbnb’s 2024 upgrade from React 16 to React 18. They used module aliasing and environment targeting to A/B test the new version in production while maintaining a "permitted failures" list. This method allowed them to achieve a full rollout without any rollbacks[2].

Here are some common modernization strategies and their risk levels:

Strategy Best For Risk Level
Strangler Fig Gradually replacing entire systems Low
Outside-In Quick UX improvements on specific pages Medium
Inside-Out Replacing parts within a stable shell Medium
Big Bang Rewrite Total tech stack overhaul High

How to Extend Legacy Systems Without Full Rewrites

Instead of overhauling your entire system, extend its life by gradually replacing core components. This incremental approach reduces risk and avoids downtime. The Strangler Fig pattern, where old components are replaced piece by piece, allows you to modernize while keeping the system operational[2].

"The most reliable path from legacy to modern architecture is incremental migration rather than a complete rewrite." – Mark Knichel, Vercel[2][3]

Start by identifying natural "seams" in your system, like API calls or message queues. These are points where you can intercept traffic without rewriting entire components. For data migration, use the dual write pattern: write to both the old and new databases, then gradually switch to reading from the new one while keeping a fallback in place. VMware Tanzu applied this method in 2024 during a five-day Event Storming workshop with a shipping company, helping the team pinpoint high-value processes and avoid unnecessary legacy replication[3].

Modernizing your tools first can also reveal hidden bugs and make debugging easier. Teams that adopt modern frameworks often see productivity gains of 20% to 30% and cut operating costs by up to 30%[2]. The key is to frame modernization as a way to achieve specific business goals – like speeding up report generation or enabling new features – rather than just "refactoring for its own sake"[15].

"The safest upgrades look uneventful on the outside and disciplined on the inside." – Alex Kukarenko, Director of Legacy Systems Modernization, Devox Software[2]

Conclusion: Moving Forward with a Clear Plan

Fragile, undocumented code doesn’t age well – it only gets more expensive to fix over time. The teams that thrive are those that stabilize first, modernize step by step, and carefully manage risks along the way. This isn’t about choosing the trendiest framework; it’s about diving into the core business logic hidden in your code and ensuring the essentials remain intact. That’s the foundation for a thoughtful and risk-conscious modernization process.

Start with a complete assessment. Leverage AI-powered tools to map out dependencies, flag outdated libraries, and uncover critical business logic before making any changes[2][16][3]. From there, align your technical roadmap with business goals – whether that’s speeding up feature delivery, cutting maintenance costs, or improving the user experience. Keeping business priorities front and center is non-negotiable.

Once the assessment is done, tackle immediate issues to stabilize the system. Then, shift to incremental updates. Use strategies like the Strangler Fig pattern, targeted refactoring, or even replatforming to modernize in phases[16]. Tools like feature flags can help deploy new code to a small fraction of users (1–5%) first, so you can quickly revert if issues arise[5][3]. By dedicating 10–20% of each sprint to reducing technical debt, you’ll avoid those high-stress moments that lead to rushed, risky decisions[2][4].

A disciplined approach to modernization doesn’t just cut costs – it opens up new opportunities for growth. It reduces tech expenses, boosts team productivity, and positions modernization as a smart business investment rather than just another technical task.

At AlterSquare, we guide founders and CTOs through every step of this process – from assessment to execution. Our AI-Agent Assessment evaluates your system’s health and produces a Traffic Light Roadmap, helping you focus on what matters most. The Principal Council – Taher, Huzefa, Aliasgar, and Rohan – personally reviews your codebase before any work begins, ensuring you get expert technical insight rather than generic account management. Whether your goal is to stabilize, expand, or scale, we create a clear, risk-aware plan that keeps your product running smoothly and your revenue flowing.

FAQs

How do I know it’s worth touching our legacy code now?

If your system is showing performance issues – like sluggish load times, frequent crashes, or recurring errors – it might be time to take a closer look at your legacy code. Other red flags include challenges with scalability, trouble adding new features, or rising maintenance costs. Security vulnerabilities and a poor user experience are also strong indicators that your code needs attention. Letting these problems linger can pile up technical debt and leave you with a fragile system. Tackling these issues through gradual modernization is often the smartest way forward.

What’s the safest first change to make in a fragile codebase?

When diving into code improvements, the safest approach is to begin with small, incremental changes rather than tackling massive overhauls. For instance, you can start by refactoring individual methods or clearing out unused code. These smaller updates are easier to test, minimize the chances of introducing new bugs, and help keep the system stable. Plus, this step-by-step process gives developers the chance to gradually familiarize themselves with the codebase while ensuring everything continues to work as expected.

How can AI help without introducing new risks?

AI plays a key role in updating fragile and undocumented codebases by enabling step-by-step, pattern-based changes. For instance, it can handle tasks like converting old callback structures to modern async/await syntax or swapping out obsolete frameworks for newer ones. This careful, incremental process helps avoid major disruptions and eliminates the need for risky, large-scale rewrites. On top of that, AI encourages test-first workflows, ensuring that stability is maintained throughout the process and minimizing the likelihood of bugs or security vulnerabilities during the update.

Related Blog Posts

Leave a Reply

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