Currently viewing the human version
Switch to AI version

What Pgpool-II Actually Does (And Why It'll Probably Break)

PostgreSQL Connection Pooling Architecture

Pgpool-II is a connection pooler that sits between your application and PostgreSQL databases. Think of it as a bouncer at a club - it manages who gets in, where they go, and kicks people out when they overstay their welcome.

The Reality of Process-Based Architecture

Pgpool-II uses a process-based model like PostgreSQL itself, spawning up to 32 child processes by default. Each process uses about 2MB of RAM baseline, so you're looking at 64MB just for the proxy before it does anything useful. When you hit max connections, it just starts dropping new ones - learned this the hard way during a traffic spike that took down our staging environment for 2 hours.

The connection pooling architecture differs significantly from thread-based poolers like PgBouncer. Each Pgpool process maintains its own pool of backend connections, which can lead to suboptimal resource utilization compared to shared connection pools.

The parent process forks children to handle connections, and here's where it gets fun: if a child process crashes (which happens more often than you'd like with SSL issues), the parent kills all other children and respawns them. So one bad connection can temporarily murder your entire connection pool.

Connection Pooling That Actually Pools

Unlike application-level pooling where your framework pretends to be smart, Pgpool-II maintains persistent connections to your PostgreSQL servers. This saves you from the 50ms handshake overhead on every new connection. In practice, we saw connection establishment time drop from 45ms to under 1ms for pooled connections.

But here's the catch: connections are per-process, not shared. If you have 32 Pgpool processes and 4 backend servers, you could theoretically open 128 connections to your database cluster. Set max_pool = 4 and you're looking at 512 potential connections. Do the math before your DBA murders you.

Query Routing (When It Works)

Pgpool-II can automatically detect SELECT statements and route them to read replicas while sending writes to the primary. This sounds great until you realize it's session-based routing, not statement-based.

The load balancing mechanism analyzes SQL queries to determine routing, but load balancing conditions can be more complex than expected. Enterprise load balancing techniques show that pgpool's query-aware routing has limitations compared to simpler approaches.

If your web app holds connections open (like every single web framework does), your "load balancing" becomes "randomly pick a server and hammer it for the next 10 minutes." We've seen scenarios where one replica gets 80% of the read traffic while others sit idle because of long-lived connections. Load balancing comparisons often highlight this session affinity issue.

Failover: The Part That Actually Matters

When your primary database shits the bed, Pgpool-II can automatically fail over to a replica. The good news: it usually works. The bad news: every client connection gets dropped during failover, so your application better handle ECONNRESET gracefully.

Failover detection uses SELECT pg_is_in_recovery() to identify the primary. With default health check intervals, you're looking at 10-30 seconds of downtime while Pgpool figures out what happened. Set health checks too aggressive and you'll get false positives from network hiccups. PostgreSQL high availability strategies provide broader context for when automatic failover makes sense.

The watchdog feature coordinates multiple Pgpool instances for failover coordination, but production experiences show that watchdog can be complex to configure properly without split-brain scenarios.

SSL Performance Hell

SSL overhead with OpenSSL 3.0.2 will destroy your CPU. We saw 300% CPU utilization on a 4-core box just handling SSL handshakes. Version 4.6.3 finally addresses some of this, but you'll still want to monitor CPU usage carefully if you're terminating SSL at Pgpool.

The SSL performance issues are well-documented in the GitHub repository, where users report 75% CPU utilization with SSL enabled. This is tied to broader OpenSSL 3.0 performance issues that affect many applications.

Pro tip: terminate SSL at a load balancer in front of Pgpool if you can. Your CPU will thank you.

The Real Talk: Pgpool-II vs Everything Else

Feature

Pgpool-II

PgBouncer

HAProxy

Patroni

AWS RDS Proxy

Connection Pooling

✅ Works but complex

✅ Just fucking works

❌ Not its job

❌ Doesn't pool

✅ Works if you pay

Load Balancing

✅ Query-aware (kinda)

❌ Manual routing only

✅ Dumb but reliable

❌ Not included

✅ Basic round-robin

Automatic Failover

✅ Usually works

❌ External solution needed

✅ If you configure it right

✅ Actually excellent

✅ Managed for you

Read/Write Splitting

✅ Session-based hell

❌ Application handles it

✅ Rule-based routing

❌ Application problem

✅ Works automatically

Query Caching

✅ Built-in memcached

❌ Not its problem

❌ Not its problem

❌ Not included

❌ Use ElastiCache

Resource Usage

🟡 64MB+ baseline

✅ ~10MB total

✅ ~5MB footprint

🟡 Python overhead

N/A

Configuration Hell

🔴 Weekend project

✅ 10 lines of config

🟡 Decent docs

🔴 YAML nightmare

✅ Click buttons

Production Stability

🟡 Works when tuned

✅ Rock solid

✅ Bulletproof

🟡 Complex but good

✅ Someone else's problem

Cost

✅ Free (your time isn't)

✅ Actually free

✅ Free + your sanity

✅ Free + etcd cluster

💰 $$$$ per connection

Installation and Configuration (AKA Your Weekend Is Gone)

Installation: The Easy Part

Getting Pgpool-II installed is the only part that actually works as advertised. Most package managers have it, and the official installation documentation covers both package and source installation methods:

## Ubuntu/Debian (works)
apt-get install pgpool2

## RHEL/CentOS (also works)
yum install pgpool-II

## Or compile from source if you hate yourself
wget https://www.pgpool.net/download.php?f=pgpool-II-4.6.3.tar.gz
./configure --prefix=/usr/local/pgpool
make && make install  # Takes 20 minutes, fails if missing dev libs

If you're compiling from source and it fails with pg_config not found, you need libpq-dev and postgresql-server-dev-XX. This error message is the first of many that will make you question your life choices. The MyDBOps installation guide covers these dependency issues in detail.

Configuration Files: Welcome to Hell

Pgpool-II uses two main config files that live in /etc/pgpool-II/ (or wherever your package manager decided to put them):

  • pgpool.conf - The 200+ parameter nightmare that controls everything
  • pcp.conf - Authentication for administrative commands (you'll forget about this until nothing works)

The basic configuration examples from the official docs are a good starting point, but sample configuration files on GitHub show real-world scenarios. Here's a basic config that looks simple but will break in 17 different ways:

## This will fail if DNS hiccups
listen_addresses = '*'
port = 5432

## These numbers are lies until you tune them for your workload
connection_cache = on
max_pool = 4
num_init_children = 32

## Load balancing that works until it doesn't
load_balance_mode = on
master_slave_mode = on

## Backend configuration that assumes everything is perfect
backend_hostname0 = 'db-primary.internal'
backend_port0 = 5432
backend_weight0 = 1

backend_hostname1 = 'db-replica1.internal'
backend_port1 = 5432
backend_weight1 = 1

Authentication: The Part That Always Breaks

Authentication is where Pgpool-II goes from "challenging" to "I'm updating my resume." You need to sync three different auth configurations:

  1. PostgreSQL's pg_hba.conf (controls database access)
  2. Pgpool's pool_hba.conf (mirrors pg_hba.conf, sort of)
  3. The pool_passwd file (password hashes that never match)

The authentication configuration documentation explains the theory, but Stack Overflow authentication issues show the reality of debugging auth problems.

The password file is the real killer. Use the pg_md5 utility or spend hours debugging why connections fail with unhelpful error messages:

## Generate password hash (this command will save your sanity)
pg_md5 -m -u username password

If you get authentication failed for user errors, it's always the password hashes. Every. Single. Time.

SSL Configuration: CPU Death Trap

SSL between clients and Pgpool works fine. SSL between Pgpool and PostgreSQL backends will murder your CPU. We measured 300% CPU utilization on OpenSSL 3.0.2 handling just 50 concurrent connections.

The SSL configuration guide shows proper setup, while TLS connection tutorials provide PostgreSQL SSL context. PostgreSQL security hardening covers the broader security implications.

Version 4.6.3 helps, but if you're stuck on older versions, terminate SSL at HAProxy in front of Pgpool:

## In pgpool.conf - this will peg your CPU
ssl = on
ssl_cert = '/etc/ssl/certs/pgpool.crt'
ssl_key = '/etc/ssl/private/pgpool.key'

## Better: terminate SSL at load balancer, use plaintext to Pgpool

Watchdog Clustering: Split-Brain Guaranteed

The Watchdog feature lets multiple Pgpool instances coordinate for high availability. In theory. In practice, you'll get split-brain scenarios when network connectivity hiccups. The watchdog setup utility helps with initial configuration, and Google Cloud HA architecture guides show enterprise deployment patterns.

## This config assumes perfect network connectivity (spoiler: it's not)
use_watchdog = on
watchdog_hostname = 'pgpool1.internal'
wd_lifecheck_method = 'heartbeat'

## When this fails, you'll have two Pgpool instances fighting over the VIP

Network partitions will cause both Pgpool instances to think they're primary. Your monitoring will show two active VIPs and you'll wonder why half your traffic is disappearing.

The Gotchas That Aren't in the Docs

Health Check Tuning

Default health check intervals (10 seconds) are too conservative for production. Set health_check_period = 5 but prepare for false positives during network congestion.

Connection Limits Math

With 32 child processes, max_pool = 4, and 3 backend servers, you're looking at potentially 384 connections to your database cluster. Your DBAs will not be happy.

Failover Timing

Failover detection can take 30+ seconds with default settings. Applications need to handle connection drops gracefully or users will see errors during database failover.

Log File Growth

Enable query logging for debugging but remember to rotate logs. We filled a 20GB partition in 6 hours during a connection storm.

Production Reality Check

Plan 2-3 days for initial setup and another week for production tuning. The official documentation shows perfect configs that work in tutorials but break under real load.

Enterprise deployments often involve extensive cluster configuration and monitoring setup. The PCP command documentation becomes essential for production operations, though the syntax is cryptic.

For production monitoring, Debian security advisories track CVEs you'll need to patch. Consider Docker deployment patterns for development, but test thoroughly before production use.

Keep your old PgBouncer config handy - you might need to fall back to it while debugging Pgpool at 3am on a Saturday.

Frequently Asked Questions (AKA Common Pain Points)

Q

Why does `configure` fail with "pg_config not found"?

A

Because PostgreSQL splits its packages and doesn't tell you. You need the development libraries that your distro probably doesn't install by default:

## Ubuntu/Debian
apt-get install libpq-dev postgresql-server-dev-XX

## RHEL/CentOS
yum install postgresql-devel

Replace XX with your PostgreSQL version. This will save you 30 minutes of Googling the same error message everyone else hits.

Q

Can I mix PostgreSQL versions in a Pgpool cluster?

A

No, and the error messages won't help you figure out why things are breaking. All servers must be the same major version (e.g., all 15.x). Mixing 14.x and 15.x will cause weird protocol errors that look like network issues.

Q

Why does authentication always fail?

A

Because Pgpool-II authentication is a special kind of hell. You need to sync three different auth configs and they all use slightly different formats. When you get authentication failed for user, it's usually the pool_passwd file.

Use the pg_md5 utility to generate password hashes:

pg_md5 -m -u myuser mypassword

Don't try to manually create MD5 hashes. It won't work and you'll waste hours debugging why.

Q

Why aren't my connections load balanced evenly?

A

Because load balancing in Pgpool-II is session-based, not query-based. If your app holds connections open (like every modern web framework), your "load balancing" becomes "randomly stick to one server for 10 minutes."

This is by design, not a bug. Long-lived connections will hammer one replica while others sit idle. If you need statement-level balancing, use application-level routing or HAProxy with custom rules.

Q

Why does failover take forever?

A

Default health check settings are conservative to avoid false positives. You're probably seeing 10-30 seconds of downtime while Pgpool figures out your primary is dead.

Tune health_check_period and health_check_timeout but be prepared for false positives during network hiccups:

health_check_period = 5        # Check every 5 seconds
health_check_timeout = 3       # 3 second timeout
health_check_max_retries = 2   # Retry twice before giving up
Q

Why do I get "connection not available" errors?

A

You hit the connection limit. With default settings (32 child processes, max_pool = 4), you can handle 128 client connections max. Each process maintains its own connection pool, so math gets weird quickly.

Either increase num_init_children or tune max_pool based on your database capacity. Remember: 32 processes × 4 pools × 3 backends = 384 database connections.

Q

Why is my CPU usage at 300%?

A

SSL termination at Pgpool-II will murder your CPU, especially with OpenSSL 3.0.2. We've seen 4-core boxes max out handling 50 SSL connections.

Either upgrade to Pgpool-II 4.6.3+ or terminate SSL at a load balancer:

## HAProxy in front of Pgpool, SSL to plain HTTP
frontend ssl_frontend
    bind *:5432 ssl crt /etc/ssl/certs/postgres.pem
    default_backend pgpool_plain

backend pgpool_plain
    server pgpool1 127.0.0.1:5433 check
Q

How do I fix "relation does not exist" errors?

A

This happens when different connections end up in different database contexts. Pgpool-II doesn't maintain session state across pooled connections, so if your app relies on session-specific settings, it'll break randomly.

Either:

  1. Always specify database names explicitly in connection strings
  2. Set reset_query_list to restore session state on connection reuse
  3. Switch to PgBouncer's transaction-level pooling if this keeps happening
Q

Why does Watchdog keep split-brain?

A

Because network partitions are real and Watchdog assumes perfect connectivity. When Pgpool instances can't talk to each other, they both think they're primary.

Monitor your VIP assignments and have a plan for manual intervention. Network-level split-brain is an infrastructure problem, not a Pgpool problem.

Q

What happens during failover?

A

All client connections to the failed backend get dropped with ECONNRESET. Your application must handle connection failures gracefully and retry.

This is documented behavior, not a bug. Plan for it or users will see errors during database failover.

Q

Is Pgpool-II stable enough for production?

A

Yes, but it requires proper tuning and monitoring. We've run it in production handling thousands of connections, but it took weeks to get the configuration right.

Start with PgBouncer if you just need connection pooling. Move to Pgpool-II only if you specifically need its advanced features and have time to configure it properly.

Q

How many backend servers can Pgpool-II handle?

A

Theoretically many, but practical limits depend on your network and hardware. Most production deployments use 2-5 backends. Beyond that, the complexity and coordination overhead usually aren't worth it.

Q

Should I use Pgpool-II with cloud databases?

A

Maybe. Azure PostgreSQL requires clear text passwords instead of MD5, which breaks default authentication. AWS RDS works better but you're probably better off using RDS Proxy if you're already on AWS.

Cloud databases have their own connection pooling and high availability features. Pgpool-II adds value mainly for read/write splitting and query caching in cloud environments.

Related Tools & Recommendations

tool
Similar content

PgBouncer - PostgreSQL Connection Pooler

Stops PostgreSQL from eating all your RAM and crashing at the worst possible moment

PgBouncer
/tool/pgbouncer/overview
100%
troubleshoot
Similar content

PostgreSQL Connection Pool Exhausted - Here's the Fix

Database looks fine but users getting timeout errors? Your app's connection pool is fucked.

PostgreSQL
/troubleshoot/postgresql-connection-pool-exhaustion/connection-pool-exhaustion-fixes
51%
compare
Recommended

PostgreSQL vs MySQL vs MariaDB - Performance Analysis 2025

Which Database Will Actually Survive Your Production Load?

PostgreSQL
/compare/postgresql/mysql/mariadb/performance-analysis-2025
46%
compare
Recommended

PostgreSQL vs MySQL vs MongoDB vs Cassandra - Which Database Will Ruin Your Weekend Less?

Skip the bullshit. Here's what breaks in production.

PostgreSQL
/compare/postgresql/mysql/mongodb/cassandra/comprehensive-database-comparison
46%
howto
Recommended

How I Migrated Our MySQL Database to PostgreSQL (And Didn't Quit My Job)

Real migration guide from someone who's done this shit 5 times

MySQL
/howto/migrate-legacy-database-mysql-postgresql-2025/beginner-migration-guide
46%
tool
Popular choice

jQuery - The Library That Won't Die

Explore jQuery's enduring legacy, its impact on web development, and the key changes in jQuery 4.0. Understand its relevance for new projects in 2025.

jQuery
/tool/jquery/overview
42%
tool
Popular choice

Hoppscotch - Open Source API Development Ecosystem

Fast API testing that won't crash every 20 minutes or eat half your RAM sending a GET request.

Hoppscotch
/tool/hoppscotch/overview
40%
tool
Popular choice

Stop Jira from Sucking: Performance Troubleshooting That Works

Frustrated with slow Jira Software? Learn step-by-step performance troubleshooting techniques to identify and fix common issues, optimize your instance, and boo

Jira Software
/tool/jira-software/performance-troubleshooting
38%
integration
Recommended

Stop manually configuring servers like it's 2005

Here's how Terraform, Packer, and Ansible work together to automate your entire infrastructure stack without the usual headaches

Terraform
/integration/terraform-ansible-packer/infrastructure-automation-pipeline
38%
integration
Recommended

Ansible Kubernetes Integration - 새벽 3시 장애 때문에 터득한 실전 가이드

kubectl 명령어 100개씩 치다가 손목 나간 개발자들을 위한 자동화 가이드

Ansible
/ko:integration/ansible-kubernetes/overview
38%
tool
Recommended

Ansible - SSH만 있으면 되는 서버 자동화 도구

서버 10대만 관리해도 실수하는 개발자들을 위한 도구

Ansible
/ko:tool/ansible/overview
38%
troubleshoot
Recommended

Docker Daemon Won't Start on Windows 11? Here's the Fix

Docker Desktop keeps hanging, crashing, or showing "daemon not running" errors

Docker Desktop
/troubleshoot/docker-daemon-not-running-windows-11/windows-11-daemon-startup-issues
38%
howto
Recommended

Deploy Django with Docker Compose - Complete Production Guide

End the deployment nightmare: From broken containers to bulletproof production deployments that actually work

Django
/howto/deploy-django-docker-compose/complete-production-deployment-guide
38%
tool
Recommended

Docker 프로덕션 배포할 때 털리지 않는 법

한 번 잘못 설정하면 해커들이 서버 통째로 가져간다

docker
/ko:tool/docker/production-security-guide
38%
tool
Popular choice

Northflank - Deploy Stuff Without Kubernetes Nightmares

Discover Northflank, the deployment platform designed to simplify app hosting and development. Learn how it streamlines deployments, avoids Kubernetes complexit

Northflank
/tool/northflank/overview
36%
tool
Popular choice

LM Studio MCP Integration - Connect Your Local AI to Real Tools

Turn your offline model into an actual assistant that can do shit

LM Studio
/tool/lm-studio/mcp-integration
35%
troubleshoot
Similar content

PostgreSQL Breaks in Creative Ways - Here's How to Fix the Disasters

The most common production-killing errors and how to fix them without losing your sanity

PostgreSQL
/troubleshoot/postgresql-performance/common-errors-solutions
34%
tool
Similar content

Bun Database Integration

Built-in database drivers. No more npm package hell when Node updates.

Bun
/tool/bun/database-integration
34%
tool
Popular choice

CUDA Development Toolkit 13.0 - Still Breaking Builds Since 2007

NVIDIA's parallel programming platform that makes GPU computing possible but not painless

CUDA Development Toolkit
/tool/cuda/overview
33%
troubleshoot
Recommended

Docker говорит permission denied? Админы заблокировали права?

depends on Docker

Docker
/ru:troubleshoot/docker-permission-denied-linux/permission-denied-solutions
31%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization