Skip to content

Behind the scenes

How getReport stays free

One server, Google's free speed data and a 12-hour cache keep a report near zero. Donations switch the bigger features on for everyone.

getReport team9 min readUpdated 2 Oct 2026

getReport has no paid plan, no trial and no ads. That is not a promotion that ends when enough of you sign up; it is the product decision everything else serves. The moment a website checkup has a paid tier, every finding becomes a sales argument: the free scan shows you three problems and blurs the rest, the severity labels drift towards alarming, and the report page turns into a funnel. We wanted the opposite: one report you can trust precisely because nobody earns anything by scaring you.

A free product still gets an invoice at the end of the month, though. This post is the honest version of how that invoice stays small, what donations actually switch on, what they don't buy, and what would happen if they stopped coming.

  • 1server runs the site, the database and every check
  • 0paid APIs for speed data, within Google's daily quota
  • 12 ha report is reused for the same address

Free only works if a report costs almost nothing

"Free" is easy to promise and hard to keep. Plenty of free tools quietly degrade, bolt on a paid tier, or disappear when the founder's patience runs out. The only version of free that survives is the one where the cost of serving you rounds to zero, so that no growth curve can turn the tool into a liability.

So the real engineering constraint behind getReport is not speed or scale. It is this: a report must cost so little that giving it away is sustainable on donations alone, indefinitely. Every architectural choice below follows from that one sentence.

One server does all of it

A virtual server in Germany with 4 cores, 8 GB of memory and 75 GB of disk runs the website, the API, the queue, the database and the workers that fetch and render pages. Screenshots and PDFs go to Cloudflare R2, which charges for storage but not for downloads, and Cloudflare sits in front of the site.

That is the whole production footprint. There is no fleet to scale, no managed database bill that grows with every row, and no per-seat SaaS stack behind the scenes. A small server is not a limitation we are waiting to outgrow; it is the design. When you know the whole system has to fit on one machine, you stop adding things that don't pay their way.

Why a report costs so little

The expensive part of a website report is measuring speed: loading the page in a real browser, several times, on a throttled phone profile. Google runs exactly that measurement for anyone through the PageSpeed Insights API (it powers our speed test), and the Chrome UX Report API adds real visitors' speed data (our Core Web Vitals check). Both are free within a daily quota, so we use them first and only render the page ourselves for what they don't cover (accessibility, screenshots, the WordPress plugin cost breakdown).

Everything else is small: one HTTP request for the page, a few for robots.txt, the sitemap and headers, a TLS handshake, some HTML parsing. The methodology lists every request a report makes. That is milliseconds of work per check, on hardware we have already paid for.

The more reports, the cheaper each one

The server is a fixed cost, so what one report costs depends on how many we run:

Server cost per fresh report, relative to 100 reports a day (= 100)
  • 100 a day100
  • 300 a day33
  • 1,000 a day10

Source: our hosting invoices, September 2026: the fixed monthly cost divided by 30 days of reports at each volume. Cached reports add nothing.

This is the opposite economics of a pay-per-use API bill, and it is why donations work as a funding model here: a busy month does not cost meaningfully more than a quiet one, so support doesn't have to grow in lockstep with traffic. At some volume the server will be full. The plan then is a second worker machine, which roughly doubles capacity, so the cost per report stays in the same range.

The limits that keep the bill flat

A free tool with an uncapped bill is one viral post away from trouble. So nothing in getReport's cost grows without a cap:

  • Cache. A report for the same normalised address within 12 hours is the same report. A cache hit costs nothing. (Your own site can do the same for its visitors: caching for humans.)
  • Rate limits. Up to 10 fresh reports per visitor every 10 minutes and 50 a day, and 5 fresh reports per target site per hour.
  • A daily cap tied to Google's quota. If it runs out, the speed test runs Lighthouse on our own server and labels the result a lab estimate, rather than calling a paid service.
  • One job at a time per page. Two people checking the same site at the same moment share one run.

When there is a spike, reports queue for longer. They don't get more expensive. That last sentence is the entire risk model: the worst day getReport can have is a slow one, never an expensive one.

Funded unlocks: how donations switch features on

The core report is cheap enough to give away. Some features are not: they need their own infrastructure, more server capacity, or a paid data supplier. We don't sell those features, and we don't lock them behind a donor badge. Instead, each one is a rung on the unlock ladder you can see on the funding page, and the rule is mechanical:

  1. Every unlock has a running monthly cost and a monthly support level that covers it with headroom.
  2. When donations hold above that level for 7 days, the unlock switches on.
  3. It switches on for everyone. Donors and non-donors get exactly the same product on the same day.

The first rungs are already on for everyone, because within their limits they cost next to nothing on the current server: the sitemap generator, which crawls up to 100 pages and writes your sitemap.xml, and the page change monitor, which emails you when the visible text of up to 5 pages changes, checked daily.

The rungs that donations are working towards are the ones with real running costs:

  • A site crawl of up to 500 pages, re-checked weekly: broken links, duplicate titles, orphan pages, a sitemap diff and a CSV export. Today the report sees one page at a time; a crawl finds the problems that live between pages, like broken internal links buried in old posts.
  • Daily speed monitoring with email alerts for 1,000 sites: score drops, LCP regressions, new security findings, and a certificate about to expire before it takes your site down.
  • A US test location (Ashburn), so every speed test can run from the US as well as Frankfurt, with Singapore as a later rung, then uptime monitoring with 5-minute checks from 3 regions, and a weekly rank snapshot for 10 keywords, bought from a data supplier.

No unlock has a date attached, because dates would be a promise about other people's generosity. The ladder has an order, the funding page shows which rung is next, and that is as much as we will predict.

  • 500pages in the funded site crawl, re-checked weekly
  • 1,000sites the daily monitoring unlock covers
  • 7 daysdonations must hold a level before an unlock switches on

What a donation does not buy

This part matters more than the ladder. A donation to getReport buys nothing for the donor that everyone else doesn't get:

  • No priority lane. Your report waits in the same queue as everyone else's.
  • No donor-only features, ever. If a feature exists, it is on for every visitor, or it is not on at all.
  • No influence on results. Companies that sponsor monthly can have a logo on the funding page and in the footer, and that is all: logos never appear inside findings, and sponsors cannot affect a score or a check.

If you donate, you are not buying access. You are moving the whole ladder up, for everyone, including the people who will never give anything. That is the deal, stated plainly, and it is also why we can keep every report honest: there is no customer to please, only a bill to cover.

What happens if donations don't cover it

An honest funding page needs an honest failure mode, so here it is.

Every feature that costs real money sits behind its own flag and its own kill switch, independent of the rest. If support drops below what a rung costs, that rung can be paused without touching anything beneath it: the rank snapshot before the extra locations, the extra locations before monitoring, each one a clean switch rather than a slow rot. The funding page would show it plainly, the same way it shows what is live today.

What never pauses is the core: the single-page report with all its checks, the 12-month report history, the PDF and JSON export, and the badge. Its cost is the server itself, and the server is the one bill we treat as non-negotiable. If Google's daily speed quota runs out, reports fall back to a lab estimate measured on our own machine and say so on the result. Degraded means slower or more clearly labelled, never "pay to continue".

Why there are no ads or trackers

The cheapest funding model would have been advertising, and we ruled it out on day one, for a reason that is specific to this kind of tool: you tell getReport which sites you are working on. An advertising business attached to that stream of addresses would be worth more than the tool, and it would deserve none of your trust.

So: our analytics are self-hosted and the numbers stay on our server. We ask before Google Analytics may count visits, it runs only if you accept, and it never sees the addresses you check or anything you type. Reports ask search engines to stay out unless the verified site owner opts in, so a report is seen only by the people you send it to. None of this is a compliance checkbox; it is the same decision as having no paid plan. The product is the report, not you.

The short version

getReport stays free because a report costs almost nothing to produce, and it costs almost nothing because of choices made for that purpose: one server, Google's free measurement APIs first, a 12-hour cache, and hard caps on everything that could grow. Donations cover the fixed bill and climb the unlock ladder on the funding page, and every rung they reach switches on for everyone at once. If that model ever strains, features pause cleanly and visibly, and the core report keeps running.

If you want the bigger features sooner, the funding page is where that happens. If you just want to check a site, go ahead. That is the point.

How does your site compare?

Free report, no account, ready in under a minute.

Check my site

More posts

All posts →
Behind the scenes

How we publish every day without a CMS

getReport now ships one new guide or post every day for the next six months. There is no CMS behind it: markdown files, pull requests and one scheduled rebuild.

4 min read
Product

Check your site on every deploy

The getReport GitHub Action fails your build when a score drops. The story behind it, the design decisions, and a workflow you can paste in today.

9 min read