SaaS500+
daily active users
SaaS Analytics
A reporting dashboard that replaced a fortnightly spreadsheet ritual nobody enjoyed and everybody depended on.
- Custom dashboard
- Data viz
- Next.js
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.
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.
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.
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.
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.
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.
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.
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.
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.
In this order, and stop when the benefit stops being obvious:
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.
If you'd rather not run this yourself, these are the pages that cover it.
SaaS500+
daily active users
A reporting dashboard that replaced a fortnightly spreadsheet ritual nobody enjoyed and everybody depended on.
2.9×
search-to-purchase rate
3,400 outdoor SKUs, two warehouses, and a search that couldn't find a waterproof jacket by waterproof rating.
Server components, caching, data fetching, and the four mistakes we've made on real App Router projects so you don't have to repeat them.
Read itLCP, CLS, and INP explained by cause rather than definition — and the specific fixes that moved each one on real sites, in the order we try them.
Read itNo winner. Three honest profiles, the cost of each over three years, and the specific questions that decide it.
Read itTell 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.