DirectAdmin Server Performance Tuning: Apache MPM, PHP-FPM, OPcache & MySQL (2026 Guide)

Priya

Content Writer & Researcher

Last Updated: 9 August 2026
DirectAdmin Server Performance Tuning
πŸ–₯️

Slow DirectAdmin Server? We'll Tune It for Peak Performance

Our server management team tunes Apache, PHP-FPM, OPcache, and MySQL on DirectAdmin servers β€” with load testing to prove the improvement. Get your site running 3x faster.

πŸ–₯️12,400+PCs Fixed
⭐4.9β˜…Google Rating
⚑<15 minAvg. Response
πŸ›‘οΈISO 27001Certified

Why DirectAdmin Servers Run Slow: Root Causes

A slow website on a DirectAdmin server is rarely caused by a single bottleneck. The most common culprits are Apache MPM misconfiguration (too few or too many worker processes), PHP-FPM pool exhaustion, an under-tuned MySQL InnoDB buffer pool, and missing opcode caching. When all four are suboptimal simultaneously β€” as they are on a freshly installed DirectAdmin server β€” the combined effect can make even a simple WordPress site feel sluggish under moderate load.

This guide covers the complete performance stack for DirectAdmin: Apache MPM Event, PHP-FPM pool tuning, OPcache, MySQL/MariaDB InnoDB settings, and Nginx as a reverse proxy front-end β€” with real configuration values you can apply today.

Step 1: Identify the Bottleneck Before Tuning

Before changing any configuration, measure where time is actually being spent.

Check Server Load and Memory

# Current load average (1, 5, 15 minute)
uptime
# Output: load average: 4.21, 3.89, 3.51
# Rule of thumb: load > number of CPU cores = overloaded

# Memory breakdown
free -h
# Check if swap is being used heavily β€” that alone causes severe slowness

# Top processes consuming CPU/memory
top -bn1 | head -20

# Apache process count
ps aux | grep -c httpd
ps aux | grep -c apache2

Check MySQL Slow Query Log

# Enable slow query log temporarily
mysql -e "SET GLOBAL slow_query_log = 'ON';"
mysql -e "SET GLOBAL long_query_time = 1;"
mysql -e "SET GLOBAL slow_query_log_file = '/var/log/mysql-slow.log';"

# After 10 minutes, analyze the log
mysqldumpslow -t 10 /var/log/mysql-slow.log

Time a PHP Response

# Measure TTFB (Time To First Byte) from the server itself
curl -o /dev/null -s -w "Connect: %{time_connect}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s
" https://yourdomain.com/

# Target: TTFB under 200ms for cached pages, under 800ms for dynamic PHP

Step 2: Switch Apache to MPM Event Mode

DirectAdmin's default Apache setup often uses MPM Prefork, which spawns a new process for every request β€” extremely memory-hungry. MPM Event uses threads and is far more efficient for high-concurrency loads.

# Check current MPM
httpd -V | grep -i mpm
# or
apache2 -V | grep -i mpm

# Switch MPM in CustomBuild (DirectAdmin's build system)
cd /usr/local/directadmin/custombuild
./build set apache_mpm event
./build apache

# Verify the switch
httpd -V | grep -i "MPM Name"
# Should show: Server MPM: event

Tune MPM Event Settings

Edit /etc/httpd/conf/extra/httpd-mpm.conf (or /etc/apache2/mods-enabled/mpm_event.conf on Debian):

<IfModule mpm_event_module>
    # Tune based on: RAM / (avg PHP-FPM process size in MB)
    # For a 4GB RAM server with ~40MB average PHP process:
    StartServers             2
    MinSpareThreads         25
    MaxSpareThreads         75
    ThreadLimit             64
    ThreadsPerChild         25
    MaxRequestWorkers      150
    MaxConnectionsPerChild 1000
</IfModule>

After editing, test and reload:

apachectl configtest
service httpd graceful

Step 3: Tune PHP-FPM Pool Settings

PHP-FPM is the recommended PHP handler for DirectAdmin with MPM Event. The key configuration is pm.max_children β€” the maximum number of simultaneous PHP processes. Too low and requests queue; too high and the server runs out of RAM.

Calculate the Right pm.max_children

# Find average PHP-FPM process memory usage
ps --no-headers -o rss -C php-fpm | awk '{sum+=$1} END {print "Average PHP-FPM RSS: " sum/NR/1024 " MB"}'

# Calculate max_children:
# max_children = (Available RAM for PHP) / (Average PHP process size)
# Example: 3000 MB available / 50 MB per process = 60 max_children

Apply PHP-FPM Pool Configuration

PHP-FPM pool configs in DirectAdmin live at /usr/local/php{VERSION}/etc/php-fpm.d/. Edit the pool file for your PHP version:

[www]
; Process manager: use 'dynamic' for most setups
pm = dynamic

; Total PHP processes (calculated above)
pm.max_children = 60

; Start with this many workers
pm.start_servers = 10

; Keep at least this many idle workers
pm.min_spare_servers = 5

; Keep at most this many idle workers
pm.max_spare_servers = 20

; Recycle workers after this many requests (prevents memory leaks)
pm.max_requests = 500

; Kill workers idle for this long (seconds)
pm.process_idle_timeout = 10s

; Log slow requests (PHP execution > 5s)
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 5s
# Restart PHP-FPM
service php-fpm restart
# or for a specific version
service php74-fpm restart

# Verify workers are running
php-fpm -t && service php-fpm status

Step 4: Enable and Tune OPcache

OPcache compiles PHP files to bytecode and stores them in shared memory, eliminating the parsing overhead on every request. On a WordPress site, enabling OPcache typically cuts PHP execution time by 30–60%.

# Check if OPcache is active
php -r "var_dump(function_exists('opcache_get_status'));"
# Should return: bool(true)

# View current OPcache status
php -r "print_r(opcache_get_status());"

Optimal OPcache Settings

Edit /etc/php.d/10-opcache.ini or /usr/local/php{VERSION}/lib/php.ini:

opcache.enable=1
opcache.enable_cli=0

; Memory for compiled bytecode (MB) β€” increase if you host many sites
opcache.memory_consumption=256

; Number of cached files β€” 10000 covers most setups
opcache.max_accelerated_files=10000

; Seconds before checking for source file changes (0 = never check in prod)
opcache.revalidate_freq=60

; Interned string memory (MB)
opcache.interned_strings_buffer=16

; Enable JIT compiler (PHP 8.0+) β€” significant boost for compute-heavy PHP
opcache.jit_buffer_size=100M
opcache.jit=1255
# Restart PHP-FPM to apply
service php-fpm restart

# Verify OPcache is using memory
php -r "print_r(opcache_get_status()['memory_usage']);"

Step 5: Tune MySQL/MariaDB InnoDB Settings

MySQL performance issues are responsible for slow page load times on database-heavy sites (WordPress, Magento, WooCommerce). The two most impactful settings are innodb_buffer_pool_size and innodb_log_file_size.

# Check current InnoDB buffer pool usage
mysql -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%';"

# Check buffer pool hit rate (should be > 99%)
mysql -e "SELECT (1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests)) * 100 AS buffer_hit_rate FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME IN ('Innodb_buffer_pool_reads', 'Innodb_buffer_pool_read_requests');" 2>/dev/null || mysql -e "SELECT (1 - (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_buffer_pool_reads') / (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_buffer_pool_read_requests')) * 100 AS hit_rate;"

Apply MySQL Performance Settings

Edit /etc/my.cnf under [mysqld]:

[mysqld]
# Set to 50-70% of available RAM
# For a 4GB server: ~2.5GB
innodb_buffer_pool_size = 2560M

# For servers with >1GB buffer pool, use multiple instances
innodb_buffer_pool_instances = 4

# Larger log file = fewer flushes = better write performance
innodb_log_file_size = 512M

# How often InnoDB flushes logs to disk (2 = flush once per second, less safe but faster)
innodb_flush_log_at_trx_commit = 2

# Use O_DIRECT to avoid double buffering with OS cache
innodb_flush_method = O_DIRECT

# Enable query cache (deprecated in MySQL 8 β€” skip if using 8.0+)
# query_cache_type = 1
# query_cache_size = 64M

# Connection limits
max_connections = 200
thread_cache_size = 50
# Restart MySQL
service mysqld restart
# or
service mariadb restart

# Verify the settings took effect
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"

Step 6: Add Nginx as a Reverse Proxy Front-End

DirectAdmin's CustomBuild supports running Nginx in front of Apache. Nginx serves static files (images, CSS, JS) with near-zero overhead while Apache handles PHP behind it. This can reduce server load by 40–70% on content-heavy sites.

cd /usr/local/directadmin/custombuild

# Enable Nginx reverse proxy
./build set nginx yes
./build set nginx_proxy yes
./build nginx

# Rebuild Apache to work behind Nginx
./build apache

Configure Nginx Static File Caching

Add to /etc/nginx/conf.d/yourdomain.com.conf:

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    access_log off;
}

location ~* \.php$ {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Step 7: Enable Gzip Compression

# Apache: enable mod_deflate
# Add to /etc/httpd/conf.d/deflate.conf
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    AddOutputFilterByType DEFLATE application/javascript application/json
    AddOutputFilterByType DEFLATE application/x-javascript text/javascript
    DeflateCompressionLevel 6
</IfModule>

# Nginx: enable gzip
# Add to /etc/nginx/nginx.conf in http block
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;

Conclusion

DirectAdmin performance tuning follows a clear hierarchy: fix the PHP handler first (MPM Event + PHP-FPM), enable OPcache, then tune the database, then add a caching layer. Each step compounds: a properly tuned DirectAdmin server can handle 5–10x the concurrent users of a default installation with the same hardware. If you need performance tuning done correctly β€” with load testing before and after to confirm real-world improvement β€” the team at CloudHouse server management optimises DirectAdmin servers as part of our managed hosting service.

Get the Free Linux Server Admin Cheatsheet (PDF)

Essential commands for server management, networking, and troubleshooting β€” all on one printable page.

Running Linux servers? Let us manage them for you.

Our Managed Linux Server plans cover updates, security hardening, monitoring, and 24/7 incident response β€” so your servers stay up and your team stays focused.

  • Proactive OS patching and security updates
  • 24Γ—7 monitoring with instant alerting
  • Backup configuration and disaster recovery
  • Dedicated Linux engineers on call
See Pricing Plans β†’

What our customers say

β€œOur production server went down at 2 AM. CloudHouse had it back online in under 20 minutes. Incredible response time.”

Arun S.

CTO, SaaS Startup

β€œThey migrated our entire infrastructure from Ubuntu 18 to 22 with zero downtime. Couldn't have asked for better.”

Deepak N.

DevOps Lead

Frequently Asked Questions

The most common cause is Apache running MPM Prefork (one process per request) instead of MPM Event (threaded), combined with PHP-FPM pm.max_children set too low. Run 'httpd -V | grep MPM' to check, and 'ps aux | grep php-fpm | wc -l' to see if workers are maxed out. Switch to MPM Event via CustomBuild and recalculate pm.max_children as (available RAM) / (average PHP process size).

Need this done for you?

Server Management Service

Managed Linux and Windows servers: monitoring, patching, security and 24/7 support.

Learn more

Book your free 15-minute diagnosis

A certified technician will call you back within 15 minutes during business hours.

Share this article

Leave a Comment

Comments (0)

Loading comments...