Running PostgreSQL natively vs into containers

A benchmark against a stress test

The results in a nutshell:

MachineRuntimeDurationDuration ratio wrt MachineDuration per recordDuration per record ratio wrt Machine
M4 Maxnative137s10.21ms1
M4 Maxcontainer217s1,58390.34ms1,619
Debian boxnative611s10.95ms1
Debian boxcontainer974s1,59411.51ms1,5894

On a M4 Max

System report details

  • Model Name: MacBook Pro
  • Model Identifier: Mac16,5
  • Chip: Apple M4 Max
  • Total Number of Cores: 16 (12 performance and 4 efficiency)
  • Memory: 128 GB
  • System Firmware Version: 13822.61.10
  • OS Loader Version: 13822.61.10

Running into a container

pgbench (18.1)
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
maximum number of tries: 1
duration: 5 s
number of transactions actually processed: 3850
number of failed transactions: 0 (0.000%)
latency average = 1.298 ms
initial connection time = 5.704 ms
tps = 770.645801 (without initial connection time)

Running natively

pgbench (18.1)
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
maximum number of tries: 1
duration: 5 s
number of transactions actually processed: 7858
number of failed transactions: 0 (0.000%)
latency average = 0.636 ms
initial connection time = 2.290 ms
tps = 1572.119114 (without initial connection time)

Installation steps

For the sake of clarity, here the steps for compiling PostgreSQL 18.1 from sources according to the official page. The configuration command looks a bit complicated (many thanks, Stack Overflow):

LDFLAGS="${LDFLAGS} -L`brew --prefix icu4c`/lib" CPPFLAGS="${CPPFLAGS} -I`brew --prefix icu4c`/include" PKG_CONFIG_PATH=`brew --prefix icu4c`/lib/pkgconfig:"$PKG_CONFIG_PATH" ./configure

Then the make as usual:

make && sudo make install

For the sources in the contrib subdirectory:

cd contrib && make && sudo make install

required to have some useful extensions.

The previous command install artifacts into /usr/local/pgsql, so add /usr/local/pgsql/bin and /usr/local/pgsql/lib to your $PATH in order to reach them, respectively. Then initialize a new pg-data folder somewhere under your $HOME:

/usr/local/pgsql/bin/initdb -D $HOME/pg-data

Before starting the server by:

/usr/local/pgsql/bin/pg_ctl -D $HOME/pg-data -l logfile start

remember to adjust your $HOME/pg-data/postgresql.conf by changing listen_addresses = '*' and also add to $HOME/pg-data/pg_hba.conf the following line:

host    all             all             all                     trust

to let the serve accept incoming connections from your network.

On a Debian Linux box

System report details

Hardware Information:

  • Hardware Model: Lenovo ThinkPad T14s Gen 1
  • Memory: 16.0 GiB
  • Processor: Intel® Core™ i7-10510U × 8
  • Graphics: Intel® UHD Graphics (CML GT2)
  • Disk Capacity: 1.0 TB

Software Information:

  • Firmware Version: N2YET43W (1.32 )
  • OS Name: Debian GNU/Linux 13 (trixie)
  • OS Build: (null)
  • OS Type: 64-bit
  • GNOME Version: 48
  • Windowing System: Wayland
  • Kernel Version: Linux 6.12.63+deb13-amd64

Running into a container

Running natively

Installation steps

The steps here are more straightforward and mimic the ones described in the corresponding section for the M4 Max architecture.