Open Source Project: github.com/appstonia/pg_qos
pg_qos is a PostgreSQL extension that brings Quality of Service (QoS) style resource governance to your databases.
It improves overall stability and predictability by capping resource usage per role or per database, reducing cross-workload interference without application changes.
The goal of pg_qos is to isolate workloads in clusters where multiple databases share the same PostgreSQL instance, especially in vertical deployment setups.
Instead of splitting databases into separate instances just to protect resources, the extension lets you enforce boundaries inside the same cluster and keep operations simpler.
work_mem per session.ALTER ROLE/DATABASE SET qos.*.PostgreSQL 15 or newer.pg_config available.# Install
sudo dpkg -i postgresql-<version>-qos_1.0.0-1_debian13_amd64.deb
sudo apt-get install -f
# Install
sudo dpkg -i postgresql-<version>-qos_1.0.0-1-ubuntu24_amd64.deb
sudo apt-get install -f
# Install
sudo rpm -i postgresql<version>-qos-1.0.0-1.el10.x86_64.rpm
Install the development package that matches your PostgreSQL version:
postgresql-server-dev-15 for PostgreSQL 15postgresql-server-dev-16 for PostgreSQL 16postgresql-server-dev-17 for PostgreSQL 17postgresql-server-dev-18 for PostgreSQL 18# Example (Ubuntu/Debian)
sudo apt update
# Choose the version you run (15/16/17/18)
sudo apt install postgresql-server-dev-18 build-essential
Install the development package that matches your PostgreSQL version:
postgresql15-devel for PostgreSQL 15postgresql16-devel for PostgreSQL 16postgresql17-devel for PostgreSQL 17postgresql18-devel for PostgreSQL 18# Example (RHEL/AlmaLinux/Centos/Rocky)
# Setup pgdg repository
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# Choose the version you run (15/16/17/18)
sudo dnf install -y gcc make autoconf libtool automake postgresql18-devel redhat-rpm-config
make
sudo make install
pg_config points to the intended server version. If multiple versions are installed, set PG_CONFIG explicitly.
# Debian/Ubuntu
make clean
make PG_CONFIG=/usr/lib/postgresql/<version>/bin/pg_config
sudo make install PG_CONFIG=/usr/lib/postgresql/<version>/bin/pg_config
# RHEL/AlmaLinux/Centos/Rocky
make clean
make PG_CONFIG=/usr/pgsql-<version>/bin/pg_config
sudo make install PG_CONFIG=/usr/pgsql-<version>/bin/pg_config
Server restart required because pg_qos uses hooks and shared memory.
Edit postgresql.conf:
shared_preload_libraries = 'qos'
Restart PostgreSQL, then enable the extension in each database where QoS should be active:
CREATE EXTENSION qos;
Configure limits per role and/or per database using standard GUC storage in pg_db_role_setting:
qos.work_mem_limit (bytes) - max effective work_mem per session, for example 64MB or 1GBqos.cpu_core_limit (integer) - maximum CPU core countqos.max_concurrent_tx (integer) - maximum concurrent transactionsqos.max_concurrent_select (integer) - maximum concurrent SELECT statementsqos.max_concurrent_update (integer) - maximum concurrent UPDATE statementsqos.max_concurrent_delete (integer) - maximum concurrent DELETE statementsqos.max_concurrent_insert (integer) - maximum concurrent INSERT statements-- Per-role limits
ALTER ROLE app_user SET qos.work_mem_limit = '32MB';
ALTER ROLE app_user SET qos.cpu_core_limit = '2';
ALTER ROLE app_user SET qos.max_concurrent_select = '100';
-- Per-database limits (for all roles)
ALTER DATABASE appdb SET qos.max_concurrent_tx = '200';
-- Per-role limits for a specific database
ALTER ROLE app_user IN DATABASE appdb SET qos.work_mem_limit = '4MB';
ALTER ROLE app_user IN DATABASE appdb SET qos.max_concurrent_update = '10';
Effective limits are the most restrictive combination of role-level and database-level settings.
Intercepts SET work_mem and rejects values above qos.work_mem_limit.
Gather and Gather Merge workers inside the configured core budget.Executor hooks track active transactions and statements per command type; caps are enforced against configured maxima.
Increase verbosity temporarily to trace QoS activity:
SET client_min_messages = 'debug1';
You'll see messages when cache is refreshed, CPU workers are adjusted, or limits are enforced.
shared_preload_libraries and a server restart to activate.DROP EXTENSION IF EXISTS qos;
Remove from shared_preload_libraries and restart the server.
Makefile.hooks.c, hooks_cache.c, hooks_resource.c, hooks_statement.c, hooks_transaction.c, and qos.c/qos.h.GPL-3.0 license. See the LICENSE file in the repository.
Visit our GitHub repository for the latest updates, source code, and to contribute: