Skip to main content
Back to Category

Best Server Configuration for WordPress

Optimal server configuration for WordPress: LEMP stack, PHP-FPM, Nginx FastCGI cache, Redis, MariaDB tuning, OPcache and CDN setup. Recommended specs for different traffic levels.

Read time: 15 min Web Hosting / Applications
wordpressnginxphp-fpmmariadbredishostingweb server

Table of Contents

Best Server Configuration for WordPress

WordPress is the world's most popular content management system. However, performance issues can occur when running with default configurations. This guide explains step by step the optimal server configuration to run your WordPress site quickly and reliably.

Traffic LevelMonthly VisitorsCPURAMStorageRecommended Plan
Small< 10,0002 vCPU2 GB20 GB NVMeVPS Starter
Medium10,000 - 100,0004 vCPU4-8 GB50 GB NVMeVDS Starter
Large100,000 - 500,0008 vCPU16 GB100 GB NVMeVDS Pro
Enterprise500,000+16+ vCPU32+ GB200+ GB NVMeDedicated

LEMP Stack Installation

The LEMP stack (Linux + Nginx + MariaDB + PHP-FPM) provides the best performance for WordPress. It uses less memory than Apache and supports higher concurrent connections.

hljs bash
# Update system
sudo apt update && sudo apt upgrade -y

# Install Nginx
sudo apt install nginx -y

# Install MariaDB
sudo apt install mariadb-server mariadb-client -y

# Install PHP and required extensions
sudo apt install php8.2-fpm php8.2-mysql php8.2-xml php8.2-gd \
  php8.2-curl php8.2-mbstring php8.2-zip php8.2-intl \
  php8.2-bcmath php8.2-imagick php8.2-redis -y

PHP-FPM Pool Configuration

Optimizing PHP-FPM for WordPress improves memory usage and response times.

hljs bash
sudo nano /etc/php/8.2/fpm/pool.d/wordpress.conf
hljs ini
[wordpress]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm-wordpress.sock

; Dynamic process management
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500

; PHP settings
php_admin_value[memory_limit] = 256M
php_admin_value[upload_max_filesize] = 64M
php_admin_value[post_max_size] = 64M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_vars] = 3000

Nginx Configuration and FastCGI Cache

Nginx FastCGI cache bypasses PHP processing and responds as fast as static content.

hljs nginx
# Define FastCGI cache zone
fastcgi_cache_path /var/cache/nginx/wordpress
    levels=1:2
    keys_zone=WORDPRESS:100m
    inactive=60m
    max_size=1g;

fastcgi_cache_key "$scheme$request_method$host$request_uri";
hljs nginx
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    root /var/www/wordpress;

    set $skip_cache 0;

    # Don't cache POST requests and query strings
    if ($request_method = POST) { set $skip_cache 1; }
    if ($query_string != "") { set $skip_cache 1; }

    # Don't cache WordPress admin and special URLs
    if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/") {
        set $skip_cache 1;
    }

    # Don't cache logged-in users
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wordpress_logged_in") {
        set $skip_cache 1;
    }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm-wordpress.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_cache WORDPRESS;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;
        add_header X-FastCGI-Cache $upstream_cache_status;
    }

    # Long cache for static files
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    location ~ /\.ht { deny all; }
    location = /xmlrpc.php { deny all; }
}

Redis Object Cache

Redis caches WordPress database queries, significantly reducing page load times.

hljs bash
# Install Redis
sudo apt install redis-server -y
# Redis configuration
maxmemory 256mb
maxmemory-policy allkeys-lru
save ""
unixsocket /var/run/redis/redis-server.sock
unixsocketperm 770
hljs php
// Add to wp-config.php
define('WP_REDIS_HOST', '/var/run/redis/redis-server.sock');
define('WP_REDIS_PORT', 0);
define('WP_REDIS_DATABASE', 0);

Install and activate the "Redis Object Cache" plugin from the WordPress admin panel.

MariaDB Optimization

hljs ini
[mysqld]
# InnoDB settings
innodb_buffer_pool_size = 1G          # 50-70% of RAM
innodb_buffer_pool_instances = 4
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT

# Query cache
query_cache_type = 1
query_cache_size = 64M
query_cache_limit = 2M

# Connection settings
max_connections = 150
wait_timeout = 60

# Temporary tables
tmp_table_size = 64M
max_heap_table_size = 64M

# Slow query log
slow_query_log = 1
long_query_time = 2

OPcache Configuration

OPcache caches PHP code as compiled bytecode, eliminating the need to recompile on every request.

hljs ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.jit=1255
opcache.jit_buffer_size=128M

CDN Setup

A CDN (Content Delivery Network) distributes your static files to servers worldwide, reducing load times.

Cloudflare Integration

  1. Sign up for Cloudflare and add your domain
  2. Move DNS records to Cloudflare
  3. Set SSL/TLS mode to "Full (Strict)"
  4. Install the Cloudflare plugin in WordPress
hljs php
// Add to wp-config.php (behind Cloudflare)
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 
    $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

WordPress Security Configuration

hljs php
// wp-config.php security settings
define('DISALLOW_FILE_EDIT', true);      // Disable theme/plugin editor
define('FORCE_SSL_ADMIN', true);         // Force HTTPS for admin
define('WP_DEBUG', false);               // Debug off (production)
define('AUTOMATIC_UPDATER_DISABLED', false); // Auto updates on

Backup Strategy

hljs bash
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/wordpress"

mkdir -p $BACKUP_DIR

# Backup database
mysqldump -u wpuser -pwppassword wordpress | \
  gzip > $BACKUP_DIR/db_$DATE.sql.gz

# Backup files
tar -czf $BACKUP_DIR/files_$DATE.tar.gz \
  --exclude=/var/www/wordpress/wp-content/cache \
  /var/www/wordpress

# Delete backups older than 30 days
find $BACKUP_DIR -mtime +30 -delete

To improve WordPress performance, apply the optimizations with the biggest impact first: 1) OPcache, 2) FastCGI cache, 3) Redis object cache, 4) CDN. These four steps speed up most WordPress sites by 5-10x.