PlanetScale’s new $5 single-node PostgreSQL tier (PS-5) promises the same observability/maintenance story you get from their Vitess-backed MySQL side. I wanted to see how it feels next to the very boring Postgres instance I already pay for: a Hetzner CPX11 (2 vCPU / 2 GB RAM for €3.85) running in their eu-central region (Nuremberg). This isn’t even LAN vs internet—it’s literally local disk vs a remote region—so the goal is to get a sanity check, not crown a winner.
I pointed the usual pgbench mix at PlanetScale’s x64 PS-5, PS-10, PS-20, PS-40, PS-80, and PS-160 plans. I asked for eu-central-1 to keep everything close to the Hetzner VPS, but PlanetScale split the replicas across eu-central-1 and eu-central-2, so we roll with what they provisioned. Each plan got hit via the direct endpoint and via PgBouncer. The Hetzner box got the same treatment so we can see how much pooling narrows the gap. Everything lives in mhmd-azeez/hetzner_vs_planetscale if you want to re-run or tweak the tests.
Direct connections
First pass: raw connections, no pooling tricks, single region hops only.
TPS (transactions/second)
| concurrency | local | ps5 | ps10 | ps20 | ps40 | ps80 | ps160 |
|---|---|---|---|---|---|---|---|
| 1 | 406.97 | 29.43 | 24.70 | 24.67 | 23.59 | 28.50 | 24.11 |
| 10 | 2,445.69 | 256.03 | 261.99 | 278.28 | 257.12 | 268.42 | 272.31 |
| 50 | 2,487.99 | - | - | - | - | - | 1,245.58 |
Latency (ms)
| concurrency | local | ps5 | ps10 | ps20 | ps40 | ps80 | ps160 |
|---|---|---|---|---|---|---|---|
| 1 | 2.46 | 33.98 | 40.49 | 40.53 | 42.38 | 35.09 | 41.48 |
| 10 | 4.09 | 39.06 | 38.17 | 35.93 | 38.89 | 37.26 | 36.72 |
| 50 | 20.10 | - | - | - | - | - | 40.14 |
PgBouncer
Next pass: slap PgBouncer in front of everything and see how far we can push concurrency before the network becomes the wall.
TPS
| concurrency | local | ps5 | ps10 | ps20 | ps40 | ps80 | ps160 |
|---|---|---|---|---|---|---|---|
| 1 | 275.29 | 23.50 | 26.13 | 22.61 | 24.53 | 27.17 | 21.72 |
| 10 | 1,645.86 | 256.16 | 264.75 | 253.11 | 259.09 | 260.90 | 265.06 |
| 50 | 1,676.38 | 397.54 | 458.44 | 479.10 | 477.70 | 1,204.07 | 1,207.27 |
| 100 | 1,719.79 | 396.29 | 464.93 | 485.40 | 473.24 | 1,200.39 | 2,137.35 |
| 200 | 1,712.10 | 397.50 | 460.53 | 481.65 | 474.73 | 1,196.91 | 2,165.73 |
| 400 | 1,693.84 | 398.24 | 465.79 | 477.23 | 471.96 | - | - |
Latency (ms)
| concurrency | local | ps5 | ps10 | ps20 | ps40 | ps80 | ps160 |
|---|---|---|---|---|---|---|---|
| 1 | 3.63 | 42.56 | 38.27 | 44.22 | 40.77 | 36.81 | 46.05 |
| 10 | 6.08 | 39.04 | 37.77 | 39.51 | 38.60 | 38.33 | 37.73 |
| 50 | 29.83 | 125.77 | 109.07 | 104.36 | 104.67 | 41.53 | 41.42 |
| 100 | 58.15 | 252.34 | 215.09 | 206.02 | 211.31 | 83.31 | 46.79 |
| 200 | 116.82 | 503.15 | 434.28 | 415.24 | 421.29 | 167.10 | 92.35 |
| 400 | 236.15 | 1,004.42 | 858.76 | 838.18 | 847.53 | - | - |
Takeaways
- Latency is the tax: even PS-160 stays ~10× slower on single-connection round trips because physics wins.
- Pooling earns its keep: once PgBouncer gets involved, PS-160 eventually outruns the local box at extreme concurrency simply because it can hold more connections open at once.
- Small plans hit ceilings fast: PS-5/10/20 tap out before the 50-connection mark, so plan accordingly if you expect chatty workloads.
- You still pay for the managed bits: backups, maintenance, branches, and observability are the real pitch for PlanetScale; Hetzner only wins if you’re happy being your own DBA.