Benchmarks for Python PostgreSQL client drivers, measuring throughput and latency across a range of query types and concurrency levels.
| Benchmark name | Library | Mode |
|---|---|---|
python-asyncpg |
asyncpg | async |
python-aiopg |
aiopg | async (dict rows) |
python-aiopg-tuples |
aiopg | async (tuple rows) |
python-psycopg3 |
psycopg v3 | sync |
python-psycopg3-async |
psycopg v3 | async |
python-psycopg2 |
psycopg2 | sync (thread pool) |
Seven benchmark queries cover different driver workloads:
| File | Description |
|---|---|
1-pg_type.json |
Read from pg_type system catalog |
2-generate_series.json |
Server-side row generation |
3-large_object.json |
Fetch a large binary object |
4-arrays.json |
Array column decoding |
5-copyfrom.json |
Bulk-load via COPY FROM STDIN |
6-batch.json |
Batch INSERT |
7-oneplusone.json |
Minimal round-trip (SELECT 1+1) |
Requires Python 3.11+ and uv.
make # runs uv syncOr directly:
uv sync./pgbench [OPTIONS] [benchmark ...]With no benchmark arguments all six drivers are run. Pass one or more names to run a subset:
./pgbench python-asyncpg python-psycopg3-asyncKey options:
| Flag | Default | Description |
|---|---|---|
--concurrency-levels |
10 |
Comma-separated list of concurrency values |
--duration |
30 |
Seconds per benchmark run |
--warmup-time |
5 |
Warmup seconds before measurement |
--pghost |
(temp cluster) | PostgreSQL host; omit to spin up a temporary cluster |
--pgport |
5432 |
PostgreSQL port |
--pguser |
postgres |
PostgreSQL user |
--save-json / -J |
— | Write results to a JSON file |
--save-html / -H |
— | Write results to an HTML report |
--queryfiles |
(all) | Comma-separated list of query JSON files |
./pgbench --concurrency-levels=1,10,50 --duration=60 \
--save-html=results.html \
python-asyncpg python-psycopg3-asyncpgbench_python is the per-driver runner called by the orchestrator. It can also be invoked directly:
./pgbench_python [OPTIONS] <driver> <queryfile>Drivers: asyncpg, aiopg, aiopg-tuples, psycopg3, psycopg3-async, psycopg2