Hello everyone!
I am trying to optimize PostgreSQL for insert performance and I think I've reaced the limit of my knowledge and experience.
Here's what I'm trying to do:
I have a synthetic java application which simulates a real production application. This application is using postgresql jdbc driver in combination with jooq framework.
This app inserts records into my table called "outbox".

So far, I was able to reach RPS of 35k inserts per second. But I can't tune it any better, neither I understand where is the bottleneck.

What I am using for PostgreSQL:
48 vCPU,
64 GB RAB,
SSD
Version: 17

Number of postgres instances: 1

Synthetic app settings per app (run on different VMs than postgres):
connection pool size: 200
insert threads: 50
transactional inserts: yes

Number of instances of synthetic apps: 5

Postgresql.conf options which differ from defaults:
```
max_connections = 1200 # change requires restart
ssl = on
shared_buffers = 8GB                    # min 128kB
huge_pages = on #on, off, or try
maintenance_work_mem = 4GB            # min 64kB
dynamic_shared_memory_type = posix      # the default is usually the first option
effective_io_concurrency = 200           # 1-1000; 0 disables prefetching
max_worker_processes = 48               # (change requires restart)
max_parallel_workers_per_gather = 8    # limited by max_parallel_workers
max_parallel_maintenance_workers = 8   # limited by max_parallel_workers
max_parallel_workers = 48               # number of max_worker_processes that
wal_level = logical                    # minimal, replica, or logical
wal_buffers = 256MB                       # min 32kB, -1 sets based on shared_buffers checkpoint_completion_target = 0.9     # checkpoint target duration, 0.0 - 1.0
max_wal_size = 32GB
min_wal_size = 4GB


shared_preload_libraries = 'pg_stat_statements,decoderbufs' # (change requires restart)
wal_compression = on
autovacuum=off
#throuth put
commit_delay=10000 # 10ms
commit_siblings = 50

full_page_writes=off
fsync=off

random_page_cost = 1.1
effective_cache_size = 20GB
```

DDL of my table:
```
CREATE UNLOGGED TABLE ${database.defaultSchemaName}.outbox (
    queue_name varchar(255) NOT NULL,
    payload bytea NOT null
)
```

What I observe:
User CPU usage: ~15-20%
Idle CPU: ~80-90%
IO wait: ~0-0.5%

pg_locks is around 400-500 out of 1000 connections at all times for this table.

So I don't see that PostgreSQL is bound to hardware since CPU is not used at full, IO is also not the problem, RAM also seems to be fine. I tried scaling synthetic applications but it doesn't give any RPS boost. So I'm stuck here. Have I reached PostgreSQL performance cap? Or do I have a bottleneck somewhere else? I don't have any ideas anymore what can I try, I would appreciate any help



Reply via email to