Dashboard view of WordPress performance metrics and DirectAdmin control panel on Rocky Linux.

WordPress Performance Tuning on DirectAdmin: The Complete Guide

, , ,

Series: WordPress Performance on DirectAdmin (Rocky Linux 9)

Phase 1: Foundations — Part 1 of 30

Overview and Goals

This article is part of the “WordPress Performance on DirectAdmin (Rocky Linux 9)” series (phase 1: foundations). The goal is to get a clean, measurable baseline and apply safe, DirectAdmin-aware performance tuning you can build on in later phases.

Scope and assumptions:

  • Rocky Linux 9 (EL9), DirectAdmin-managed hosting
  • PHP-FPM (per-user or per-domain) via DirectAdmin
  • Apache with or without NGINX reverse proxy (DirectAdmin defaults)
  • Shell and WP-CLI access

1. Establish a Baseline

1.1 Identify stack and DirectAdmin configuration

First confirm how DirectAdmin is serving WordPress for the target domain.

sudo /usr/local/directadmin/custombuild/build options | egrep "(webserver|php|nginx)"

Check per-domain web stack in DirectAdmin:

  • DirectAdmin > User Level > Domain Setup > domain.tld
  • Note if NGINX is enabled as a reverse proxy or if it is Apache-only.

Confirm PHP-FPM mode:

sudo /usr/local/directadmin/custombuild/build php n

Look for php1_mode=php-fpm and whether you are using per-user or per-domain pools (common on newer DirectAdmin installs).

1.2 Install baseline tooling

Install CLI tools for measurement and debugging:

sudo dnf install -y epel-release
sudo dnf install -y htop iotop curl wget git ncdu
sudo dnf install -y wrk

Optional (for more advanced load testing):

sudo dnf install -y nodejs
sudo npm install -g k6

Install WP-CLI globally (if not already):

cd /usr/local/src
sudo curl -o wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
sudo php wp-cli.phar --info
sudo chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

Test from a WordPress docroot (replace with your path):

cd /home/USER/domains/example.com/public_html
wp core version

1.3 Capture baseline performance

Use a single page as your reference, typically the homepage or a heavy landing page.

URL="https://example.com/"
wrk -t4 -c40 -d30s "$URL"

Record:

  • Requests/sec
  • Latency distribution
  • CPU load (htop) and memory usage during the test

Also log a simple single-request timing:

curl -o /dev/null -s -w "DNS: %{time_namelookup}\nConnect: %{time_connect}\nTTFB: %{time_starttransfer}\nTotal: %{time_total}\n" "$URL"

2. PHP-FPM Pool Tuning (DirectAdmin-Specific)

PHP-FPM is usually the first bottleneck on small to medium DirectAdmin servers. DirectAdmin manages pool configs under /usr/local/phpXY/lib/php-fpm.conf and per-user/per-domain pool files under /usr/local/phpXY/etc/php-fpm.d/ (exact path may vary slightly by version).

2.1 Locate the relevant pool

For a given domain, identify the pool file. Common patterns:

  • Per-user: /usr/local/php81/etc/php-fpm.d/USER.conf
  • Per-domain (newer DirectAdmin templates): /usr/local/php81/etc/php-fpm.d/USER-domain.tld.conf
sudo ls /usr/local/php*/etc/php-fpm.d/ | grep -i user_or_domain

Warning: Editing pool files incorrectly can break PHP for that user/domain. Apply changes incrementally and be ready to revert.

2.2 Choose sane starting values

For a typical 2–4 vCPU, 4–8 GB RAM Rocky 9 server hosting a few WordPress sites, a good starting point per busy pool:

  • pm: ondemand (for low concurrency) or dynamic (for steady traffic)
  • pm.max_children: 10–20 (per busy site)
  • pm.start_servers: 2–4
  • pm.min_spare_servers: 2
  • pm.max_spare_servers: 6
  • pm.process_idle_timeout: 10–20s

Estimate memory usage per PHP process:

ps -o rss,cmd -C php-fpm | head

RSS (KB) × pm.max_children should stay well below available RAM.

2.3 Edit pool config

Open the pool file for the relevant PHP version:

sudo nano /usr/local/php81/etc/php-fpm.d/USER.conf

Example tuned block:

[USER]
user = USER
group = USER
listen = /usr/local/php81/sockets/USER.sock
listen.owner = USER
listen.group = USER
listen.mode = 0660

pm = dynamic
pm.max_children = 15
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 6
pm.max_requests = 500
pm.process_idle_timeout = 15s

Restart PHP-FPM for that version:

sudo systemctl restart php-fpm81.service

Downtime note: Restarting PHP-FPM briefly interrupts PHP responses (usually <1s). During traffic peaks, coordinate restarts during low-traffic windows.

2.4 Persisting changes via DirectAdmin templates

DirectAdmin can overwrite pool configs during updates. To keep tuning persistent, adjust the PHP-FPM templates:

  • Template directory (example): /usr/local/directadmin/data/templates/custom/
  • Copy default templates: php-fpm.conf, php-fpm_pool.conf
sudo mkdir -p /usr/local/directadmin/data/templates/custom
cd /usr/local/directadmin/data/templates
sudo cp php-fpm* /usr/local/directadmin/data/templates/custom/

Edit the custom/php-fpm_pool.conf and set your preferred pm.* values, using DirectAdmin placeholders (e.g. |MAX_CHILDREN|) if you want per-user overrides later.

Rebuild configs:

sudo /usr/local/directadmin/custombuild/build php_fpm

3. Web Server and DirectAdmin Templates

3.1 Apache MPM tuning

On Rocky 9, Apache config is typically under /etc/httpd/conf/httpd.conf and /etc/httpd/conf.modules.d/. DirectAdmin often uses event MPM by default.

Check MPM:

sudo httpd -M | egrep "(mpm_event|mpm_prefork|mpm_worker)"

For PHP-FPM, event or worker is preferred over prefork. If you must change MPM, do it via DirectAdmin custombuild:

sudo /usr/local/directadmin/custombuild/build set apache_mpm event
sudo /usr/local/directadmin/custombuild/build apache
sudo systemctl restart httpd

Downtime note: Rebuilding Apache and restarting httpd will cause brief downtime; schedule appropriately.

3.2 KeepAlive and basic Apache tuning

In /etc/httpd/conf/httpd.conf (or DA-managed includes), tune:

sudo nano /etc/httpd/conf/httpd.conf

Suggested starting values:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

&lt;IfModule mpm_event_module&gt;
    ServerLimit 16
    StartServers 4
    MinSpareThreads 25
    MaxSpareThreads 75
    ThreadsPerChild 25
    MaxRequestWorkers 400
    MaxConnectionsPerChild 5000
&lt;/IfModule&gt;

Reload:

sudo systemctl reload httpd

3.3 NGINX reverse proxy (if enabled)

When DirectAdmin uses NGINX as a reverse proxy, configs are under /etc/nginx/ and DirectAdmin templates under /usr/local/directadmin/data/templates/.

Check NGINX status:

sudo systemctl status nginx

Basic NGINX tuning in /etc/nginx/nginx.conf:

worker_processes auto;
worker_connections 4096;

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 30;
    types_hash_max_size 2048;

    gzip on;
    gzip_comp_level 5;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

Test and reload:

sudo nginx -t
sudo systemctl reload nginx

4. WordPress-Level Performance

4.1 Disable slow or unused plugins/themes

From the WordPress docroot:

cd /home/USER/domains/example.com/public_html
wp plugin status

Deactivate obvious unused plugins:

wp plugin deactivate plugin-slug-1 plugin-slug-2

Switch away from heavy multipurpose themes where possible; at minimum, disable unused bundled plugins.

4.2 Enable page caching

On DirectAdmin, filesystem-based full-page caching is usually the simplest and most robust approach.

Install a caching plugin (example: Cache Enabler, WP Super Cache, or similar). Once installed, verify cache status via headers:

curl -I https://example.com/ | egrep -i "(cache|x-cache)"

Then compare performance with wrk before/after enabling cache.

4.3 Object caching (optional at this phase)

On Rocky 9, Redis is a good option if you have multiple WordPress sites or heavy authenticated traffic.

sudo dnf install -y redis
sudo systemctl enable --now redis

Secure Redis (bind to localhost):

sudo sed -i 's/^bind .*/bind 127.0.0.1/' /etc/redis/redis.conf
sudo systemctl restart redis

Install a Redis object cache plugin, then:

cd /home/USER/domains/example.com/public_html
wp redis enable

Monitor Redis memory usage with redis-cli info memory and adjust maxmemory in /etc/redis/redis.conf if needed.

5. Logging, Monitoring, and Testing Changes

5.1 Tail logs during tests

For Apache:

sudo tail -f /var/log/httpd/access_log /var/log/httpd/error_log

For NGINX (if used):

sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log

For PHP-FPM 8.1 (example):

sudo tail -f /var/log/php-fpm/81-php-fpm.log

Watch for:

  • server reached pm.max_children (increase pm.max_children or optimize PHP)
  • 502/504 errors (proxy timeouts, PHP-FPM overload)
  • Slow script warnings

5.2 Repeat performance tests

After each tuning step, rerun your baseline tests:

wrk -t4 -c40 -d30s "$URL"

Use curl to compare TTFB and total time:

curl -o /dev/null -s -w "TTFB: %{time_starttransfer}\nTotal: %{time_total}\n" "$URL"

Optional k6 script (save as load.js):

import http from 'k6/http';
import { sleep } from 'k6';

export let options = {
  vus: 20,
  duration: '1m',
};

export default function () {
  http.get('https://example.com/');
  sleep(1);
}

Run:

k6 run load.js

6. Per-Domain Tuning Workflow Checklist

Use this checklist per WordPress domain on DirectAdmin:

  • Identify PHP version and pool file for the domain.
  • Measure baseline with wrk and curl.
  • Estimate PHP-FPM memory usage and set pm.* values safely.
  • Restart PHP-FPM and confirm no errors in logs.
  • Review Apache/NGINX configs; apply basic keepalive and worker tuning.
  • Ensure full-page cache is enabled and working (check headers).
  • Optionally enable Redis object cache for dynamic-heavy workloads.
  • Retest performance and compare metrics to baseline.
  • Persist changes via DirectAdmin custom templates where applicable.

7. Firewalld and Network Considerations

On Rocky 9, ensure only necessary ports are exposed. This does not directly speed up WordPress, but reduces attack surface and noisy traffic.

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Keep Redis bound to 127.0.0.1 as shown earlier; do not open Redis ports externally.

8. Summary and Next Steps

In this phase we focused on foundational performance tuning for WordPress on DirectAdmin with Rocky Linux 9:

  • Establishing a measurable performance baseline using wrk, curl, and WP-CLI
  • DirectAdmin-aware PHP-FPM pool tuning and template persistence
  • Basic Apache/NGINX configuration tuning aligned with PHP-FPM
  • Enabling and verifying WordPress page and object caching
  • Systematic testing and log-based validation of each change

Later phases in this series will go deeper into opcode caching, database tuning (MariaDB/MySQL), advanced caching strategies, and automation of these configurations across multiple DirectAdmin servers.

This article offers general technical guidance. Validate all configurations in a safe environment before applying them to production.

Next: How WordPress Actually Handles a Page Request (And Where Performance Is Lost)

Smart reads for curious minds

We don’t spam! Read more in our privacy policy

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *