Back to tutorials
Tutorial

Linux VPS Database Connection Pool Configuration Tutorial: Optimize MySQL, PostgreSQL, and MariaDB Performance for High Traffic in 2026

Master database connection pool configuration for MySQL, PostgreSQL & MariaDB on Linux VPS. Complete tutorial with PgBouncer, ProxySQL & optimization.

By Anurag Singh
Updated on May 09, 2026
Category: Tutorial
Share article
Linux VPS Database Connection Pool Configuration Tutorial: Optimize MySQL, PostgreSQL, and MariaDB Performance for High Traffic in 2026

Why Database Connection Pool Configuration Matters for VPS Performance

Your database runs out of connections during traffic spikes. Applications timeout. Users see error pages.

You scramble to restart services, but the root problem persists: inefficient connection management.

Database connection pool configuration solves this by maintaining a pool of reusable connections between your application and database server. Instead of opening and closing connections for each request, connection pooling reuses existing connections.

This reduces overhead and improves response times.

On a HostMyCode VPS, proper connection pooling can handle 10x more concurrent users with the same hardware resources. You'll reduce connection establishment latency from 10-20ms to near zero while preventing connection exhaustion errors.

MySQL Connection Pooling with ProxySQL

ProxySQL acts as a transparent proxy between your applications and MySQL servers. It provides advanced connection pooling, query routing, and load balancing capabilities.

Installing ProxySQL on Ubuntu 24.04

Add the ProxySQL repository and install the package:

wget -O - 'https://repo.proxysql.com/ProxySQL/proxysql-2.6.x/repo_pub_key' | apt-key add -
echo deb https://repo.proxysql.com/ProxySQL/proxysql-2.6.x/$(lsb_release -sc)/ ./ | tee /etc/apt/sources.list.d/proxysql.list
apt update
apt install proxysql mysql-client

Start and enable the ProxySQL service:

systemctl start proxysql
systemctl enable proxysql

Basic ProxySQL Configuration

Connect to the ProxySQL admin interface on port 6032:

mysql -u admin -padmin -h 127.0.0.1 -P6032

Configure your MySQL backend servers:

INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight) VALUES
(0, '127.0.0.1', 3306, 1000);

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

Add MySQL users that ProxySQL will use:

INSERT INTO mysql_users(username, password, default_hostgroup) VALUES
('app_user', 'secure_password', 0);

LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

Connection Pool Optimization

Configure connection pool settings for your traffic patterns:

UPDATE global_variables SET variable_value='200' WHERE variable_name='mysql-max_connections';
UPDATE global_variables SET variable_value='10' WHERE variable_name='mysql-default_max_latency_ms';
UPDATE global_variables SET variable_value='4' WHERE variable_name='mysql-server_version';

LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

Key parameters explained:

  • mysql-max_connections: Maximum connections ProxySQL accepts from clients
  • mysql-default_max_latency_ms: Maximum acceptable latency before marking a server as lagged
  • mysql-free_connections_pct: Percentage of free connections to maintain in the pool

PostgreSQL Connection Pooling with PgBouncer

PgBouncer provides lightweight connection pooling specifically designed for PostgreSQL. It supports three pooling modes and requires minimal memory overhead.

Installing PgBouncer

Install PgBouncer from the Ubuntu repositories:

apt update
apt install pgbouncer postgresql-client

Create the PgBouncer configuration directory:

mkdir -p /etc/pgbouncer
chown postgres:postgres /etc/pgbouncer

Configuring PgBouncer

Create the main configuration file at /etc/pgbouncer/pgbouncer.ini:

[databases]
myapp = host=127.0.0.1 port=5432 dbname=production_db user=app_user

[pgbouncer]
listen_port = 6432
listen_addr = 127.0.0.1
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
logfile = /var/log/postgresql/pgbouncer.log
pidfile = /var/run/postgresql/pgbouncer.pid

; Connection pool settings
pool_mode = transaction
max_client_conn = 200
default_pool_size = 20
max_db_connections = 50
reserve_pool_size = 5

Create the user authentication file:

echo '"app_user" "md5hashed_password"' > /etc/pgbouncer/userlist.txt
chown postgres:postgres /etc/pgbouncer/userlist.txt
chmod 600 /etc/pgbouncer/userlist.txt

Pool Mode Selection

Choose the appropriate pooling mode for your application:

  • session: Connection released when client disconnects (most compatible)
  • transaction: Connection released after each transaction (recommended for most apps)
  • statement: Connection released after each statement (highest performance, limited compatibility)

For web applications using frameworks like Django or Rails, transaction mode provides the best balance of performance and compatibility.

Starting PgBouncer

Start PgBouncer as the postgres user:

sudo -u postgres pgbouncer -d /etc/pgbouncer/pgbouncer.ini

Create a systemd service file for automatic startup:

cat << EOF > /etc/systemd/system/pgbouncer.service
[Unit]
Description=PgBouncer PostgreSQL connection pooler
After=postgresql.service

[Service]
Type=forking
User=postgres
ExecStart=/usr/bin/pgbouncer -d /etc/pgbouncer/pgbouncer.ini
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable pgbouncer
systemctl start pgbouncer

MariaDB Connection Pool Configuration

MariaDB includes built-in connection pooling through the thread pool plugin. It also supports external poolers like ProxySQL.

Enabling MariaDB Thread Pool

Edit your MariaDB configuration file /etc/mysql/mariadb.conf.d/50-server.cnf:

[mariadb]
thread_handling = pool-of-threads
thread_pool_size = 4
thread_pool_max_threads = 500
thread_pool_min_threads = 1
thread_pool_idle_timeout = 60
thread_pool_oversubscribe = 3

Restart MariaDB to apply changes:

systemctl restart mariadb

Verifying Thread Pool Status

Connect to MariaDB and check thread pool statistics:

mysql -u root -p
SHOW GLOBAL STATUS LIKE 'thread_pool%';

Key metrics to monitor:

  • Thread_pool_threads: Current number of threads
  • Thread_pool_busy_threads: Active threads processing queries
  • Thread_pool_idle_threads: Threads waiting for work

Application-Level Connection Pool Configuration

Configure connection pools in your application frameworks for optimal performance.

Node.js with mysql2

Configure connection pooling in your Node.js application:

const mysql = require('mysql2/promise');

const pool = mysql.createPool({
  host: 'localhost',
  port: 6033, // ProxySQL port
  user: 'app_user',
  password: 'secure_password',
  database: 'production_db',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0,
  acquireTimeout: 60000,
  timeout: 60000
});

// Use the pool for queries
async function getUsers() {
  const [rows] = await pool.execute('SELECT * FROM users LIMIT 10');
  return rows;
}

Python with SQLAlchemy

Configure connection pooling with SQLAlchemy:

from sqlalchemy import create_engine
from sqlalchemy.pool import QueuePool

engine = create_engine(
    'postgresql://app_user:password@localhost:6432/myapp',
    poolclass=QueuePool,
    pool_size=10,
    max_overflow=20,
    pool_pre_ping=True,
    pool_recycle=3600
)

Java Spring Boot Configuration

Configure HikariCP connection pool in application.yml:

spring:
  datasource:
    url: jdbc:mysql://localhost:6033/production_db
    username: app_user
    password: secure_password
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      leak-detection-threshold: 60000

Performance Monitoring and Optimization

Monitor your connection pools to identify bottlenecks and optimize performance.

ProxySQL Monitoring

Check ProxySQL connection statistics:

mysql -u admin -padmin -h 127.0.0.1 -P6032 -e \
"SELECT hostgroup,srv_host,status,ConnUsed,ConnFree,ConnOK,ConnERR,Queries FROM stats_mysql_connection_pool;"

Monitor query performance:

SELECT * FROM stats_mysql_query_digest ORDER BY sum_time DESC LIMIT 10;

PgBouncer Statistics

Connect to PgBouncer admin interface:

psql -h 127.0.0.1 -p 6432 -U pgbouncer pgbouncer

Check pool statistics:

SHOW POOLS;
SHOW CLIENTS;
SHOW SERVERS;

Setting Up Alerts

Create monitoring scripts to alert on connection pool issues:

#!/bin/bash
# Check ProxySQL connection usage
USAGE=$(mysql -u admin -padmin -h 127.0.0.1 -P6032 -ss -e \
  "SELECT SUM(ConnUsed) FROM stats_mysql_connection_pool;")

if [ "$USAGE" -gt 180 ]; then
  echo "High connection usage: $USAGE" | mail -s "ProxySQL Alert" admin@example.com
fi

For comprehensive monitoring, consider integrating with Prometheus and Grafana for VPS monitoring.

Common Connection Pool Issues and Solutions

Troubleshoot frequent connection pooling problems before they impact production.

Connection Exhaustion

Symptoms: "Too many connections" errors, application timeouts

Solution: Increase max_connections in MySQL/PostgreSQL and adjust pool sizes:

# MySQL
SET GLOBAL max_connections = 500;

# PostgreSQL
echo "max_connections = 200" >> /etc/postgresql/14/main/postgresql.conf
systemctl restart postgresql

Connection Leaks

Symptoms: Gradual increase in active connections, eventual exhaustion

Solution: Enable connection leak detection and set connection timeouts:

# HikariCP leak detection
hikari.leak-detection-threshold=60000

# PgBouncer connection lifetime
server_lifetime = 3600

High Connection Latency

Symptoms: Slow query response times, connection establishment delays

Solution: Optimize pool sizes and enable connection pre-warming:

# Increase minimum idle connections
default_pool_size = 10
min_pool_size = 5

# Enable connection validation
server_check_delay = 30

Proper MySQL performance monitoring helps identify connection-related bottlenecks early.

Need a reliable VPS for your database connection pooling setup? HostMyCode managed VPS hosting provides optimized servers with pre-configured database environments and 24/7 support to help you implement these connection pooling strategies effectively.

Frequently Asked Questions

What's the ideal connection pool size for my application?

Start with pool_size = (number_of_cpu_cores * 2) + effective_spindle_count. For a 4-core VPS with SSD storage, begin with 10 connections and adjust based on monitoring data.

Should I use connection pooling with both ProxySQL and application-level pools?

Yes, but configure them carefully. Set application pools smaller (5-10 connections) and let ProxySQL handle the database-level pooling with larger pools (20-50 connections).

How do I handle connection pooling in microservices architectures?

Use a centralized connection pooler like ProxySQL or PgBouncer. Have each microservice connect through the pooler to prevent connection multiplication across services.

What connection timeout values should I use?

Set application timeouts to 30-60 seconds, connection pool timeouts to 10-20 seconds, and database timeouts to 5-10 seconds. This creates a proper timeout hierarchy.

How can I test my connection pool configuration?

Use tools like Apache Bench (ab) or wrk to simulate concurrent connections: ab -n 1000 -c 50 http://your-app/api/endpoint. Monitor pool statistics during the test to verify behavior.