Skip to main content

Database Performance Tuning Basics (WordPress VPS)

Database tuning is most effective when you measure first, change one thing at a time, and validate the result. On WordPress VPS servers, many "slow site" incidents are caused by one of three categories: memory pressure (buffer pool too small), slow queries (missing indexes or heavy plugins), or disk I/O bottlenecks (storage saturation during backups or peak writes).

Quick Summary

Start with measurement: confirm CPU/memory/disk health, check current MySQL/MariaDB variables, then enable the slow query log to find real query offenders.

warning

Incorrect MySQL/MariaDB configuration changes can prevent the database from starting. Always keep a rollback plan and validate syntax before restarting.

Mental Model

Prerequisites

  • Access to the database CLI (mysql).
  • Permission to view variables/status and (if needed) edit DB configuration.
  • Enough disk space for logs if you enable slow query logging.

Core Workflow

  1. Confirm the server is healthy (CPU, memory, disk).
  2. Check MySQL/MariaDB runtime variables (buffer pool size, max connections).
  3. Capture symptoms (slow queries, high threads running, lock waits).
  4. Enable slow query log (short window) and identify the real offenders.
  5. Tune/optimize, then verify.

Examples (Commands + Expected Output)

Output varies

Variable names are consistent, but values depend on your RAM and workload.

Check InnoDB buffer pool size

check-innodb-buffer-pool-size.sh
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"

Expected output:

example-output-buffer-pool.txt
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 1073741824|
+-------------------------+-----------+

Use case: The buffer pool is a key driver of read performance.

Check max connections

check-max-connections.sh
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"

Expected output:

example-output-max-connections.txt
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+

Use case: Too many connections can exhaust RAM; too few can cause errors under load.

Check current running threads (pressure signal)

check-threads-running.sh
mysql -u root -p -e "SHOW GLOBAL STATUS LIKE 'Threads_running';"

Expected output:

example-output-threads-running.txt
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| Threads_running | 12 |
+-----------------+-------+

Use case: Spikes often correlate with slow admin pages and timeouts.

Inspect active queries (processlist)

show-full-processlist.sh
mysql -u root -p -e "SHOW FULL PROCESSLIST;"

Expected output (excerpt):

example-output-processlist.txt
Id User Host db Command Time State Info
10 wpuser localhost wordpress Query 5 Sending SELECT * FROM wp_posts ...

Use case: Identify long-running queries and stuck states.

Check table engine distribution (InnoDB vs others)

check-table-engines.sh
mysql -u root -p -e "SELECT ENGINE, COUNT(*) AS tables FROM information_schema.TABLES WHERE TABLE_SCHEMA='wordpress' GROUP BY ENGINE;"

Expected output:

example-output-engines.txt
+--------+--------+
| ENGINE | tables |
+--------+--------+
| InnoDB | 12 |
+--------+--------+

Use case: Confirms whether --single-transaction is safe for dump consistency (InnoDB).

Use EXPLAIN to understand a query plan

explain-wordpress-query.sh
mysql -u root -p -D wordpress -e "EXPLAIN SELECT ID, post_date FROM wp_posts WHERE post_type='post' AND post_status='publish' ORDER BY post_date DESC LIMIT 10;"

Expected output (excerpt):

example-output-explain.txt
+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | wp_posts | ref | type_status | ... | ... | ... | 1000 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+

Use case: Confirm whether a query is using indexes or scanning too many rows.

Slow Query Logging (Safe Default Pattern)

Enable slow query logging for a short window to capture real offenders.

Example configuration (paths vary):

/etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=1
caution

Slow logs can grow quickly on busy sites. Ensure /var/log has space and log rotation is configured.

WordPress VPS Use Cases

SymptomLikely DB-related causeWhat to check
Slow wp-adminExpensive queries / too many running threadsSHOW FULL PROCESSLIST, slow query log
CPU spikes on DBQuery storms or missing indexessar, top, slow query log
Disk I/O waitHeavy writes (backups, imports, logs)iostat -xz, vmstat

Troubleshooting

ProblemLikely causeFix
DB restart failsConfig syntax errorRevert recent changes, check logs
Performance worse after tuningWrong assumptionRoll back and re-measure
Slow query log not createdPath/permission issueFix directory ownership and file permissions

Best Practices

  • Measure first, tune second.
  • Apply one change at a time and validate.
  • Keep a tested backup and a rollback plan.
Cheat Sheet
db-perf-cheat-sheet.sh
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"
mysql -u root -p -e "SHOW GLOBAL STATUS LIKE 'Threads_running';"
mysql -u root -p -e "SHOW FULL PROCESSLIST;"
mysql -u root -p -e "SELECT ENGINE, COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='wordpress' GROUP BY ENGINE;"

What's Next