
Two applications can have similar numbers of users, screens and features yet cost very different amounts to maintain.
In one, a developer can understand a change, update the code, run reliable automated tests and release it through a repeatable deployment pipeline in a few hours.
In the other, the same-sized request requires tracing dependencies across several tightly coupled modules, asking a long-serving engineer why the code behaves the way it does, testing manually, coordinating a production release and then watching closely because rollback is difficult.
The visible feature might be equally small.
The maintenance effort is not.
That is why estimating application maintenance as a simple percentage of original development cost is often misleading. Original build cost says little about how maintainable the software is today, how frequently its environment changes, how much production support it needs or how much effort is required to make a safe modification.
A more useful way to think about maintenance cost is:
Maintenance cost is driven by how much work the application generates and how much effort is required to understand, change, verify, release and operate it safely.
For Levelworks, this is closely connected to App Health. An application that is Well Documented, Tested, Observable, Current & Updated, Version Controlled and Seamlessly Updatable is generally easier to maintain because routine work requires less investigation, manual verification and operational effort.
Those qualities do not make maintenance free. They make maintenance more predictable.
Companies often combine several different expenses under “app maintenance.”
These may include:
These costs are related, but they behave differently.
If cloud traffic doubles, infrastructure spending may rise without engineering maintenance effort increasing significantly.
Conversely, an application with very few users can still be expensive to maintain if every code change requires extensive manual testing and specialist knowledge.
For this article, the main focus is the technical effort required to keep an application working reliably over time. Infrastructure and vendor costs matter where the architecture or operating model causes them to create additional maintenance work.
Complexity is one of the strongest cost drivers, but it should not be confused with application size.
A large, well-separated application can sometimes be easier to change than a smaller application where every component depends on everything else.
Maintenance becomes more expensive when a developer needs to understand a large portion of the system before safely changing one part.
Common complexity drivers include:
Imagine changing the way a customer's status is calculated.
In a cleanly separated system, one service may own that rule.
In a tightly coupled system, the status might also influence billing, reporting, permissions, email notifications and several database procedures.
The amount of code changed may remain small, but the blast radius that must be understood and tested becomes much larger.
DORA's research on loosely coupled teams and architecture highlights this relationship. Systems that allow teams to test, deploy and change components independently reduce coordination overhead, while tightly coupled architectures make relatively small changes dependent on wider parts of the organization and system.
More components do not automatically mean higher maintenance cost.
More coupling between components usually does.
Technical debt increases the cost of otherwise ordinary changes.
It may take the form of:
Technical debt is expensive because future work has to navigate around it.
Suppose adding one reporting field should require modifying one query and one API response.
If reporting logic has been duplicated across six modules over several years, the same change now requires locating every implementation, understanding subtle differences and testing all of them.
The feature has not become more valuable.
The cost of changing it has increased because previous design decisions made the system harder to work with.
Technical debt can therefore compound. A difficult area is avoided because it is expensive to change; more workarounds accumulate around it, making the next change even harder.
[Internal Link: “How Technical Debt Affects the Health of Your Application”]
The useful maintenance-cost question is not simply, “How much technical debt do we have?”
It is:
How much additional effort does the current structure add to normal maintenance work?
That makes debt measurable through the friction it creates.
Every maintenance change needs some level of verification.
The cost depends heavily on how that verification is performed.
Consider a small bug fix affecting checkout.
Team A changes the code and runs automated unit, integration and end-to-end tests covering the affected workflow. Human testing concentrates on the areas where judgment adds value.
Team B has almost no automated regression coverage, so somebody must manually test login, product selection, checkout, payment and order creation before the release can be considered safe.
Repeat that difference across dozens of maintenance changes each year and the cost becomes significant.
DORA's research on test automation notes that manual regression testing is time-consuming and expensive, while delayed feedback also increases the effort required to diagnose and correct defects.
Weak test coverage creates another cost: fear of change.
Engineers compensate for uncertainty with:
For Levelworks, this is the practical cost impact of Tested App Health. Testing is not simply a quality control expense; reliable automated feedback reduces the amount of work needed to make routine maintenance safe.
A maintenance engineer spends time in two broad ways:
Poor documentation increases the second.
If architecture, deployment, integrations and important historical decisions are not documented, maintainers have to recover that context from:
DORA's research on documentation quality found a strong relationship between high-quality internal documentation and organizational performance, and identifies clarity, findability and reliability as important documentation characteristics.
The cost becomes especially visible when knowledge is concentrated in a few individuals.
If one engineer is the only person who understands billing, every billing-related maintenance task depends on that person's availability.
Good documentation cannot replace technical expertise, but it reduces the amount of specialist time required to reconstruct routine context.
[Internal Link: “Why Good Documentation Makes an App Cheaper to Maintain”]
Application age by itself does not determine maintenance cost.
An older application running on well-supported technology can be straightforward to maintain.
The expensive situation is usually distance from currently supported versions.
Maintenance effort increases when the application relies on:
OWASP recommends maintaining an ongoing inventory of frameworks, runtimes, libraries and other components and monitoring them for vulnerabilities and support status. Its guidance on vulnerable and outdated components explicitly includes operating systems, servers, databases, APIs, runtimes and libraries.
Falling several major versions behind creates a different maintenance problem from performing smaller regular updates.
GitHub's Dependabot documentation illustrates one reason: in deep dependency graphs, updating a single vulnerable package may become impossible without also upgrading parent or related dependencies. GitHub therefore recommends staying relatively current because that increases the likelihood that future security fixes can be applied without resolving a large chain of incompatibilities. GitHub: Dependabot dependency update errors
Postponed upgrades do not eliminate maintenance cost.
They often concentrate it into a larger future event.
Each important external integration adds another relationship the application team must maintain.
That can include:
The maintenance cost does not come simply from the number of API calls.
It comes from external change.
Providers can alter:
A ten-integration application where most connections are stable and loosely coupled may be relatively inexpensive.
A five-integration application can be costly if all five are business-critical and change frequently.
Integration cost also rises when external behavior is spread directly throughout the application rather than isolated behind clear interfaces.
[Internal Link: “Why Third-Party Integrations Fail Over Time”]
A useful cost assessment therefore records not only how many integrations exist, but their criticality, volatility and degree of coupling to the core application.
When production problems occur, somebody has to determine what happened.
Good observability reduces the amount of engineering time spent doing that.
Poor observability turns diagnosis into reconstruction.
An application with useful:
may allow an engineer to move quickly from a user report to the failing component.
Without them, the team may need to reproduce the issue manually, search several systems and add temporary logging before even beginning the fix.
AWS's Well-Architected guidance recommends using observability telemetry to make informed operational decisions and take prompt action when outcomes are at risk. AWS Well-Architected: Operational Excellence
This is why Observable and Explainable & Debuggable App Health have economic consequences.
They shorten investigation.
And investigation time is part of maintenance cost.
A maintenance fix is not finished when the code is written.
It has to reach production.
Compare two release processes.
A pull request triggers automated tests, creates a build artifact, deploys through CI/CD and runs post-deployment validation.
An engineer builds locally, uploads files manually, changes production configuration, runs a database script and verifies the release from a checklist.
Even if the application change takes the same engineering time, Application B makes every maintenance release more expensive.
AWS recommends automating integration, testing and deployment specifically because doing so reduces errors from manual processes and reduces the effort required to deliver changes. AWS Well-Architected: Fully automate integration and deployment
Release friction is therefore a multiplier.
If your app needs one release a year, a cumbersome process may be tolerable.
If it needs fifty maintenance releases, the same process becomes a major recurring expense.
Some applications continuously create maintenance work even when engineers are not changing code.
Teams may repeatedly:
Google SRE calls repetitive, manual, operational work that provides little enduring value toil. Its Eliminating Toil guidance emphasizes an important characteristic: this type of work often grows as the service grows.
That makes manual operational work especially dangerous economically.
If every 1,000 new customers create ten more hours of manual work, maintenance staffing eventually has to grow with the customer base.
Automation changes that relationship.
AWS similarly recommends quantifying the time spent on operational work and prioritizing repetitive, time-consuming or error-prone activities for automation. AWS Well-Architected: Perform automation for operations
The important cost metric is therefore not merely how many operational tasks exist, but how much human attention they consume repeatedly.
An application with recurring production problems naturally generates more maintenance work.
That includes both the engineering time required to fix defects and the operational cost surrounding them:
A useful predictor of future maintenance burden is therefore the application's recent defect and incident history.
Look at:
A system that repeatedly fails in the same areas probably has structural maintenance work waiting behind the visible incidents.
Simply budgeting for faster responses does not remove that cost driver.
Correcting the recurring source does.
A low-risk internal tool and a regulated financial or healthcare application can require very different maintenance effort even if their codebases are similar in size.
Higher-assurance applications may require more:
NIST's Secure Software Development Framework recommends integrating secure development practices throughout the software lifecycle so vulnerabilities are identified, mitigated and prevented from recurring.
That work requires engineering capacity.
The mistake is treating security and compliance obligations as exceptional costs that appear only during an audit. For applications where those requirements are permanent, they belong in the normal maintenance model.
Two technically identical applications can have different maintenance costs because the business expects different levels of service.
An internal application used during office hours might reasonably operate with business-hours support.
A payment platform used globally may require:
Those requirements change staffing and operational effort even if the underlying code remains unchanged.
This is why maintenance cost cannot be estimated purely from technical architecture.
The required service level matters.
A system that must recover quickly from failures costs more to support than one where several hours of downtime are acceptable.
Maintenance cost also depends on how often the application needs to change.
Consider two stable, well-built systems.
Application A receives one significant update per quarter.
Application B operates in an environment where dependencies, business rules, integrations and customer requirements change every week.
Application B will naturally require more engineering capacity.
Change can come from:
The useful question is not merely “How old is the app?”
It is:
How much change does this application need to absorb each year?
A mature application in a stable environment can sometimes be inexpensive to maintain. A young application operating in a rapidly changing ecosystem may require substantial ongoing work.
These factors rarely operate independently.
An outdated framework is more expensive to upgrade when automated tests are weak.
Complex architecture costs more when documentation is poor.
Third-party integration failures take longer to diagnose when observability is missing.
Frequent releases become expensive when deployment is manual.
This interaction explains why simplistic formulas based on application size produce unreliable estimates.
A more useful assessment looks at several dimensions together:
Cost driver
Lower-cost condition
Higher-cost condition
Architecture
Clear boundaries
Heavy coupling
Technical debt
Controlled
Accumulated
Testing
Reliable automation
Manual regression
Documentation
Current and findable
Tribal knowledge
Technology
Supported/current
Several versions behind
Integrations
Few/stable
Many critical/volatile
Observability
Fast diagnosis
Production blind spots
Deployment
Automated/repeatable
Manual/high-risk
Operations
Low toil
Frequent manual intervention
Reliability
Few recurring issues
Repeated incidents
Assurance
Standard
High security/compliance burden
Support
Business hours
High-availability / 24×7
Change rate
Stable
Frequent external/product change
When evaluating maintenance cost, the most useful estimate is not simply:
“This application requires X hours per month.”
It should explain why.
For example:
Those assumptions make the estimate adjustable.
If incident volume drops after fixing recurring defects, future effort can change. If the business adds 24/7 coverage or several critical integrations, required capacity may increase.
This is considerably more useful than relying on a generic percentage of original development cost.
The strongest long-term cost reductions usually do not come from negotiating a lower hourly engineering rate.
They come from reducing the amount of engineering effort required for each maintenance outcome.
Reliable tests mean less manual regression.
Good documentation means less rediscovery.
Observability shortens diagnosis.
Current dependencies keep routine upgrades manageable.
Automation removes recurring operational work.
Looser architecture reduces the number of components and teams affected by a change.
That is where Levelworks' App Health framework becomes economically useful. Well Documented, Tested, Observable, Current & Updated, Version Controlled and Seamlessly Updatable are not simply markers of engineering quality. They influence how expensive the next fix, upgrade or production investigation is likely to be.
[Internal Link: “How to Create an Annual App Maintenance Budget”]
A maintenance budget becomes much more useful once these underlying cost drivers are understood.
Because ultimately, the expensive application is not necessarily the largest one.
It is the one that makes the team work hardest to understand it, change it safely and keep it running.