PostgreSQL on Hetzner vs ServersCamp: a ~EUR 100 database server

Consumer benchmark: vanilla PostgreSQL, two VMs per side, one afternoon. July 2026.

The story of why we ran a test we expected to lose, and how that felt, is in the blog post: The benchmark we expected to lose. This page is the numbers.

You have about a hundred euros a month and a database that intends to grow. What do you actually get for that money? We bought the closest thing to the same database server from Hetzner and from ourselves, put vanilla PostgreSQL 18.4 on both, and ran the same pgbench battery over a ladder of database sizes: from fits-in-RAM to ten times bigger than RAM. Every command is in this article; the whole thing reproduces in an afternoon from a plain console.

TL;DR

Writes, commits, big databases

ServersCamp wins

  • TPC-B writes: +13% to +18% at every database size
  • Raw commit rate: 41.9k/s vs 34.8k/s (+20%) at lower latency
  • Reads on 44-88 GB databases: +12%
  • Bulk load 1.6x faster, latency lower everywhere, jitter roughly half

Small in-RAM databases, reads

Hetzner wins

  • 2x the RAM for the money: 16 GB vs our 8
  • Reads on a 1.5 GB database: 48.3k vs 43.5k qps (+10%)
  • Reads at the 15 GB cache edge: +5%
  • And the check is EUR 16.73 smaller
The one-line verdict. If your whole database fits in RAM and mostly reads, the cheaper Hetzner box is a fine deal. The moment the database grows past RAM or the workload writes in earnest, the ServersCamp box is faster at everything we measured, with visibly steadier behavior, and that is what the extra EUR 17 a month buys.

The contenderstop

 HetznerServersCamp
DB serverCCX23, "4 dedicated vCPU" / 16 GBhf-m Sustained, 4 vCPU / 8 GB
CPUAMD EPYC MilanAMD EPYC 4565P, up to 5.7 GHz
Disk160 GB local NVMe, included160 GB Database-class W4: replicated network NVMe with power-loss protection, 150k IOPS / 2 GB/s
What kills the diskThe host dying kills itSurvives the host: replicated across nodes
Network between the two VMsPublic IPs in one DC (private networks exist but are extra setup); ping RTT avg 0.81 msDefault private network, zero setup; ping RTT avg 0.13 ms
OS / PostgreSQLUbuntu 26.04, PostgreSQL 18.4 from PGDG, same pgtune OLTP formula on both (values from each box's own RAM/cores)
Client VM (not part of the compared check)CPX22, 2 shared vCPU / 4 GB, EUR 19.99hf-s, 2 vCPU / 4 GB, EUR 20.50
Monthly check, incl. IPv4EUR 86.49EUR 103.22

The checks differ by EUR 16.73 and the machines differ in shape: Hetzner spends the money on 2x the RAM, we spend it on faster cores and a disk that survives its host. Neither side gets to normalize that away: each provider sells the stack it sells, and a buyer gets the whole stack or none of it. The size ladder below is designed to show exactly where each choice pays.

Method, in one paragraphtop

Standard pgbench, PostgreSQL 18.4, client on a separate small VM talking over each provider's network, because that is how applications talk to databases. TPC-B (write-heavy: three UPDATEs, an INSERT and a COMMIT per transaction) at 32 connections for 5 minutes per point; select-only reads at 32 connections for 2 minutes; a raw commit-rate test (single INSERT + COMMIT, 64 writers). Database sizes: scale 100 / 1000 / 3000 / 6000, which is 1.5 / 15 / 44 / 88 GB against 16 GB of RAM on one side and 8 GB on the other. One pass per point, no retries, no tuning beyond the same public pgtune formula on both. Full command list at the bottom.

Writestop

Database sizeHetzner tps (latency)ServersCamp tps (latency)Δ tps
1.5 GB (in RAM both)5,680 (5.62 ms)6,724 (4.74 ms)+18%
15 GB (cache edge)5,182 (6.16 ms)5,840 (5.47 ms)+13%
44 GB (disk territory)~5,000* (~6.3 ms)5,631 (5.67 ms)+13%
88 GB (deep disk)4,726 (6.76 ms)5,504 (5.80 ms)+16%

* The 44 GB Hetzner run completed but its final summary was lost with console scrollback; the figure is bracketed by its own 10-second progress lines (4.6-5.2k) and by the 128-client run on the same size (4,997). Disclosed rather than re-run: the machine was already deleted.

TPC-B writes, tps at 32 connections (higher is better) 0 2500 5000 7500 1.5 GB 5680 6724 15 GB 5182 5840 44 GB ~5000 5631 88 GB 4726 5504 Hetzner CCX23 ServersCamp hf-m
Write throughput barely cares about database size on either box: both are CPU-bound before the disks break a sweat. ServersCamp holds a +13-18% lead at every rung, at lower latency.

Three things worth knowing behind these bars:

  • Both boxes hit their CPU ceiling, not their disks. During every write run, both servers sat at 97-100% CPU. TPC-B at these sizes is a contention-and-commit test, and no amount of disk speed lifts it. We verified with 128 clients on the 44 GB point: Hetzner got 4,997 tps (nothing gained, latency x4), ServersCamp 5,335 (+7%, latency x4). More connections added queueing on both sides and nothing else.
  • The latency gap is the network gap. A TPC-B transaction is seven round trips. On Hetzner's out-of-the-box path (public IPs in one DC) that is 7 x 0.81 ms of wire time inside every transaction; on ServersCamp's default private network it is 7 x 0.13 ms. You can configure a private network at Hetzner too; it just does not come configured.
  • Steadiness differs more than the averages. ServersCamp's per-10-second jitter (stddev 1.1-1.7 ms) ran at roughly half of Hetzner's (1.9-2.9 ms), and the Hetzner 88 GB run shows a visible sawtooth (4.3k to 5.0k) where checkpoints bite. Flat lines are what your p95 is made of.

Reads: the cache laddertop

Database sizeHetzner qps (latency)ServersCamp qps (latency)Δ qps
1.5 GB48,261 (0.65 ms)43,514 (0.73 ms)-10%
15 GB31,886 (1.00 ms)30,206 (1.05 ms)-5%
44 GB26,549 (1.20 ms)27,090 (1.18 ms)+2%
88 GB22,544 (1.41 ms)25,303 (1.26 ms)+12%
44 GB, right after an hour of writes21,882 (1.46 ms)24,837 (1.28 ms)+13.5%

Unlike writes, reads scale with database size on both boxes, and the crossover is the story. On a small hot database Hetzner's extra RAM and its read path win: 48k qps is an excellent number. As the database outgrows RAM the order reverses, and by 88 GB the ServersCamp box reads 12% faster despite having half the RAM to cache with: the replicated network disk answers point reads faster than their local NVMe once real disk IO is in the loop.

The last row is the one production people will recognize. We measured the 44 GB read test twice on each box: once on a freshly loaded database and once right after a long write workload had chewed the same tables (bloat, dirty pages, the state your database actually lives in). Hetzner lost 18% to that churn; ServersCamp lost 8% and ended up 13.5% ahead. Benchmarks run on pristine data; Tuesday afternoon does not.

Raw commit rate: the number databases live ontop

 HetznerServersCamp
Commits per second, 64 writers34,80041,878 (+20%)
Latency per commit1.82 ms1.51 ms

This test strips the workload to its skeleton: one INSERT, one COMMIT, 64 clients hammering it. Every commit has to reach durable media before PostgreSQL answers, so this is a direct measurement of the WAL-fsync path: the thing every transactional database queues behind. The ServersCamp disk is a replicated network volume with power-loss-protected write cache, and it out-commits Hetzner's local NVMe by 20% while writing every byte twice across independent nodes. This mirrors what our fio storage benchmark measured a week earlier with parallel fsync: it is a hardware property, not a lucky run.

Bulk load, since you will restore a dump one daytop

pgbench -i (load + index)HetznerServersCamp
15 GB78-90 s50-57 s
44 GB242-244 s149-152 s
88 GB487 s295 s (1.65x faster)

Loading 88 GB with indexes took 8 minutes on ServersCamp and 8 minutes plus most of a coffee on Hetzner. The same ratio will apply to the restore you run at 3 AM some day, which is when you will care about it most.

Throughput per eurotop

Metric, divided by the monthly checkHetzner (EUR 86.49)ServersCamp (EUR 103.22)
Write tps per euro, 88 GB database54.653.3
Write tps per euro, 1.5 GB database65.765.1
Commits/s per euro402406
Read qps per euro, 88 GB database260.7245.1
Read qps per euro, 1.5 GB database558.0421.6

Divide everything by the money and the picture changes: on writes and commits the two boxes deliver almost identical throughput per euro, and on reads Hetzner's smaller check wins the ratio outright. The extra EUR 17 a month does not buy more transactions per euro. What it buys is the shape of those transactions: 15-17% lower latency, half the jitter, no checkpoint sawtooth, a 1.6x faster restore, and the difference between a disk that dies with its host and one that does not. Whether that is worth EUR 17 is exactly the decision this article exists to inform.

What else is inside the checkstop

The tps tables are half of the purchase. The other half is what happens to this database over a year of operating it, and here the two checks buy structurally different things:

  • The disk itself. Hetzner's NVMe is local: if that host dies, the disk and the database die with it, and recovery means restoring backups onto new hardware. The ServersCamp volume is replicated across storage nodes: a dead host restarts the VM elsewhere with the disk intact, mid-transaction durability included.
  • Growing. The Hetzner disk is 160 GB, full stop; the next size means the next instance. The ServersCamp volume resizes online and changes speed class in place while the database keeps running.
  • Backups that leave the building. Snapshots plus encrypted off-cluster backups to another provider in another country, with your key, are one toggle. On the other side you build this yourself.
  • The network you saw in the latency column. The private network that made every transaction 4.7 ms instead of 5.6 exists from the first minute, unconfigured.
  • The perimeter. Warden's live traffic map is free on every ServersCamp resource; this database server spent the whole benchmark watchable.

Verdict: who should buy whichtop

Your situationBuyWhy
Small database that fits in RAM, read-heavy, budget-firstHetzner CCX2348k in-cache qps for EUR 86 is the best line item in this article
Write-heavy anything: OLTP, queues, event streamsServersCamp+13-18% tps at every size, +20% raw commits, lower latency, half the jitter
A database that will outgrow RAM (they all do)ServersCampThe deep-ladder points: +12-16% at 88 GB on both reads and writes, and the gap widens with churn
Anything you cannot afford to lose with the hostServersCampEvery Hetzner number above is conditional on one physical machine staying alive; ours are not

Reproduce ittop

Two VMs per side, PostgreSQL 18 from PGDG on the server (pgtune-formula config printed below), postgresql-client-18 on the client, then this console session. That is the entire methodology:

the whole battery
export PGHOST=<server-ip> PGUSER=bench PGDATABASE=bench PGPASSWORD=...
ping -c 20 $PGHOST | tail -2

pgbench -i -s 100
pgbench -c 32 -j 2 -T 300 -P 10        # writes, 1.5 GB
pgbench -i -s 1000
pgbench -c 32 -j 2 -T 300 -P 10        # writes, 15 GB
pgbench -i -s 3000
pgbench -c 32 -j 2 -T 300 -P 10        # writes, 44 GB
pgbench -S -c 32 -j 2 -T 120 -P 10     # reads, 44 GB (after the writes)
pgbench -i -s 100
pgbench -S -c 32 -j 2 -T 120 -P 10     # reads, 1.5 GB fresh
pgbench -i -s 1000
pgbench -S -c 32 -j 2 -T 120 -P 10     # reads, 15 GB fresh
pgbench -i -s 3000
pgbench -S -c 32 -j 2 -T 120 -P 10     # reads, 44 GB fresh
pgbench -i -s 6000
pgbench -c 32 -j 2 -T 300 -P 10        # writes, 88 GB
pgbench -S -c 32 -j 2 -T 120 -P 10     # reads, 88 GB

echo "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (1, 1, 1, 1, now());" > ins.sql
pgbench -f ins.sql -c 64 -j 2 -T 120 -P 10   # raw commit rate

Server config, same formula both sides (shown for the 8 GB box; the 16 GB box gets proportionally larger memory values):

conf.d/bench.conf
max_connections = 200
shared_buffers = 2GB                  # RAM/4
effective_cache_size = 6GB            # RAM x 3/4
maintenance_work_mem = 512MB
work_mem = 10MB
wal_buffers = 16MB
min_wal_size = 2GB
max_wal_size = 16GB
checkpoint_completion_target = 0.9
random_page_cost = 1.1
effective_io_concurrency = 256

If your numbers on a ServersCamp VM come out below what this page claims, that is a bug: tell us in a ticket.

Disclaimerstop

  • One pass per point, run on 2026-07-21, by one engineer, from a plain console. This is a consumer measurement, not a lab paper: no repeats, no statistics beyond what pgbench prints, and the per-10-second progress lines are our stability evidence.
  • The 44 GB Hetzner write summary was lost with scrollback and is quoted as ~5,000, bracketed by its progress lines and the 128-client run on the same data. Every other number is a full pgbench final block.
  • The machines differ where the providers differ: Hetzner ships 2x the RAM on a 2021 CPU; ServersCamp ships faster 2024 cores and a replicated disk. Prices as configured on 2026-07-21, VAT excluded, screenshots kept. A buyer cannot normalize any of this away, so neither did we.
  • Network paths are each provider's out-of-the-box defaults: public IPs within one DC on Hetzner (private networks are available with extra setup), the default private network on ServersCamp. The latency difference is part of both products as delivered.
  • Both 2-vCPU client VMs ran near 100% CPU on the hottest read points, so the in-RAM read ceilings are partly client-bound, symmetrically: same client shape on both sides.
  • The ServersCamp stand physically ran a 150 GB W4 volume (headroom for the 88 GB point: peak usage was 107 GB); the quoted check prices the 160 GB the workload actually calls for, matching Hetzner's included capacity. W2/W3 classes would be cheaper but their 0.5-1 GB/s throughput caps sit below the 1.4 GB/s bulk-load peaks we measured, so W4 is the right class.
  • PostgreSQL 18.4 out of the PGDG box on both sides, configured by the same public pgtune formula from each machine's own RAM and cores. No per-side tuning of any kind.