Shrink Your Codebase, Boost Your Velocity: The Overlooked Secret to Dev Productivity

By Erik Costlow, Sr Director, Product Management, Azul.

In the 30 years that Java has been around, more than 70% of global respondents to Azul’s 2025 State of Java Survey & Report indicate that their critical applications run on Java. This timeline also crosses the invention of cloud computing and other advancements, meaning that many large applications have been under development for years and have undergone multiple transformations. For those running development teams, this means lots of refactoring, lots of testing, and lots more code. In the same survey, 62% of developers said that the sheer size of their codebase created a time-consuming problem: long test pipelines, difficult upgrades, and generally hard maintenance. This difficulty creates a dividing line – those who can manage and pay down technical complexity can out-compete and out-innovate those who become mired in maintenance.

For a VP of Engineering, the line is two key points -- spending less time on maintenance means more time on valuable features, and top engineers leave maintenance work for better opportunities. One way of shifting time from maintenance to features is to get a project’s size down by finding and deprecating older code that no longer runs. In watching large applications, we’ve been finding that sometimes more than half of an application’s custom code is not used. We’ve gone further to evaluate commits and found between 10-20% of a team’s engineering velocity went into maintaining this dead and unused code. There are many reasons for this including Java upgrades (from Java 8 to Java 21) or the need to change various libraries. This ultimately means that for every five days an engineer spends coding, only four of those days matter.

Software engineers don’t set out to write unnecessary code, the code just changes and is never deprecated/removed. Removing code without proper tooling can be risky -- ultimately it boils down to time and confidence. Using common static analysis tools is too risk averse to be effective and only finds totally dead code, not code that looks alive. Other times test frameworks keep the code alive to ensure that it would work if it were ever called again. The best signal for finding code that runs is to simply collect a new type of log from production systems: compare what you’ve run against what you have in your code inventory and test. Without this runtime log, deprecating code feels too risky – make the wrong decision and the app breaks. Armed with this new log and visibility into what code is actually running in production, teams can confidently deprecate code to remove technical debt and gain their time back.

Removing code is an effective path to “first principles” for testing and security. When a test fails or a security issue rises from a library, an important question to

ask is if the library is even needed. In the State of Java survey, about a third of participants stated that roughly 50% of the security alerts they dealt with were time-wasting false positives. The reason is clear for those who step back -- many Java dependencies are present in an application but never actually invoked. If the library isn’t even used, there’s no risk and the easiest path is to prevent future discussions by removing it. Unfortunately, many engineering teams are unable to tell which libraries their application fully needs so they continue shipping all libraries and have to keep patching every vulnerability. For others though the path is simple -- hackers can’t attack what isn’t there.

The prospect of removing code can sound more frightening and impactful than it actually is. After monitoring, engineering teams can start by using @Deprecated annotations to mark unused code and draw attention that time spent on this code is unnecessary. Then a decision could be made in terms of timing to fully remove the code. Combined with tools like OpenRewrite, the act of applying these actions can be automated once the unused code is identified.

Having worked with so many organisations to address this problem, I have seen the benefits it can deliver. It is almost a kind of software development lifecycle (SDLC) therapy as removing dead or unused code lifts the mental burden off developers who don’t want to have to worry about what code they should hold on to.

Ultimately, the end result should help developers be more productive by focusing on writing code that is useful. Getting to grips with dead and unused code will help to speed up feedback loops and avoid endless debates about whether code is effective. More importantly, adopting the right strategy will enable the VP of Engineering to avoid confrontation with the business about constant demands for new features and allow the developer team to become a strategic partner helping the organisation to build on its competitive advantages.

By Erin Yepis, Senior Analyst, Market Research and Insights, Stack Overflow.
By Dan Laun, General Manager, Testing at Perforce.
React Native is a popular cross-platform app development framework used for thousands of software...
By Anugraha Benjamin, Manager, Infrastructure at Progress.