TL;DR: Software does not stay finished after launch, because the world around it keeps moving. Operating systems update, app stores raise their requirements, dependencies age, third-party APIs and AI models change, and real users find the bugs your testing missed. Maintenance is the work of keeping a shipped product running, secure and accepted by the platforms it lives on, and it is a separate line in the budget from new features. Plan for it in four buckets: platform upkeep you cannot skip, dependency and security updates, monitoring and fixes, and small improvements driven by real usage. I have done this work on React Native and Unity apps released through the App Store and Play Console as CTO at RAQTS, on a cross-platform SDK at Geonode, and on AI voice agents running in production for clients.
The most common surprise I see from founders is not a missed deadline. It is the moment, a few months after launch, when something that worked perfectly stops working and nobody changed a line of code. The app gets a warning from Google Play. A login flow breaks on a new iOS version. A voice agent starts phrasing things slightly differently because the model behind it was updated. The product did not rot. Everything around it moved.
This post is what I tell clients before launch so the first maintenance bill is a plan, not a shock.
Why "done" software still needs work
A shipped product sits on top of a stack it does not control:
- The operating system. iOS and Android ship major versions every year, and each one changes permissions, background behaviour and privacy rules.
- The stores. Apple and Google raise their requirements on a schedule. Google Play requires apps to target a recent Android API level, and if you do not update, you eventually cannot ship updates at all. I covered the release side of this in getting through App Store and Google Play review.
- Your dependencies. Every framework, SDK and package in the project gets security fixes and breaking changes. The longer you wait, the bigger the jump.
- Third-party services. Payment providers, CRMs, telephony and AI platforms deprecate endpoints, change pricing and retire models.
- Your users. They do things nobody tested, on devices nobody owns, on networks nobody expected.
None of this is a sign the code was bad. It is the cost of shipping onto platforms that are themselves alive.
The four buckets of maintenance
When I scope maintenance with a client, I split it into four buckets. It makes the budget conversation honest, because each bucket has a different urgency.
1. Platform upkeep you cannot skip
This is the non-negotiable work: target API level bumps on Android, new SDK requirements from Apple, privacy manifest updates, certificate and provisioning renewals, and engine or framework upgrades that the stores eventually force.
On Unity projects this bucket is the big one. An old Unity version eventually cannot produce a build the stores will accept, and upgrading the engine under a live product is real work with real risk. I wrote up the process in upgrading Unity on a live project. On React Native, the same pressure shows up as native module upgrades that have to move together.
The key property of this bucket: it arrives on someone else's calendar. You can see it coming months ahead if someone is watching, and it becomes an emergency if nobody is.
2. Dependency and security updates
Packages get vulnerabilities reported against them. Libraries you depend on stop being maintained. A build tool drops support for the runtime version you are on. Even my own small site has had its deploy tooling break because a newer Node version was installed and the CLI did not support it yet.
Small, regular updates are cheap. One giant upgrade after two years of silence is expensive, because you are untangling a dozen breaking changes at once and you cannot tell which one broke what. On the React, TypeScript and GraphQL dashboard I provide CTO guidance on at Bettershop Consulting, the rule is boring and effective: update often, in small steps, with something checking that the important flows still work.
3. Monitoring and fixes
This is everything that comes from production: crash reports, error logs, slow screens, failed background jobs, the support email that says "it just spins". Some of it is real bugs. Some is edge cases nobody could have predicted before real users arrived.
Two things make this bucket cheaper:
- Visibility. Crash reporting, error logging and alerts on the flows that make money. If you only learn about a broken checkout from a customer, you have already lost the customers who did not write in.
- Old versions in the wild. On mobile, users do not all update when you do. A backend change that is fine for the newest build can break a version from six months ago. That is why I design for it from day one, as I explained in keeping old mobile app versions working.
4. Small improvements from real usage
After launch you finally have data instead of opinions. Users get stuck on the same screen, ask for the same missing option, or use a feature in a way you did not design for. A small amount of ongoing time for these changes is usually the highest return work in the whole product.
I keep this bucket separate from new features on purpose. New features are a roadmap decision. Fixing the friction in what already exists is maintenance, and it is what turns a launched product into a product people keep using.
AI products need more maintenance, not less
Anything built on LLMs or voice AI has an extra layer that traditional software does not: the behaviour can change while the code stays the same.
On the voice agents I have built on Retell AI, with n8n and GoHighLevel behind them, maintenance includes:
- Model and platform changes. Providers update and retire models. A new model can be better overall and still handle one of your critical phrasings differently. The only defence is a set of test conversations you run again after every change, which is the subject of regression testing voice agents.
- Stale knowledge. Opening hours, prices, staff and policies change on the business side. A stale fact sounds just as confident as a correct one, so someone has to own updating it. I covered that in what a voice agent should actually know.
- Integrations that fail quietly. A CRM field gets renamed, an API token expires, a webhook starts timing out. The call goes fine and the follow-up never happens. That failure mode has its own post: post-call automation failures.
- Compliance and carriers. SMS registration, consent rules and telephony requirements shift over time, especially in the US.
AI costs are also a maintenance concern. Usage grows, prices change, and a prompt that was cheap at a hundred users is not cheap at ten thousand. On LectureNotes AI, knowing what each user actually cost us was part of running the product, not a one-off calculation. I wrote about that in AI app unit economics.
How to budget for maintenance
I do not give clients a single percentage, because it depends too much on the product. A web dashboard with a handful of dependencies is cheap to keep alive. A mobile app plus a Unity layer plus a web portal plus a voice agent touching three external services is not. Instead I look at what drives the cost:
- How many platforms you ship on. Web only is the cheapest. Each mobile platform adds its own store, OS cycle and review process. Unity, XR headsets and native plugins add more.
- How many external services you depend on. Every integration is a contract with someone else's roadmap.
- Whether there is AI in the loop. Model changes, prompt testing and cost monitoring are recurring work.
- How regulated the domain is. Healthcare, finance and anything recording calls carries compliance upkeep.
- How much traffic and data you have. Scale turns rare bugs into daily ones.
The practical structure that works for most early products is a small monthly retainer that covers the first three buckets reliably, plus a separate, flexible amount for improvements. That way the essential upkeep never waits for a budget meeting. If you are weighing how to structure that arrangement, I compared the options in fixed price vs hourly vs retainer.
What to set up before launch day
Most maintenance pain is decided before the product ships. If I am building something, these are in place before launch:
- Every account owned by the company. App store accounts, cloud, domain, repository, AI platforms and telephony. A maintainer who leaves must not take the ability to ship with them.
- A written runbook. How to build, how to deploy, where the secrets live, which services exist and who to contact when they break.
- Crash reporting and error alerts on the flows that matter.
- A version gate and remote flags in mobile apps, so a broken old version can be asked to update.
- A small test suite or checklist for the critical paths, including test calls for voice agents.
- A calendar of known deadlines: store requirement changes, certificate expiries, plan renewals.
If you are inheriting a product that has none of this, start with an audit before touching features. My checklist is in inheriting a codebase: the first week.
The cost of skipping it
Skipping maintenance does not save the money. It moves the bill to the worst possible moment: the week your app gets removed from search on Google Play, the day a security issue is reported, or the morning your biggest customer cannot log in. At that point the work costs more, because it is rushed, it is stacked on years of deferred updates, and the person doing it may be new to the codebase.
The products I have seen stay healthy for years are not the ones with the cleverest code. They are the ones where somebody owns the boring upkeep every month.
I build and maintain AI voice agents, web and mobile apps, and Unity and AR/XR products for founders and teams in the US, UK and Europe. If you have a product that is about to launch, or one that has been running without anyone watching it, more about my background here, or book a call and I will tell you honestly what it needs to stay healthy.