Tune PostgreSQL

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab Self-Managed

You should tune PostgreSQL when:

  • Other GitLab components are reconfigured or scaled up in a way that affects the database.
  • The performance of your GitLab environment is impaired.
  • GitLab uses an external PostgreSQL service.

Use this information in combination with the required PostgreSQL settings for GitLab.

Plan your database connections

GitLab versions 16.0 and later use two sets of database connections for the main and ci tables. This doubles connection usage, even when the same PostgreSQL database serves both sets of tables.

GitLab uses database connections from multiple components. Proper connection planning prevents database connection exhaustion and performance issues.

Each GitLab component uses database connections based on its configuration. Sidekiq and Puma establish a pool of connections to PostgreSQL at initialization. The number of connections in the pool can increase later if there are connection spikes or temporary increases in demand:

  • Configure database pool headroom with the environment variable DB_POOL_HEADROOM.
  • When you tune PostgreSQL, plan for pool headroom but do not change it. GitLab deployments respond better to higher demand if more capacity is available: deploy more Sidekiq or Puma workers.

Puma

Puma connections = puma['worker_processes'] × (puma['max_threads'] + DB_POOL_HEADROOM)

By default:

  • puma['worker_processes'] is based on CPU core count.
  • puma['max_threads'] is 4.
  • DB_POOL_HEADROOM is 10.

Per-worker calculation: Each Puma worker uses 4 threads + 10 headroom, for a total of 14 connections.

Default calculation, assuming 8 vCPU: 8 workers × 14 connections per worker, for a total of 112 Puma connections.

Sidekiq

Sidekiq connections = Number of Sidekiq processes × (sidekiq['concurrency'] + 1 + DB_POOL_HEADROOM)

By default:

  • The number of Sidekiq processes is 1.
  • sidekiq['concurrency'] is 20.
  • DB_POOL_HEADROOM is 10.

Default calculation: 1 Sidekiq process × (20 concurrency + 1 + 10 headroom), for a total of 31 total Sidekiq connections.

Geo Log Cursor (Geo installations only)

The Geo Log Cursor daemon runs on all GitLab Rails nodes in a secondary site.

Geo log cursor connections = 1 + DB_POOL_HEADROOM

Default calculation: 1 + 10 headroom, for a total of 11 Geo connections.

Total connection requirements

For single node installations:

Total connections = 2 × (Puma + Sidekiq + Geo)

For multi-node installations, multiply by the number of nodes running each component:

Total connections = 2 × ((Puma × Rails nodes) + (Sidekiq × Sidekiq nodes) + (Geo × secondary Rails nodes))

Multiplying by 2 accounts for the dual database connections in GitLab 16.0 and later.

Examples

Single node installation

This example is based on the GitLab reference architecture for 20 RPS (requests per second) or 1000 users:

ComponentNodesConfigurationConnections per componentComponent total, dual database
Puma18 workers, 4 threads each14 per worker224
Sidekiq11 process, 20 concurrency31 per process62
Total286

Multi-node installation

This example is based on the GitLab reference architecture for 40 RPS or 2000 users:

ComponentNodesConfigurationConnections per componentComponent total, dual database
Puma28 workers per node, 4 threads each14 per worker448
Sidekiq14 processes, 20 concurrency each31 per process248
Total696