Cloud Support & Maintenance

Cloud support and maintenance is the part nobody demos but everybody needs: keeping applications running, patched, monitored, and improving after launch. Software Mile provides ongoing support sized to how critical the system is – not a one-size contract.

What Ongoing Support Covers

  • Monitoring and incident response, with escalation matched to what downtime costs you
  • Patching and dependency updates – including the security updates that pile up dangerously when ignored
  • Performance and cost tuning as usage grows and patterns change
  • Backup and recovery verification, because an untested backup is a hope, not a plan
  • Small enhancements and fixes on an agreed cadence, so the system keeps improving

Support on Your Terms

We support software we built and software we did not. Support hours are set to your business day and criticality – some systems need business-hours coverage, some need more. We size the arrangement to the real need, and revisit it as that changes.

Tell us what needs supporting – the application, its platform, and how critical uptime is. We will propose a support arrangement that fits.

When a Support Retainer Earns Its Cost

Not every system needs one. An internal tool with a handful of users, running on a managed platform that patches itself, where a day of downtime costs nothing but inconvenience, is usually served well enough by time-and-materials help when something breaks. A monthly retainer to watch a system nobody would miss for a day is money that could go into features instead.

A retainer earns its cost when downtime has a price. Systems that take orders, move money, hold regulated data, or sit between two other systems that keep changing all fail in ways that need a fast and informed response. The test is not how complex the software is. It is what happens in the hour after it stops.

What Is a Support SLA Really Promising You?

Support agreements mix up three different numbers. Response time is how long before someone acknowledges you. Resolution time is how long before it works again, and it is worth asking directly whether a vendor will commit to that at all for a software defect. Uptime is a property of the whole system rather than of the support contract. Ask which of the three is actually being guaranteed, and get the answer in writing.

Read the cloud provider’s own uptime figure the same way. Check what it is written against, since these commitments generally cover the provider’s infrastructure rather than your application running on it, and check what the remedy is, since a service credit and being made whole are different things. Your real protection comes from architecture and a tested recovery plan.

How Does Support Work on Software Someone Else Built?

Inheriting a codebase is a real piece of work, not a formality. Before anyone can respond quickly, the system has to build and run from source on a clean machine, access to the environments and accounts has to be in place, and somebody has to write down what nobody wrote down. Expect the first weeks to run slower than steady state while that happens, and plan the engagement around it.

If the application cannot be rebuilt from what is in version control, that becomes the first job, ahead of any feature request. A system only one machine can compile is one hard drive failure away from being unmaintainable. The principle underneath is simple: prove what the system does before changing it.

What Belongs in a Retainer and What Is a Project?

Retainers cover keeping a system healthy: monitoring, patching, incident response, dependency updates, small fixes and minor changes. Projects cover anything with a design phase, such as a new module, a platform move, or an integration with a system you have just bought. When the two blur, a support arrangement fails quietly.

Feature work absorbed into a fixed number of monthly hours crowds out maintenance, because nobody notices a missing patch until it matters. We keep the two budgets separate, which makes it visible when a request has crossed from maintenance into project work.

Cost Review Belongs in Ongoing Support

Running costs rise on their own if nobody is watching, and the causes are usually unglamorous and fixable. That is why the review belongs in ongoing support instead of an occasional audit that happens after the finance team complains. What makes it work has less to do with tooling than with cadence and authority.

Where a fix would need genuine redesign, we say so and scope it as its own piece of work. The categories where cloud spend tends to leak are set out on our cloud services page, and a retainer is where somebody actually goes looking for them.

  • Spend broken out by environment and service, read on a fixed date every month
  • Alerts on a change in the run rate, so a surprise arrives before the invoice does
  • Tags maintained as new resources are created, so new spend still has an owner
  • A standing allowance for cleanup, so removing something does not need its own approval
  • One named person with the authority to turn things off

Alerts That Correspond to Something Real

Monitoring splits into two kinds of signal, and only one of them is worth waking somebody for. Symptoms are what a user experiences: requests returning errors, a queue that stopped draining, a scheduled job that did not run, response times at the 95th or 99th percentile. Causes are CPU, memory, disk, and connection counts. Alerting on causes produces pages for conditions nobody would have noticed, while alerting on symptoms produces pages that correspond to something happening to somebody. Averages hide the cases that matter: a mean response time of 200 ms is entirely consistent with 5 percent of requests taking eight seconds, and that 5 percent is who calls you.

A second class of failure is invisible from inside the application. An expired TLS certificate, a DNS record that stopped resolving, an identity provider outage, or a CDN serving stale errors all leave the application reporting itself healthy while nobody can reach it. Checks that run from outside your network catch these. Certificate expiry is the tidiest example, because it is an outage with a known date on it: public certificate lifetimes have been shortened repeatedly and automated renewal is now the norm, so the thing worth alerting on is the renewal that quietly stopped working, several days out, rather than the expiry itself.

Alert volume is a failure mode of its own. Every alert that fires without needing action teaches the person on call that the next one can wait, and that habit is what turns a five minute incident into an hour. Alerts that have fired repeatedly without producing an action need retuning or deletion, and that review belongs on a schedule rather than falling to whoever gets annoyed enough to do it.

  • The symptom in the alert text, not only the name of the check that fired
  • A threshold with a duration attached, so one slow request or a single failed retry does not page anyone
  • A link to the dashboard or saved query that shows the same condition over time
  • A runbook entry naming what to check first and which mitigation is safe to apply without further approval
  • A named owner per alert, so one that fires uselessly for a month has somebody responsible for fixing it
  • An explicit split between what pages overnight and what waits until morning

Patching Is Two Different Jobs

Taking a security fix inside a version line and moving to a new major version are different work carrying different risk, and treating them as one number of hours per month gets both wrong. Under semantic versioning, patch and minor releases promise no breaking changes and can go through on a regular cadence with the test suite as the gate. Major versions carry deliberate breaking changes and need reading, planning, and often code changes across the application. Lockfiles matter here, because they pin exact resolved versions including transitive dependencies, so the set of packages that actually changes in an update is routinely much larger than the handful listed in the manifest, and the lockfile diff is the one worth reading.

The upgrade calendar is not entirely yours. Runtimes and managed services publish end of support dates well in advance: Node.js LTS lines are maintained for roughly 30 months from release, and managed database services deprecate old engine versions and eventually apply the upgrade in a maintenance window whether or not the application has been tested against it. Tracking those dates is maintenance work in its own right, because the alternative is doing the upgrade on a date somebody else chose.

Some upgrades cannot be taken incrementally. When a new major version of a framework cannot coexist with the old one in the same process or the same project file, there is no route where half the application moves now and the rest follows next month: the whole application is ported against the new API in one pass and tested as a whole.

Two Numbers Decide the Backup Design

Two numbers decide the design: how much data you can afford to lose, and how long you can afford to be down. A nightly snapshot means up to a day of writes are gone in a restore, while continuous archiving of the write ahead log or a point in time recovery feature brings that down to minutes, at the cost of storage and of a restore procedure with more moving parts. The second number is the one people underestimate, because restore time is not the same as snapshot age: restoring a large database means provisioning capacity, copying data, replaying logs, and repointing the application, and that clock starts when somebody decides to restore, not when the failure began.

Where the copies live decides what they protect against. Snapshots sitting in the same account and region as the system they cover share its failure modes, so an account compromise, a deleted project, or a region wide event takes the backups along with the original. Copies written to a separate account, under object lock or an equivalent retention setting that no credential in the primary account can shorten, are what survives deletion, whether the deletion was hostile or a typo. One specific trap: deleting a managed database instance normally deletes its automated backups with it, and only a final snapshot or one retained manually is still there afterward.

A restore drill is worth running for what it produces rather than for the reassurance. It produces a measured restore time, which is the only honest input to the second number, and it surfaces the pieces missing from the plan: the credential nobody could find, the DNS change nobody had rights to make, the config value that lived only in the old environment. Those are the parts that turn a two hour recovery into a two day one.

Drift Between Production and the Repository

Over a long running engagement, what is deployed and what is in version control tend to separate, one small emergency at a time. A value changed in a console during an outage, a package installed by hand on a server to get past an error, a firewall rule added at 2 a.m. Each is defensible in the moment, and none of them are in the repository the next morning.

The check is cheap and worth running early. Deploy the current main branch into a non production environment built the same way and compare behavior and configuration against production. Where infrastructure is defined as code, running a plan against the live account does the same thing for the environment, and a non empty plan on a system nobody has changed is a list of the manual edits made since the last apply. Neither check needs a maintenance window.

Drift is what makes rollback unreliable. Rolling back assumes the previous version is the thing that was running, and after enough manual edits it is not, so the rollback restores a state that was never actually in production. It also slows diagnosis, because the person reading the code is reading something other than the code executing.

  • Configuration values and feature flags set in a console or secret store and recorded nowhere else
  • Cron jobs and scheduled tasks defined on a host instead of in the repository
  • Security group, firewall, and DNS changes made during past incidents
  • Packages installed by hand on long lived servers that a freshly built instance would not have
  • Schema changes applied directly to a database and missing from the migration history
  • Deploys made by hand from a laptop, outside the pipeline and untagged in the repository

Severity, Authority, and Who Speaks During an Outage

Some things cannot be decided by the people fixing the problem, and they are much cheaper to settle before the first incident than during one. What counts as severity one is a business judgment rather than a technical one: an outage of a reporting dashboard and an outage of the path that takes orders can be identical in engineering terms and nowhere near equivalent to you. Authority works the same way. If a production change at three in the morning needs an approval and the only person who can give it is asleep and not on any list, the work stops there regardless of how fast the response was.

Communication is the other half of it. During an outage somebody has to tell your users something, and when that somebody is also the person debugging, one of the two jobs is being done badly. Naming the communicator in advance, along with where the update gets published, keeps the technical response and the customer response from competing for the same attention. The decisions worth writing down are short ones, and there are not many of them.

  • Severity definitions written against your business, with a named example system at each level
  • Who can authorize a production change outside business hours, and the fallback when that person is unreachable
  • What degraded service is acceptable as an interim step, so a partial mitigation does not need a debate
  • Who writes the customer facing update, and where it is published
  • Which environments the support team may change without asking, and which always need a ticket
  • Who is contacted when the primary escalation contact does not answer

Frequently Asked Questions

Is this the same as the support included with our cloud provider or our managed hosting?

No, and managed hosting is the layer that causes most of the confusion, because it genuinely covers more than a bare cloud account does. A managed platform or hosting plan typically patches the operating system and the web server, restarts a process that dies, and keeps the host reachable; the deploy that introduced a bug, the background job that stopped consuming its queue, and the query that started locking a table sit outside it. Exactly where that line falls differs by product, so it is worth reading the shared responsibility description for the specific plan you are on, since a managed database, a managed container platform, and plain virtual machines draw it in three different places.

What do you need to know about the third-party services our application depends on?

A list of every external service the application calls and every account behind one: payment processor, transactional email or SMS sender, identity provider, mapping or geocoding API, error tracker, analytics, and any data feed. For each, who holds the account, which credential the application uses, whether that credential expires or rotates, and what the application does when the service returns an error or a rate limit. These cause a lot of incidents that look like application failures from the inside, such as a key rotated by the vendor, a sandbox credential still sitting in a production config, or a monthly quota reached on the 20th. They are also the pieces most often missing at handover, because they are usually billed and owned separately from the cloud account.

How does onboarding proceed, and when do you start taking calls?

Access, environment setup, and getting undocumented knowledge written down come first, and taking the pager comes last. The reason for that order is that a response time which starts before monitoring and alert routing exist only means somebody answers quickly once your users tell you something is wrong, which is both slower and less specific than an alert. So monitoring and on-call routing get verified or built before any clock starts. If you already run an on-call rotation, an overlap where the incoming team shadows a real incident is worth more than any handover document.

What access and account ownership do you need on our side?

Repository access with the ability to open pull requests, a named role in the cloud account rather than a shared login, access to CI and to whatever holds logs and errors, and either the ability to make DNS and certificate changes during an incident or a documented path to someone who can within the response window. The accounts themselves should be in your company's name: the cloud account, the domain registrar, the repository organization, and the third-party service accounts, with any support team added by role underneath. That way changing or removing a vendor is a permissions change rather than a migration, and nothing critical is tied to a login only one person can reach.

We are being offered reserved capacity and committed spend discounts. Does that affect anything?

It constrains what the architecture is allowed to do for the length of the commitment. Reserved instances and committed use or savings plan agreements are one or three year commitments made by the account that buys them, and they do not follow a workload to a different provider or into a vendor's own account; depending on the type, they may not follow one that changes region or instance family either. The question to answer before signing is whether the architecture is expected to stay as it is for that long, since a commitment bought a month before a platform move is a discount on capacity you stop using. Flexible or convertible options exist for exactly that case and carry a smaller discount in exchange.

Can you support a system another team is still actively building?

Yes, but the boundary has to be explicit before it starts, because the common failure is two teams deploying into one environment without a shared release process. The points to agree on are who holds production deploy rights, whether support fixes go through the other team's branching and release process or a separate hotfix path, and what happens when an incident traces back to a change the support team did not make and cannot safely roll back. One place where every production change is recorded, whoever made it, is the difference between diagnosing an incident in minutes and reconstructing who did what.