Skip to content
Development9 min read

The Automation That Earns Its Keep (And the Kind That Doesn't)

Six things we automated that saved real hours, two we built and deleted, and the rule we use to decide which is which.

Bilal Rehman

Lead Developer, Quesiono

Automation has a marketing problem: the case studies are always about the automation that worked. Nobody writes up the script they maintained for eight months to save four minutes a week.

So here's both halves. Six things we automated that clearly paid for themselves, two we built and later deleted, and the rule we now apply before writing any of it.

The rule

Time saved per run, times runs per month, minus time to maintain per month. If that isn't comfortably positive within a quarter, don't build it.

The maintenance term is the one everyone forgets. Every script is a small ongoing obligation: it breaks when an API changes, it needs credentials rotated, and it confuses whoever inherits it. A script that saves ten minutes a month and breaks twice a year is a net loss, and it's also a thing someone has to understand at the worst possible moment.

Corollary: automate the thing that's done often and identically. Leave the thing done rarely and thoughtfully alone.

1. A deploy preview per branch

The highest-value automation in client work, and it isn't close.

Every branch gets its own URL. Feedback happens on a real, clickable page instead of in a thread about a screenshot. Clients stop asking when they can see it. Nobody argues about whether something is fixed.

Before this, our review cycle was: build locally, screenshot, email, wait, receive a reply about a thing that was already fixed. Now the client opens a link. It cut a genuine week off a ten-week project, mostly by removing the ambiguity rather than the steps.

Setup is close to free on Vercel or Netlify — it's on by default. Add a comment bot that posts the URL onto the pull request and it's complete.

2. Checks that run before anyone reviews

Type check, lint, and build on every push. Nothing clever, and it removes an entire category of review comment.

Our workflow runs three commands: npm run lint, tsc --noEmit, and npm run build. The build step is the one people skip and the one that catches most — bad static params, metadata type errors, a component importing a server-only module into a client boundary. None of those fail in dev.

One rule that matters: the checks must be fast enough that people wait for them. Ours run in about ninety seconds. Past four or five minutes people stop watching, merge anyway, and the automation becomes a notification system for failures nobody reads.

3. Performance budgets, enforced

Performance regressions arrive one plausible commit at a time. A tracking script here, an unoptimised hero image there, and four months later the site is two seconds slower and no single change is to blame.

Lighthouse CI on every pull request against a budget: LCP under 2.5 seconds, CLS under 0.1, JavaScript payload under a set number of kilobytes. Exceed it and the check goes red with the numbers attached.

The argument then becomes concrete. "This adds 40KB and 300 milliseconds of LCP, is it worth it?" is a decision. "The site feels slower" is a conversation that goes nowhere.

Two practical notes. Run against a deployed preview, not a local build, or the numbers are fiction. And set the threshold slightly above current performance — a budget that's already failing gets ignored within a week.

4. Validating our own data

This one is specific to how we build, and it's saved more debugging time than anything else on the list.

Our sites are heavily data-driven. Services, case studies, industries, and blog posts all live in typed files and reference each other by slug — a case study lists the services it used, a service lists related posts, an industry lists case studies. TypeScript checks that a slug is a string. It cannot check that the string names something real.

So a typo produces a link to nowhere, or a related-work rail that silently renders empty. Not a crash, which is worse: it just quietly isn't there.

The fix is about forty lines. A script that loads every data file, collects the valid slug sets, walks every cross-reference array, and prints the ones that don't resolve. It runs in CI and locally after any data edit. On a recent rebuild it caught six broken references, five of which were posts referenced before they were written and one of which was an actual typo that would have shipped.

If your content model has references, write the checker. It's a morning's work and it converts a class of silent bug into a red build.

5. Uptime and form monitoring

A client emailing to say their site is down is the wrong way to find out, and a contact form failing silently is worse — nothing looks broken and enquiries just stop.

Two checks per site: an HTTP ping every five minutes, and a synthetic form submission daily that posts a test payload and confirms the email arrives. The second one has caught things the first never would. A mail provider changed a sending domain requirement once and forms failed quietly for a day. We found out at 8am from an alert rather than three weeks later from a client wondering where their enquiries went.

Also worth alerting on: SSL certificate expiry at fourteen days, and a 404 rate spike, which usually means a redirect got dropped in a deploy.

6. Client reporting, assembled not written

Monthly reports used to take about two hours each: pull Search Console, pull analytics, pull uptime, paste into a document, write commentary.

Now a scheduled job pulls the data and produces the numbers with month-on-month deltas. What it does not do is write the commentary. The interesting part of a report is why something moved, and that requires knowing what we shipped and what the client's market did. A generated paragraph of "traffic increased 12% month on month" is worth nothing to anyone.

So: numbers automated, judgement not. Two hours became twenty minutes, and the twenty minutes is the part clients actually read. This is the shape most reporting automation should take, and most of it overreaches into the commentary and produces filler.

The two we deleted

Automated dependency updates, merging on green. Sounded excellent. In practice it produced fifteen pull requests a week per project, most of them for transitive dev dependencies, and the review burden exceeded the security benefit. Twice, a minor version bump that passed all checks changed runtime behaviour subtly enough that nobody noticed for days.

What we do now: security advisories get automatic pull requests and immediate attention. Everything else gets batched into a deliberate monthly session where someone reads the changelogs. Fewer updates, actually understood.

A Slack bot that posted every deploy, commit, and check result. Within three weeks the channel was unreadable and people muted it, which meant the genuinely important messages were muted too. Deleted, replaced with alerts only for production failures. Signal has a denominator.

What we deliberately don't automate

  • Deploying to production. Automatic on merge to main sounds right and we don't do it for client sites. Someone presses the button, having decided this is a sensible moment. Fridays exist.
  • Copy and content. For fairly obvious reasons if you've read anything else on this blog.
  • Accessibility. Automated tooling catches maybe 30% of real issues — missing labels, bad contrast ratios, absent alt attributes. It cannot tell you the tab order is illogical or that a modal traps focus badly. Run the tool, then use a keyboard and a screen reader.
  • Anything done twice a year. The script would be stale by the second run.

If you're starting from nothing

In this order, and stop when the benefit stops being obvious:

  1. Deploy previews per branch. Nearly free, largest return.
  2. Lint, types, and build on every push.
  3. Uptime and form monitoring.
  4. A performance budget, once the first three are habit.

That's a day of setup and it removes most of the recurring friction in a small team's week. Everything past it should have to justify itself against the rule at the top, including — especially — the automation that seems clever.

We build this into every maintenance arrangement, because the alternative is finding out about problems from the client.

Want us to do it

The services behind this article

If you'd rather not run this yourself, these are the pages that cover it.

Got a project

Prefer to hand this to someone else?

Tell us what the site needs to do. You'll get a straight answer on scope, timeline and cost — usually inside one working day.

Rather write first?hello@quesiono.com— we reply within one business day.