Skip to content
Technology22 April 2026 · By the Intense Path Editorial Team

What Does It Actually Cost to Maintain the Thing You Just Built?

The bill for the second year is five separate streams of work, not one line called support. Here is what each one is, who it lands on, and how to budget it without borrowing somebody else’s percentage.

On This Page
Pass It On

Found this useful? Send it to someone who’s building.

Software Maintenance Cost: What Year Two Takes | Intense Path

The build shipped in March. The invoice cleared, the team moved on, and the thing has behaved ever since. Then October arrives. The payment provider emails about an API version being retired. A browser update breaks the date picker on one platform. Sales needs three sentences changed on the pricing page. And the person who wrote the deployment script has left. None of that was in the budget, because none of it was written down as work.

The software maintenance cost of anything you build is not one number, and it is not a fixed share of the build. It is five separate streams of recurring work that arrive on different schedules, from different directions, and land on different people. Teams underestimate it because they price the one stream they can picture, which is bug fixes, and ignore the four they cannot.

The position this piece defends is simple: the cost exists whether or not you fund it. Deferred maintenance does not evaporate. It accumulates quietly as risk and then converts, usually at the least convenient moment, into a project. So the honest question is never whether to pay. It is which form you would rather pay in.

Maintenance is five jobs wearing one word

Ask three people in the same company what maintenance covers and you get three answers: security patches, bug fixes, and "small changes". That vagueness is where budgets go wrong, because a number attached to a vague thing cannot be checked. Separate the streams and each one becomes something you can schedule, assign, and price against your own system.

  • Dependency updates. The libraries underneath your application move whether or not you are watching. Some of those moves are security fixes you do not get to decline.
  • Platform deprecations. Runtimes, browsers, payment providers, hosting platforms and app stores all retire things on their own calendar, and none of them ask first.
  • Content and copy changes. Prices, policies, service names, a job opening, a sentence legal wants softened. Minutes each, constant in aggregate, and never finished.
  • Monitoring and response. Somebody has to notice a failure before a customer does, and somebody has to be free to act when they do.
  • Knowledge transfer. Every system carries knowledge that lives in one person’s head. That person eventually takes leave, changes team, or leaves the company.

Three of those are predictable and two are not, which is the single most useful thing to know before you build a budget. Updates, content and handover can be scheduled. Deprecations and incidents cannot, because their timing belongs to somebody else. Scheduled work needs a rhythm. Unscheduled work needs reserved capacity. Confusing the two is why maintenance budgets are simultaneously too small and never fully spent.

StreamWhat sets the timingWho notices firstWhat deferring it turns into
Dependency updatesUpstream releases and disclosuresNobody, until a scan or a breachA version jump too large to make safely
Platform deprecationsA vendor or browser calendarA support email, then an errorAn outage on somebody else’s date
Content changesThe businessSales, legal, or a customerStale pages and a queue nobody owns
Monitoring and responseFailure itselfIdeally a check, in practice a userSilent breakage measured in weeks
Knowledge transferPeople moving onThe next person to touch itA rebuild presented as the only option

Whether that work sits with an internal developer, a retained partner on a website maintenance arrangement, or some split between the two, the five streams do not change. Only the question of who owns each one does.

Dependency updates: the work that compounds

Every application sits on a tree of libraries it did not write and cannot fully audit. Left alone for a year, that tree does not stay still. It moves without you, and the gap between the version you run and the version the rest of the ecosystem supports widens without producing a single visible symptom.

The compounding is the part teams miss. Taking a library one minor version at a time is usually a small, dull job that fits inside an afternoon. Taking the same library after two years of skipped releases means reading migration notes for changes nobody on the team witnessed, in code nobody remembers writing, often under pressure, because the reason you finally looked was a disclosed vulnerability rather than a plan.

Two reasons to update, and only one is optional

Keep them apart. A security update answers to someone else’s timetable: a vulnerability is disclosed, an identifier lands in the public CVE record, and every scanner your customers and insurers run will eventually find it. A feature update answers to yours. You take it when it buys you something you actually need.

The practical difference is authority. Security updates should not need a business case, and if yours do, the approval process is itself the risk. Feature updates should need one, because the alternative is a team that upgrades continuously and ships nothing. Patching what you already know about also beats commissioning a study of what you might have, which is the same argument as fixing the obvious before booking a penetration test.

A cadence that survives a busy quarter

  1. Run the check on a schedule, not on a feeling. A scheduled workflow that opens a report every week costs nothing to run and removes the decision to look.
  2. Batch by risk, not by package. Security first and on its own. Then breaking-change majors, one at a time. Then everything harmless together, in one merge.
  3. Update on a branch, with tests as the gate. If there is no test suite, the first honest maintenance investment is a small one covering the paths that take money.
  4. Merge small and often. A branch that lives for six weeks stops being an update and becomes a second codebase to reconcile.
  5. Write down what you skipped, and why. The skipped list is the real maintenance backlog. Unrecorded, it becomes a surprise; recorded, it becomes a decision somebody made on purpose.
The update you are most likely to skip

The one with no visible symptom. Nothing is broken, the release notes are boring, and nobody will thank you for it. That is precisely the update that costs least today and most in eighteen months, and it is why this work belongs on a schedule rather than in a queue where it competes with features it will lose to every single time.

Platform deprecations: work you did not choose

Dependencies are yours to manage. Deprecations are somebody else’s decision arriving in your inbox. A hosting provider retires a runtime version. A browser removes a behaviour your form relied on. A payment provider sunsets an API version and attaches a date to it. An app store changes a requirement and rejects your next release until you meet it.

None of this is negotiable, and all of it is schedulable, provided somebody reads the announcements. The failure here is almost never technical. It is that the deprecation notice went to an address nobody monitors, or to a developer who left in February, and the first anyone hears about it is the error in production. Put every vendor notification into a shared inbox one named person reads. That is the whole countermeasure.

Some of these bills are set at the very beginning. The runtime you picked, the platform you deployed onto and the services you integrated all carry their own deprecation habits, which is why hosting decisions are hard to reverse and why the shape of an integration matters more than how quickly it was delivered. If you own an interface other teams build against, the same rule points inward: designing for the person using it in two years is mostly about not creating deprecations for other people.

One concession, honestly meant: you cannot pre-empt all of this, and trying to is its own kind of waste. Pinning every version and refusing every platform change produces a system that is beautifully stable right up to the day it can no longer be updated at all. The aim is not zero surprises. It is that each surprise is small enough to absorb inside a normal week.

Content changes are maintenance, and usually the largest stream

This is the stream teams leave out of the budget entirely, and by volume it is generally the biggest. Prices change. A policy page needs a paragraph. A service gets renamed. A role opens and then closes. Someone spots a dead link in the footer. Individually these take minutes. Collectively they are a standing job, and when the only route for them is "ask a developer", they queue behind engineering work and quietly rot.

The cost is set by who is allowed to change a sentence

If a typo needs a developer, a branch and a deployment, then you have priced every typo at the rate of an engineering change. That is the real reason to care about the publishing model, and it has very little to do with editorial comfort. Route the work to the cheapest person who can do it safely, and the whole stream gets smaller without anyone working faster.

This is where a structured content workspace earns its place. A tool like Acrosite gives editors a structured interface, generates the required files, commits them to GitHub and triggers the configured deployment, so a copy change stops being an engineering ticket while the content stays in version control. The mechanism is less interesting than the principle behind it, which is that a publishing route is a cost control.

The same reasoning applies to a catalogue. If every product or price change requires a deploy, you have chosen a maintenance model as much as an architecture, and that is one of the quieter items in what you take on with headless commerce.

Monitoring, and the failures nobody reports

Loud failures get fixed. The site is down, everybody knows, somebody acts. The expensive ones are quiet: a contact form that submits successfully and delivers nothing, a payment webhook failing for one card type, a scheduled job that stopped running in April, a search index that has not refreshed since a config change three releases ago.

The defining property of a quiet failure is an information gap. The people who could fix it do not know, and the people who know do not report it. Users largely do not report broken things. They leave, and they do it without telling you which step defeated them.

Which makes the reporting channel part of the monitoring system rather than a marketing asset. An enquiry form is often the first place a broken checkout gets described in plain English, and treating it as a triage instrument rather than a lead capture changes both what it asks for and who reads the result.

What is worth watching, in order

Start narrow. Watch the paths that take money or generate enquiries, end to end, from outside your own network, because a check that runs inside your infrastructure will happily confirm that your infrastructure is fine while customers cannot reach it. Then watch anything that runs on a schedule, since a job that stops is invisible by definition. Then error rates. Then performance.

Alert only on things a human can act on tonight. Everything else belongs in a weekly review. A system that pages people about conditions they cannot fix does not produce vigilance; it produces a team that has learned to dismiss alerts without reading them, which is worse than having no alerting at all.

Knowledge transfer: the cost of the person who left

Every system has a part exactly one person understands. The release that needs a manual step. The queue that must be drained first. The reason that setting is set that way. This knowledge goes undocumented because writing it down never feels urgent, and because the person holding it can do the task faster than they can explain it.

The bill arrives when they go, and it does not look like a gap in knowledge. It looks like a change in cost. Work that took an hour now takes a day. Confidence drops, so changes get deferred. Deferred changes make the system stiffer, which makes the next change more expensive again. By the time anyone names the problem, it has been mistaken for the code being bad.

The countermeasure is unglamorous and cheap. Write the runbook the day you do the task for the second time. Keep a decisions file that records why, not what, because the what is already in the code and the why never is. Rotate who performs the release, so at least two people have done it under normal conditions. And when somebody does leave, treat the handover as scheduled maintenance with time allocated to it, rather than an afternoon of goodwill on their last day.

How to budget this without inventing a percentage

You will find rules of thumb that express annual maintenance as a fixed share of the build cost. We do not use them and we would advise against it, because they are averages taken over systems nothing like yours. A brochure site and a booking platform with four integrations do not share a maintenance profile, and no percentage repairs that difference. Build the figure from your own system instead. It takes an afternoon.

  1. List the five streams against what you actually run. Which dependencies, which platforms with published deprecation calendars, how often content genuinely changes, what must be watched, and where single-person knowledge sits.
  2. Give each stream a rhythm rather than an estimate. Weekly, monthly, quarterly, or on-event. A rhythm is far easier to agree than a number of hours, and it converts into hours later on its own.
  3. Time one real cycle. Run a month of the actual work and record what it took, including the interruptions. One measured month beats every industry figure, because it is your codebase and your people.
  4. Reserve capacity for the unschedulable. Deprecations and incidents need room, not a plan. A standing allocation each cycle is more honest than an emergency budget nobody has approved in advance.
  5. Review the reserve every quarter and move it. Untouched, shrink it. Overflowing every month, the system is telling you something a different conversation should hear.

Unused reserve should not simply disappear at the end of a cycle. Roll it into deliberate product improvement, so the months when nothing breaks make the system better rather than merely quieter. That also removes the perverse incentive where a team looks wasteful for having a calm quarter.

A maintenance budget you never measured is a guess wearing a spreadsheet. Measure one real month and most of the argument ends.

If you can only fund one thing

Fund the ability to release safely: a working pipeline, tests on the paths that take money, and a rollback any two people can perform without a meeting. Every other maintenance stream gets cheaper when shipping a change is boring, and every one of them gets more expensive when it is frightening.

When maintenance stops being the right answer

There is a point at which maintaining costs more than replacing, and it is rarely the point teams pick. The usual trigger is aesthetic. The stack feels old, the code is unfashionable, a new developer would rather start again and says so persuasively in week two. None of that is a reason.

The signals that count are visible in your own logs and calendar: routine updates that can no longer be applied because the framework version is unsupported upstream, dependencies with no upgrade path at all, or changes that break something unrelated most times you attempt them. Those are structural, and no amount of scheduling fixes them. Everything short of that is usually a discipline problem in an architecture costume, which is the case we make at length in when to rewrite instead of refactor.

The cheapest maintenance decision available, meanwhile, is refusing to add things. Every feature accepted is a permanent addition to all five streams: more dependencies, more surface exposed to deprecation, more content to keep true, more to monitor, more for the next person to learn. Saying no in public, by publishing your non-goals, is a maintenance strategy as much as a product one, and it is the only one that reduces cost rather than redistributing it.

So here is the rule we would apply on the day a build is signed off: name the person who owns each of the five streams, and put the first cycle in a calendar before anybody celebrates. Not a document. A date. Systems do not decay because teams stop caring. They decay because maintenance is the only work that arrives without a deadline, and work without a deadline loses every argument it has with work that has one. If you are looking at something built two years ago and cannot say which streams have been running, tell us what you are running and what nobody has touched since launch.

Take these with you
Maintenance is five separate streams of recurring work, and pricing them as a single support line is the reason the figure is always wrong.
Security updates should never require a business case, while feature updates always should, and keeping the two apart is what stops upgrades from consuming a roadmap.
Content changes are the largest stream by volume, and their cost is decided entirely by who is allowed to make them safely.
Deprecations and incidents need reserved capacity rather than a plan, because their timing is set by vendors and browsers rather than by you.
Measure one real month of maintenance work on your own system instead of borrowing a percentage from an average that describes somebody else.

Common questions.

What does website maintenance actually include?

Website maintenance covers five recurring streams: dependency updates, platform deprecations, content and copy changes, monitoring with incident response, and knowledge transfer between the people who can safely change the system. Only updates, content and handover are predictable enough to schedule tightly. Deprecations and incidents need reserved capacity instead, because their timing is set by vendors, browsers and staff movements rather than by your own plan.

How much should I budget for software maintenance each year?

Build the figure from your own system rather than from a percentage of the build cost. List the recurring streams, give each one a rhythm, then run a single real month and record the hours it consumed, interruptions included. That measured month is a far better basis than any published average, because averages cover systems with different integrations, different content velocity and different teams. Revisit the reserve each quarter.

What happens if we skip dependency updates for a year?

Skipping updates converts small, dull work into a large and risky project. Every missed release widens the gap between the version you run and the version the ecosystem supports, so the eventual upgrade spans breaking changes nobody on the team witnessed. It also means security fixes arrive bundled with feature changes, forcing the risky work to happen under time pressure rather than at a pace you chose.

Who should own maintenance if we have no in-house developer?

One named person inside the business should own the schedule even when every task is performed externally. Their job is not to patch anything. It is to make sure vendor notices reach a monitored address, that the agreed cycle actually happens, and that skipped items are recorded rather than forgotten. Outsourcing execution works well. Outsourcing ownership is how a system quietly stops being maintained.

How do we know when maintaining costs more than rebuilding?

Look for structural signals rather than aesthetic ones. Routine updates that can no longer be applied, a framework version upstream no longer supports, dependencies with no upgrade path, or changes that break unrelated features most times you try. Those show a system resisting maintenance itself. Code that merely looks dated, or that a newly hired developer dislikes, is not a rebuild argument on its own.

Why do content changes count as maintenance?

Content changes count because they recur permanently and consume the same capacity as technical work whenever nobody else can make them. Prices, policies, service names and dead links all need attention, and if each edit requires a developer, a branch and a deployment, every typo is priced at engineering rates. Giving editors a safe publishing route reduces this cost more reliably than any tooling upgrade.

What should a small team monitor first?

Start with the paths that take money or generate enquiries, checked end to end from outside your own network. Add anything that runs on a schedule next, because a job that stops running fails silently by definition. Then error rates, then performance. Alert only on conditions a person can act on immediately, and route everything else to a weekly review, or people learn to ignore alerts entirely.

Facing this in your
own business?

Tell us where you’re headed — we’ll map the shortest honest route.

Start a Project