← All writing
Craft · · 7 min

The maintenance contract nobody sells

On selling a non-event, what actually rots while nobody's looking, and the one thing that makes anyone renew.

Agency Security

A site I built in 2018 got compromised in 2021. Nothing exotic: an unpatched plugin with a known hole, exploited by something automated that scans the whole internet for exactly that.

The client rang me, we cleaned it up, they were charged for the clean-up, and everybody was slightly embarrassed.

The thing is that nobody did anything wrong at any point. I built what was commissioned. They paid what was quoted. Nobody bought maintenance because nobody sold maintenance, and the reason nobody sold it is structural rather than negligent, and I’ve been chewing on that for a while.

Why nobody sells it

From the agency side the disincentives are all pointing the same way.

A build is a project. It has a start, an end, a scope, a fixed price and a deliverable you can put on a website. Maintenance has none of those. It’s open-ended, the effort varies month to month, and there’s nothing to photograph.

New business is what sales is measured on and what agencies celebrate. Nobody has ever put “renewed a retainer for the eleventh year” on a pitch deck.

And the fundamental problem: you’re selling a non-event. The product is that nothing bad happens. Which means when it works, the client’s experience is indistinguishable from not having bought it, and after 18 months of nothing happening the line item starts to look like a subscription they forgot to cancel.

You're selling a non-event. When it works, the client's experience is exactly the same as not having bought it.

Why nobody buys it

And from the client’s side it’s just as reasonable.

The site is done. It launched, everyone clapped, it’s a thing that exists now like the office carpet. The mental model is a purchase, not a subscription, and nothing in the process corrects that.

The money is in the wrong shape too. A build is a one-off amount somebody approved once, often out of a project budget. Ongoing monthly spend goes through a completely different approval, gets reviewed annually by somebody who wasn’t in the original conversation, and has to justify itself against things with visible outputs.

And the category has been discredited. Nearly every client I’ve spoken to about this has previously paid an agency a couple of hundred a month for what turned out to be an automated PDF listing plugin updates and a traffic chart. So “maintenance” as a word arrives already meaning “money for nothing,” and I can’t blame anyone for that, because I’ve seen those reports.

What actually rots

The useful thing to be concrete about, because “things decay” persuades nobody.

Security updates, obviously, which is the one everybody names and the one that got that 2018 site.

The platform underneath. The language runtime this thing was built on has a support end date. When it passes, the host will eventually move the site onto a newer version, on their schedule, possibly with two weeks’ notice, and if the code isn’t ready the site breaks. This is the single most predictable failure in this whole list and the one that surprises clients most, because it arrives from a direction they didn’t know existed.

Integrations. The payment provider deprecates a version of their API. The mailing platform changes an endpoint. The map service starts requiring a billing account. Each of these is somebody else’s roadmap arriving on a Tuesday.

The web changing underneath it. Cookie handling rules tightened, autoplay policies changed, browsers started blocking things they used to allow. Sites that worked at launch quietly stop doing one specific thing and nobody notices for months.

Certificates, domains and DNS, which is the whole 2017 handoff post and which still causes more emergencies than code.

And the content. Dead links, a staff page listing three people who’ve left, a notice about opening hours from 2020. Nobody thinks of that as maintenance and it’s the part customers actually see.

Report the non-events

If there’s one thing in this post that’s worth acting on, it’s this.

The reason retainers get canceled is that nothing visible happens. So make the nothing visible. A short monthly note, in plain words, saying exactly what was done and what didn’t happen as a result.

the monthly note
June

- Applied 14 updates. Three were security fixes, one of them for a
  vulnerability being actively exploited elsewhere.
- Restored last week's backup into a test environment. It worked. (We
  do this quarterly because a backup nobody has restored is a rumor.)
- Submitted the contact and quote forms. Both arrived.
- Checked the certificate: renews automatically in October.
- Noted: the version of PHP the site runs on stops getting security
  patches in about 14 months. We should plan that upgrade next spring
  rather than in a hurry.
Text

That takes 15 minutes to write and it is the difference between renewing and not. I’m fairly confident it’s the single highest-return quarter-hour in this entire line of work.

The last item is doing something extra, incidentally: it converts the retainer from insurance into foresight. A client who is told 14 months ahead about a platform upgrade experiences you as looking after them. The same client, told with three weeks’ notice, experiences an emergency invoice.

How I’d price it

Openly, and against a benchmark, because a number with no reasoning behind it reads as a guess.

The convention in software generally is somewhere around 15 to 20% of the build cost per year for ongoing support, and saying that out loud helps, because it’s a figure the client can go and check rather than a number I invented.

Two things I’d include that aren’t strictly maintenance.

A small pot of hours each month for small changes, which they can spend on anything. This matters more than it sounds. It turns a grudge purchase into a service they actively use, so the relationship stays warm, so when something does go wrong you’re someone they already talk to rather than someone they have to ring.

And an annual written review: what’s coming, what’s aging, what should be budgeted for next year. One page. It’s the only document in the arrangement that’s obviously worth money on its own.

I’m not good at selling this

The bit I’d rather not write: I’m not good at selling this. Every retainer I have came from a client asking me, not from me offering. I find the conversation awkward because it feels like selling fear, and I’ve noticed that “it feels like selling fear” is a very convenient thing for me to feel, since it lets me skip a difficult conversation and call it integrity.

It isn’t fear. The version of it that’s fear is “you’ll get hacked.” The version that’s true is “in fourteen months this stops receiving security patches, here’s what we should do about that, and it’s cheaper in March than in a panic in December.”

An industry where everyone sells builds and nobody sells upkeep produces a web full of slowly rotting sites owned by people who think they bought something finished. I’ve contributed to that, at least once, in 2018.

Read similar posts
16 min

It said it was working

Porting a Claude Code safety tool from Linux to macOS turned into six weeks of discovering that nearly every failure mode on the new platform was silent, and that the tool's own adversarial test suite was the only reason I could see any of them.

6 min

.gitignore

A live payment key in a tracked `.env` file. The repository had `.env` in its `.gitignore`, and had done for two years.