PostgreSQL QoS Resource Governor

PostgreSQL QoS Resource Governor

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.

Purpose of the Extension

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.

Capabilities

  • Limit CPU usage by binding the backend to N CPU cores on Linux, while keeping parallel workers within that cap.
  • Track and cap concurrent transactions and statements for SELECT, UPDATE, DELETE, and INSERT workloads.
  • Limit work_mem per session.
  • Enforce per-role and per-database limits through ALTER ROLE/DATABASE SET qos.*.
  • Refresh configuration across sessions without reconnects through a shared epoch cache invalidation mechanism.

Requirements

  • PostgreSQL 15 or newer.
  • Build toolchain and server headers when installing from source, with pg_config available.
  • Linux for CPU affinity limiting; on other platforms, only parallel worker limiting is applied.

Installation From Package

Debian 13 Package
# Install
sudo dpkg -i postgresql-<version>-qos_1.0.0-1_debian13_amd64.deb
sudo apt-get install -f
Ubuntu 24.04 Package
# Install
sudo dpkg -i postgresql-<version>-qos_1.0.0-1-ubuntu24_amd64.deb
sudo apt-get install -f
RHEL/AlmaLinux/Centos 10 (PGDG) Package
# Install
sudo rpm -i postgresql<version>-qos-1.0.0-1.el10.x86_64.rpm

Installation From Source

Debian/Ubuntu Packages

Install the development package that matches your PostgreSQL version:

  • postgresql-server-dev-15 for PostgreSQL 15
  • postgresql-server-dev-16 for PostgreSQL 16
  • postgresql-server-dev-17 for PostgreSQL 17
  • postgresql-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
RHEL/AlmaLinux/Centos/Rocky Packages

Install the development package that matches your PostgreSQL version:

  • postgresql15-devel for PostgreSQL 15
  • postgresql16-devel for PostgreSQL 16
  • postgresql17-devel for PostgreSQL 17
  • postgresql18-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
Build and Install
1. Build
make
2. Install
sudo make install
Notes: Ensure the matching PostgreSQL development package is installed so 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

Configure

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;

Configuration: qos.* Settings

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 1GB
  • qos.cpu_core_limit (integer) - maximum CPU core count
  • qos.max_concurrent_tx (integer) - maximum concurrent transactions
  • qos.max_concurrent_select (integer) - maximum concurrent SELECT statements
  • qos.max_concurrent_update (integer) - maximum concurrent UPDATE statements
  • qos.max_concurrent_delete (integer) - maximum concurrent DELETE statements
  • qos.max_concurrent_insert (integer) - maximum concurrent INSERT statements
Examples
-- 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.

How It Works

work_mem Enforcement

Intercepts SET work_mem and rejects values above qos.work_mem_limit.

CPU Limiting
  • On Linux, QoS binds the backend to N CPU cores using CPU affinity.
  • The planner hook keeps Gather and Gather Merge workers inside the configured core budget.
  • On non-Linux platforms, only the planner effect applies.
Concurrency Limits

Executor hooks track active transactions and statements per command type; caps are enforced against configured maxima.

Observability and Logging

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.

Limitations

  • CPU limiting is only available on Linux; other platforms only enforce parallel worker limits via the planner.
  • Requires shared_preload_libraries and a server restart to activate.
  • Official support targets PostgreSQL 15 and newer.

Uninstall

DROP EXTENSION IF EXISTS qos;

Remove from shared_preload_libraries and restart the server.

Development

  • Builds with PGXS using the provided Makefile.
  • Targets PostgreSQL 15 through PostgreSQL 18 server APIs.
  • Includes modular components such as hooks.c, hooks_cache.c, hooks_resource.c, hooks_statement.c, hooks_transaction.c, and qos.c/qos.h.

License

GPL-3.0 license. See the LICENSE file in the repository.

GitHub Repository

Visit our GitHub repository for the latest updates, source code, and to contribute:

View on GitHub

Need Help?

Our PostgreSQL experts are ready to help you with installation, configuration, and optimization of pg_qos.

Contact Us