Databases

PostgreSQL vs MySQL vs MariaDB: Performance Benchmark (2026)

PostgreSQL, MySQL, and MariaDB handle the same SQL, but their storage engines, query optimizers, and concurrency models produce very different performance profiles. MariaDB forked from MySQL in 2009 and has diverged significantly since. Picking between them based on vendor benchmarks is pointless because every vendor wins their own tests.

Original content from computingforgeeks.com - post 164553

We installed all three on the same Rocky Linux 10 VM (4 cores, 8 GB RAM), loaded identical datasets with sysbench, and ran the same OLTP workloads against each. Same hardware, same test tool, same queries, same data size. The numbers below answer the question that matters: which one is faster for your workload?

Tested March 2026 on Rocky Linux 10.1 (kernel 6.12) with PostgreSQL 17.9, MySQL 8.4.8, MariaDB 10.11.15, sysbench 1.0.20

Quick Decision Table

If you already know your use case:

Use CaseBest PickWhy
Mixed read-write OLTP (web apps, SaaS)PostgreSQLHighest TPS (2,886), lowest latency (5.5ms), best MVCC
Read-heavy analytics, reportingMariaDBHighest read-only throughput (6,949 TPS)
Bulk INSERT workloads (logging, events)MariaDB3.7x faster inserts than MySQL (8,093 vs 2,206 TPS)
Point lookups (caching, key-value access)PostgreSQL72,664 QPS point SELECTs, 16% faster than MariaDB
Existing MySQL ecosystem (WordPress, etc.)MariaDBDrop-in replacement, faster on every workload we tested
Lowest memory footprintPostgreSQL182 MB idle (vs 486 MB MySQL, 640 MB MariaDB)

Test Environment

All three databases ran on the same VM, one at a time. Only one database was active during each benchmark to eliminate resource contention:

  • VM: Rocky Linux 10.1, 4 vCPUs (KVM), 8 GB RAM, kernel 6.12.0
  • Storage: LVM thin provisioning on SSD
  • Benchmark tool: sysbench 1.0.20, running locally (no network overhead)
  • Dataset: 10 tables, 100,000 rows each (total ~1 million rows per database)
  • Concurrency: 16 threads (matching CPU count x4 for realistic contention)
  • Duration: 60 seconds per benchmark
  • Tuning: Each database was tuned with 2 GB buffer pool/shared_buffers, matching InnoDB settings where applicable

Benchmark Results

All numbers from the same sysbench OLTP workloads (identical queries across all three databases):

WorkloadPostgreSQL 17.9MySQL 8.4.8MariaDB 10.11.15
OLTP Read-Write TPS2,8864362,758
OLTP R/W Avg Latency5.54 ms36.6 ms5.80 ms
OLTP R/W p95 Latency8.74 ms90.78 ms9.56 ms
Read-Only TPS5,6285,4006,949
Read-Only Avg Latency2.84 ms2.96 ms2.30 ms
Point SELECT QPS72,66449,88962,944
Point SELECT Avg Lat0.22 ms0.32 ms0.25 ms
INSERT TPS7,2552,2068,093
INSERT Avg Latency2.20 ms7.25 ms1.98 ms
Idle Memory182 MB486 MB640 MB
Memory Under Load1,129 MB983 MB916 MB

What the Numbers Mean

PostgreSQL dominates mixed OLTP workloads. At 2,886 transactions per second with 5.54ms average latency, PostgreSQL handled 6.6x more mixed read-write transactions than MySQL and 5% more than MariaDB. Its MVCC implementation (multi-version concurrency control) excels when readers and writers compete for the same rows.

MariaDB is the fastest for pure reads and inserts. At 6,949 read-only TPS and 8,093 insert TPS, MariaDB outperformed both competitors on single-operation workloads. MariaDB’s InnoDB fork has diverged significantly from MySQL’s, with optimizations for table scan performance and bulk insert handling.

MySQL 8.4 underperforms significantly. MySQL delivered 436 OLTP TPS versus PostgreSQL’s 2,886 and MariaDB’s 2,758. The 36.6ms average latency (6.6x slower than PostgreSQL) suggests InnoDB’s row-locking and redo log handling in MySQL 8.4 creates more contention under concurrent workloads than either competitor. MySQL’s INSERT throughput (2,206 TPS) was 3.7x slower than MariaDB’s 8,093 TPS on the same InnoDB engine.

PostgreSQL uses the least memory at idle. At 182 MB idle versus MySQL’s 486 MB and MariaDB’s 640 MB, PostgreSQL’s process-per-connection model starts lighter. Under load, all three converge (916 MB to 1,129 MB) because the buffer pool dominates memory usage.

PostgreSQL 17.9

PostgreSQL uses MVCC with a separate process per connection and a sophisticated query planner that gets smarter as tables grow. Version 17 added incremental backup, SQL/JSON improvements, and significant performance gains for bulk loading and vacuuming.

Install and initialize on Rocky Linux 10:

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm
sudo dnf install -y postgresql17-server postgresql17-contrib
sudo /usr/pgsql-17/bin/postgresql-17-setup initdb
sudo systemctl enable --now postgresql-17

Benchmark tuning applied:

ALTER SYSTEM SET shared_buffers = '2GB';
ALTER SYSTEM SET work_mem = '256MB';
ALTER SYSTEM SET effective_cache_size = '4GB';
ALTER SYSTEM SET max_connections = 200;
ALTER SYSTEM SET checkpoint_completion_target = 0.9;
ALTER SYSTEM SET wal_buffers = '64MB';

PostgreSQL also ships with pgbench, its built-in TPC-B benchmark tool. On the same hardware with a 10 million row dataset (scale factor 100), pgbench measured 109,026 read-only TPS and 2,006 mixed read-write TPS.

StrengthLimitation
Best OLTP throughput and latencyHigher memory under load (1,129 MB)
Lowest idle memory (182 MB)Process-per-connection can be costly at very high connection counts
Advanced features: pgvector, JSON, CTEs, window functionsNo multi-source replication without third-party tools
MVCC never blocks readersVACUUM overhead for long-running transactions

MySQL 8.4.8

MySQL 8.4 LTS is Oracle’s long-term support branch. It uses InnoDB as the default storage engine with row-level locking and crash recovery. MySQL 8.4 dropped the Query Cache entirely and focuses on the InnoDB adaptive hash index for read performance.

Install on Rocky Linux 10 (note: the MySQL GPG key expired on Rocky 10, requiring --nosignature during RPM install):

sudo dnf install -y https://dev.mysql.com/get/mysql84-community-release-el10-1.noarch.rpm
sudo dnf download mysql-community-common mysql-community-client-plugins mysql-community-libs mysql-community-client mysql-community-icu-data-files mysql-community-server --destdir=/tmp/mysql-rpms
sudo rpm -ivh --nosignature /tmp/mysql-rpms/*.rpm
sudo systemctl enable --now mysqld

Benchmark tuning:

SET GLOBAL innodb_buffer_pool_size = 2147483648;
SET GLOBAL max_connections = 200;
SET GLOBAL innodb_flush_log_at_trx_commit = 1;
StrengthLimitation
Widest ecosystem (WordPress, Drupal, most PHP apps)Slowest on every workload we tested
Oracle commercial support available36.6ms OLTP latency (6.6x slower than PostgreSQL)
MySQL Shell, InnoDB Cluster for HAINSERT throughput 3.7x slower than MariaDB
Group Replication built inGPG key issues on newer Linux distros (Rocky 10)

MariaDB 10.11.15

MariaDB is a community fork of MySQL with significant divergence since the split. MariaDB 10.11 is the current Long Term Support release (maintained until February 2028). Its InnoDB implementation has diverged from MySQL’s, with different buffer pool management, a pluggable encryption architecture, and the Aria storage engine for internal temporary tables.

Install on Rocky Linux 10 (available from the base repos):

sudo dnf install -y mariadb-server
sudo systemctl enable --now mariadb

Benchmark tuning (/etc/my.cnf.d/bench.cnf):

[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 256M
max_connections = 200
innodb_flush_log_at_trx_commit = 1

MariaDB required no GPG workarounds and installed cleanly from the base Rocky Linux repos. For detailed installation on both RHEL and Debian families, see our MariaDB installation guide.

StrengthLimitation
Fastest reads (6,949 TPS) and inserts (8,093 TPS)Higher idle memory than PostgreSQL (640 MB)
Drop-in MySQL replacement for most appsJSON support less mature than PostgreSQL
Ships in default RHEL/Rocky/Debian reposDiverging from MySQL compatibility on newer features
Galera Cluster for synchronous multi-master replicationNo native logical replication (uses Galera or standard replication)

Workload Deep Dive

OLTP Read-Write (Mixed Transactions)

This workload combines SELECT, UPDATE, INSERT, and DELETE operations in a single transaction, simulating a typical web application workload (shopping carts, user management, content updates).

sysbench /usr/share/sysbench/oltp_read_write.lua \
  --tables=10 --table-size=100000 --threads=16 --time=60 run

PostgreSQL (2,886 TPS) and MariaDB (2,758 TPS) were nearly identical, both delivering 6x the throughput of MySQL (436 TPS). The gap is explained by how each database handles concurrent transactions: PostgreSQL’s MVCC allows readers to proceed without blocking writers, while MySQL 8.4’s InnoDB creates more lock contention in mixed workloads.

Point SELECT (Key-Value Lookups)

This test measures single-row lookups by primary key, the most common query pattern in caching layers and API backends.

sysbench /usr/share/sysbench/select_random_points.lua \
  --tables=10 --table-size=100000 --threads=16 --time=60 run

PostgreSQL delivered 72,664 QPS with 0.22ms average latency, 16% faster than MariaDB (62,944 QPS) and 46% faster than MySQL (49,889 QPS). For key-value access patterns, PostgreSQL’s index-only scans and buffer manager are highly optimized.

INSERT Throughput

Pure INSERT workloads stress the write-ahead log (WAL/redo log), buffer pool, and index maintenance:

sysbench /usr/share/sysbench/oltp_insert.lua \
  --tables=10 --table-size=100000 --threads=16 --time=60 run

MariaDB (8,093 TPS) edged out PostgreSQL (7,255 TPS) and crushed MySQL (2,206 TPS). MySQL’s INSERT performance was 3.7x slower than MariaDB on the same InnoDB engine, which points to differences in how the two forks handle redo log flushing and batch insert optimizations.

Feature Comparison

Performance is one dimension. The right database also depends on features, ecosystem, and operational characteristics:

FeaturePostgreSQL 17MySQL 8.4MariaDB 10.11
Default storage engineHeap (with MVCC)InnoDBInnoDB (forked)
ACID complianceFullFull (InnoDB)Full (InnoDB)
JSON supportNative JSONB with indexingJSON typeJSON type (LONGBLOB alias)
Full-text searchBuilt in (tsvector)InnoDB FTSInnoDB FTS + Mroonga
ReplicationStreaming + LogicalBinlog + Group ReplicationBinlog + Galera Cluster
Vector searchpgvector extensionNo native supportNo native support
PartitioningDeclarative (native)Range, List, Hash, KeyRange, List, Hash, Key + System versioned
Window functionsFull SQL:2011FullFull
CTEs (WITH queries)Recursive + materializedRecursiveRecursive
Default in RHEL reposNo (PGDG repo)No (Oracle repo)Yes
LicensePostgreSQL (MIT-like)GPL v2GPL v2

Benchmark Methodology

For reproducibility, here are the exact sysbench commands used. The sysbench documentation covers additional workload types and configuration options.

Prepare the test data (identical for MySQL, MariaDB, and PostgreSQL):

# MySQL / MariaDB
sysbench /usr/share/sysbench/oltp_read_write.lua \
  --mysql-host=localhost --mysql-user=bench --mysql-password='password' \
  --mysql-db=sbtest --tables=10 --table-size=100000 prepare

# PostgreSQL
sysbench /usr/share/sysbench/oltp_read_write.lua \
  --pgsql-host=localhost --pgsql-user=bench --pgsql-password='password' \
  --pgsql-db=sbtest --db-driver=pgsql --tables=10 --table-size=100000 prepare

Run the benchmark:

sysbench /usr/share/sysbench/oltp_read_write.lua \
  --mysql-host=localhost --mysql-user=bench --mysql-password='password' \
  --mysql-db=sbtest --tables=10 --table-size=100000 \
  --threads=16 --time=60 --report-interval=10 run

Each database was given a 2 GB buffer pool (shared_buffers for PostgreSQL, innodb_buffer_pool_size for MySQL/MariaDB). Only one database ran at a time. The VM was idle except for the benchmark and the database under test.

When to Choose Each Database

Choose PostgreSQL when you need the best mixed-workload performance, advanced SQL features (CTEs, window functions, JSONB), vector search with pgvector, or when memory efficiency at idle matters (containers, small VMs). PostgreSQL is the fastest growing database in the industry for a reason.

Choose MariaDB when you are running MySQL-compatible applications (WordPress, Joomla, Magento) and want better performance without changing code. MariaDB outperformed MySQL on every single workload in our tests. It ships in the default RHEL/Rocky/Debian repos, making it the path of least resistance for MySQL-compatible deployments.

Choose MySQL when your application specifically requires MySQL (Oracle MySQL certifications, specific MySQL Shell features, or InnoDB Cluster). Be aware that MariaDB is a drop-in replacement that performs better on the same workloads, so the reason to choose MySQL should be ecosystem-specific, not performance-based.

Related Articles

Databases How To Install PostGIS on Debian 11 / Debian 10 Databases Installation of MariaDB 11 on Ubuntu 22.04|20.04|18.04 Databases Install MariaDB 11.4 LTS on Debian 13 / Debian 12 AlmaLinux Deploy Elasticsearch Cluster on Rocky Linux 10 with Ansible

Leave a Comment

Press ESC to close