Aditya Sharma

Automation

What Self-Hosting Actually Costs, Against the SaaS You Are Replacing

On this page, 10 sections

I ran docker system df on my laptop while writing this. It is a work machine, not a server:

$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images            102        49    67.03GB   21.89GB (32%)
Containers         81        29      973MB   622.2MB (63%)
Local Volumes      90        54    17.88GB   4.491GB (25%)
Build Cache       702         0    27.23GB   7.423GB
Bar chart of monthly cost: Firecrawl Standard $83, self-hosted crawler $28.80, self-hosted Plausible $14.40, Plausible Cloud Starter $9
Vendor pricing pages plus DigitalOcean droplet and backup pricing, all read 2 September 2026.

112 GB. None of that appears in any self-hosting cost comparison I have read,

because those comparisons all compute the same two numbers: the VPS price and the SaaS price.

The VPS price is the smallest honest line in the whole calculation.

So here is the version with the rest of the lines filled in, using my own server and my own laptop, checked on 2 September 2026.

The conclusion is split: for the crawling and search workload, self-hosting wins by roughly 3x and keeps winning as volume grows.

For analytics on a single small site, it loses to a $9 subscription and I keep doing it anyway, for a reason I can name.

Line 1: the machine

Hetzner is where my box lives, but their price grid is injected client-side and does not render for a crawler, so I will not quote a figure I could not read.

DigitalOcean publishes the same class of machine server-side. Their Basic Droplets, regular CPU, monthly caps, read 2 September 2026:

MemoryvCPUTransferSSD$/mo
512 MiB1 vCPU500 GiB10 GiB$4.00
1 GiB1 vCPU1,000 GiB25 GiB$6.00
2 GiB1 vCPU2,000 GiB50 GiB$12.00
2 GiB2 vCPUs3,000 GiB60 GiB$18.00
4 GiB2 vCPUs4,000 GiB80 GiB$24.00
8 GiB4 vCPUs5,000 GiB160 GiB$48.00
16 GiB8 vCPUs6,000 GiB320 GiB$96.00
The DigitalOcean Droplets pricing page showing per-second billing from 1 January 2026 and the Basic Droplet table
digitalocean.com/pricing/droplets. Screenshot taken 3 September 2026.

Which line my own box sits on

My server runs seven containers: Plausible plus ClickHouse plus Postgres, Crawl4AI, SearXNG, FalkorDB and n8n. free -m shows 7,750 MiB of RAM. The equivalent line is the $48 one.

Hold that number, because three later lines are calculated from it rather than from anything about my data.

Line 2: backups, which are priced on the machine and not the data

DigitalOcean backups pricing table showing daily backups at 30 percent of Droplet cost and weekly at 20 percent
DigitalOcean percentage-based backup pricing. Screenshot taken 2 September 2026 from digitalocean.com/pricing/backups.

Daily: 7 backups, 7 days of retention, 30 percent of Droplet cost. Weekly: 4 backups, 4 weeks of retention, 20 percent of Droplet cost.

There is also a usage-based option starting at $0.01/GiB per month with frequencies up to every 4 hours and retention from 3 days to 6 months, and Droplet snapshots at $0.06/GB per month.

What that costs on the $48 machine

On the $48 machine that is $14.40 a month for daily or $9.60 for weekly. Note what drives it: the size of the Droplet, not the size of what you are protecting.

My analytics data is 4.36 MiB. My backup bill is calculated on 160 GiB of provisioned SSD.

Snapshots are priced differently again

Snapshots price on used disk instead. df -h / on my host shows 73G of 150G used, so a single snapshot at $0.06/GB is $4.38 a month, standing still.

Line 1 plus line 2, weekly backups: $57.60.

Line 3: monitoring, and the flaw in the free answer

Uptime Kuma, in two files

The self-hosted answer is Uptime Kuma, and it is genuinely good. Two files:

services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    restart: unless-stopped
    volumes:
      - ./data:/app/data
    ports:
      - "3001:3001"

HTTP, TCP, keyword, JSON query, ping, DNS, push and Docker container checks, 20-second intervals, 90-plus notification services, status pages. Cost in cash: zero.

The Uptime Kuma README showing the docker run command and the Node.js, Git and pm2 requirements of the non-Docker path
github.com/louislam/uptime-kuma README. Screenshot taken 3 September 2026.

The flaw in the free answer

Cost in honesty: if you run it on the box it is watching, it goes down with the box, and the alert you needed most is the one it cannot send.

That is not a criticism of the tool.

It is the structural problem with self-hosted monitoring, and the fix is another machine, which is another line item, or a hosted checker on the outside.

What the hosted checker costs

UptimeRobot’s free tier gives 50 monitors at zero, and their Solo plan is listed at €10 a month, or €9 on annual billing, with 10 monitors (uptimerobot.com/pricing, read 2 September 2026).

Their Team plan is €41 monthly or €35 annual. For most single-server setups the free tier genuinely covers it, so this line can be zero.

It is only zero if you set it up, and setting it up is line 4.

Line 4: your own attention, which I will count in events rather than invent a rate

Four things this box asked of me

Nobody can tell you what your hour is worth, and I am not going to make up a number and multiply it.

What I can do is list what this one server actually asked of me this year, each item verifiable from the box:

  1. ClickHouse has restarted five times. docker inspect reports RestartCount 5. OOMKilled is false on the current run, so I cannot attribute those to memory and I am not going to.
  2. Every major search engine got suspended on 31 August 2026. My SearXNG settings.yml carries a dated comment: Added 2026-08-31 after brave/duckduckgo/google-cse/startpage all suspended. That was an evening rewriting the engine list to independent indexes.
  3. 8.3 GB of ClickHouse system logs, found today. Ten months of accumulation because my compose file does not mount the config Plausible’s own reference compose mounts. Nothing alerted. Nothing broke. It was simply true for ten months, and the full breakdown of that ClickHouse volume is its own post.
  4. A pinned image tag that was never applied, found today. The compose file says v3.2.1; docker inspect on the running container says latest, built 15 May 2026.

Drift, not incidents

Two of those four I only found because I sat down to write this. That is the real shape of the cost.

It is drift rather than incidents, and you do not notice drift until you go looking. Put an hour a month against it and you are being optimistic.

Line 5: the incident, which I cannot show you

This is the part where a post like this usually tells you about the Saturday night the disk filled.

I do not have one to tell you about on this box, and inventing one would be worse than leaving the section thin.

uptime reports 121 days, and I have no recorded outage.

The near miss

What I can show you is the near miss, which is more useful anyway:

$ free -m
               total   used   free  shared  buff/cache  available
Mem:            7750   4386    356     455        3747        3363
Swap:           2047   1808    239

1,808 MiB of 2,047 MiB of swap in use. That machine has already spilled almost everything it can spill.

And docker stats shows two containers, FalkorDB and n8n, reporting 7.569GiB as their memory limit, which is Docker’s way of saying no limit was set.

Add a 3 GB ClickHouse log table growing quietly underneath and you have all three ingredients of an incident with none of them yet arranged in the right order.

Seven services, one kernel, one disk

The single-box risk is the one to price honestly. Seven services, one kernel, one disk. When it goes, all seven go, and your monitoring goes with them if you took the free option in line 3.

The other side of the ledger

Now the subscriptions this replaces, all read 2 September 2026:

ServicePlanPrice
Plausible CloudStarter (1 site, 3 yr)$9 / month
Plausible CloudGrowth (3 sites)$14 / month
Plausible CloudBusiness (10 sites, 5 yr)$19 / month
FirecrawlStandard, 100,000 credits$83 / month
FirecrawlScale, 1,000,000 credits$599 / month
Brave Search APIpay as you go$5 per 1,000 requests

What those prices assume

Plausible Cloud figures are at the pricing slider’s default position of 10,000 monthly pageviews and rise with traffic. Firecrawl credits do not roll over on self-serve plans. Brave includes $5 of free credits a month.

The arithmetic, done twice, with two different answers

Plausible's own page reporting 20k paying subscribers, 313B tracked pageviews and 99.99 percent uptime over the last 90 days
plausible.io, the vendor’s own numbers. Screenshot taken 3 September 2026.

Analytics, one small site

Analytics, one small site. Self-hosted needs a machine that meets the 2 GB the Plausible README asks for, so $12 a month minimum, plus $2.40 of weekly backups, plus the ten months I did not notice 8 GB of logs.

Plausible Cloud Starter is $9 and includes their operations team.

Cloud wins. I self-host anyway for two reasons that are worth money to me and might not be to you: no pageview meter, and a ClickHouse client I can point at the raw event table, which Cloud lists only under Enterprise.

Crawling and search

Crawling and search. My wrapper reported 505/2000 requests used on the day I wrote this, against a self-imposed ceiling of 2,000 a day.

Call it 15,000 fetches a month at current pace, 60,000 at the ceiling. Both fit inside Firecrawl’s Standard plan, so the hosted bill is a flat $83 a month either way.

If crawling were this box’s only job, Crawl4AI and SearXNG fit comfortably on the $24 line: they use 606 MiB and 82 MiB of RAM respectively and about 4.2 GB of image.

Add weekly backups and that is $28.80. Self-hosting wins by about 2.9x, and the gap widens with every extra request because one side is metered and the other is not.

That is the rule I would extract from the whole exercise, and it has nothing to do with ideology:

Self-host the things that are metered per unit of work and that you do a great deal of.

Pay for the things that are metered per seat or per site and that you do a little of. That is the only self-hosting heuristic I trust.

Why the answer splits

Crawling is metered per request and I make thousands. Analytics is metered per site and I have one. The maths follows from that, not from a preference.

The lines almost everyone leaves out

  • Backups priced on the machine, not the data. 20 percent of a $48 Droplet is $9.60 whether you are protecting 4 MiB or 100 GB.
  • Snapshot storage that never shrinks. $0.06/GB per month against used disk, and used disk only goes up.
  • Log and image creep. 8.6 GB of ClickHouse on the server, 9.97 GB of images on the server, 67 GB of images and 27 GB of build cache on the laptop, most of it from local WordPress development environments. All of it silent.
  • Egress ceilings. DigitalOcean’s included transfer runs from 500 GiB on the $4 plan to 6,000 GiB on the $96 plan. Fine for a crawler that mostly downloads, not fine if you start serving media.
  • Monitoring that survives the outage. Free only if it lives somewhere else.
  • The upgrade you keep postponing. A pinned tag is a promise, and docker compose up -d is the moment it becomes true.

If you manage servers for other people, this is the same conversation as who pays for WordPress plugin subscriptions on client sites, one layer down.

Recurring cost is easy to see and easy to argue about. Recurring attention is neither, and it is the one that decides whether the arrangement lasts.

The operational side of that, at scale, is in managing WordPress sites for clients, and if backups are the line you are pricing right now, the WP Umbrella against Updraft Central comparison covers the hosted versions of that specific job.

Resources

One thing to do now

Take your monthly server bill, multiply it by 0.2, and write that number next to it. That is the backup line you probably are not paying and therefore probably do not have.

Then run docker system df and see how much of your disk is reclaimable.

Mine was 21.89 GB of images and 7.42 GB of build cache, on a machine I would have told you was clean.

Tell me where I am wrong

Your email is not published and I do not add it to any list. Corrections with a source are the ones I act on fastest.

Keep reading

More in Automation

Every piece in Automation

  1. 01 Running a Self-Hosted Crawler: Crawl4AI and SearXNG in Docker Real images, real limits, and the SearXNG failure that returns HTTP 200 with zero results and makes you write down findings that are not… Automation 10 min
  2. 02 WordPress in Docker for Local Development: wp-env vs the Alternatives Three environments timed on one plugin: 123s, 14s and 8s. Real commands, real disk cost, and the error that names a host you never… Automation 10 min
  3. 03 Add a “Go to Settings” Link After Installing Any WordPress Plugin (Full Code) After you install or update a plugin, WordPress makes you hunt for its settings page. This snippet adds a correct “Go to settings” link… Automation 13 min
  4. 04 Build a One-Click EDD Refund Button Inside Fluent Support (Full Code) The complete snippet for a one-click EDD refund-and-cancel button in the Fluent Support ticket sidebar — plus the five Vue-SPA gotchas that make it… Automation 7 min
  5. 05 How to Apply a WordPress Email Template to Only Specific Emails Email-template plugins wrap every WordPress email — including your FluentCRM newsletters. Here's the tested way to apply the template to only the senders you… Automation 6 min
  6. 06 AI Memory Tools for a Second Brain: mem0 vs MemPalace vs Graphiti vs Letta vs Supermemory vs Khoj vs Cognee Benchmarked comparison of the 7 AI memory tools that actually matter for a second brain: mem0, MemPalace, Graphiti, Letta, Supermemory, Khoj and Cognee. Real… Automation 23 min