DATABASE WARS

The same app, a different database, measured with k6. Every number comes from a script in the repository, and a pull request can move it.

Published results

Measured on dedicated cloud machines, each round from freshly loaded data. They hold for the setup named on each card.

PostgreSQLvsMariaDB

Postgres vs MariaDB

2 dedicated vCPUs and 4 GB per database, 5 million orders unless noted. Shown: req/s, middle run.

Reads, up to 800 users

PostgreSQL7,910
MariaDB7,902

Reads, ceiling

PostgreSQL13,324
MariaDB10,772

Writes, ceiling

PostgreSQL4,277
MariaDB4,085

20 million orders, ceiling one run

PostgreSQL9,827
MariaDB10,346
PostgreSQLvsMongoDB

Postgres JSONB vs MongoDB

2 dedicated vCPUs and 4 GB per database, one million orders. Shown: highest req/s held with p95 under 50 ms.

Reads

PostgreSQL4,977
MongoDB8,953

New orders

PostgreSQL5,964
MongoDB3,955

Status updates

PostgreSQL4,962
MongoDB3,967

Shop mix, defaults

PostgreSQLfails at 400
MongoDB4,980+

Shop mix, fastupdate = off

PostgreSQL5,474
MongoDB4,982

Shop mix, fastupdate = off, hosts swapped one run

PostgreSQL6,477
MongoDB4,487

New orders, fastupdate = off one run

PostgreSQL2,970
MongoDB3,966

Big orders (40 items): status updates one run

PostgreSQL1,492
MongoDB4,479

Big orders (40 items): reads one run

PostgreSQL4,988
MongoDB5,980+

Merged PRs

What each merged pull request changed in its short run, base and PR in turns on one GitHub runner. ▲▼ is better, ▲▼ is worse, grey is no clear change. These numbers can't be compared with the published results above.

No merged PRs with numbers yet. The first one lands here when it merges.

Contribute

Think a database was set up badly, or the app uses it wrong? Change it and the pull request measures the difference.

Fork and change

Edit the app or the database settings in one comparison folder.

Open a pull request

The owner approves the run, so outside PRs don't start by themselves.

Short load test

App, k6 and each database on one runner, base, PR, PR, base, about a minute each.

Numbers on the PR

A comment shows req/s and p95 with arrows. Merged PRs appear on this page.

# run it on your machine first (needs Docker, Go and k6) git clone https://github.com/<you>/db-wars && cd db-wars/postgres-vs-mongodb docker compose -f ci/compose.yml up -d --wait postgres cat ci/bench.conf # the seed size, the k6 options and the connection strings

Open to change

  • app/: queries, indexes, schema, connection pool
  • ci/compose.yml: database version and settings

Gets no numbers

  • .github/, k6/, ci/bench.conf, results/: the test stays the same for every PR
  • Settings that return a write before it reaches the disk, such as fsync=off, or data in memory