Question

How to Optimize Nginx Configuration for High-Traffic WordPress Sites?

Hello DigitalOcean Community,

I’m currently managing several WordPress sites hosted on a single droplet, and I’ve started noticing some performance issues as traffic has grown over the past few months. Here are my droplet specs:

  • CPU: 2 vCPUs
  • RAM: 4GB
  • Storage: 80GB SSD
  • OS: Ubuntu 22.04
  • Web Server: Nginx with PHP-FPM

The sites run well under normal conditions, but during traffic spikes (especially after publishing new content or during campaigns), I face issues like:

  1. Slow Page Load Times: Pages, especially dynamic ones, take a long time to load under high traffic.
  2. Frequent Timeouts: Visitors occasionally report timeouts or connection errors.
  3. High Resource Usage: Both CPU and RAM usage spike to nearly 100% during these times.

I suspect my Nginx configuration might not be fully optimized for hosting multiple WordPress sites under high traffic. Here’s my current configuration:

worker_processes auto; events { worker_connections 1024; } http { client_max_body_size 100M; keepalive_timeout 65; sendfile on; gzip on; gzip_types text/plain application/javascript application/json text/css; }

My Questions

  1. How can I optimize Nginx settings for multiple WordPress sites? Are there specific tweaks or best practices to make Nginx handle dynamic WordPress content more efficiently?

  2. Is caching enough to reduce server load significantly? I’ve been looking into caching plugins like WP Super Cache and object caching with Redis. Should I prioritize server-side caching over WordPress plugins, and how should I implement it?

  3. Should I upgrade the droplet or scale horizontally? Would adding a load balancer or distributing sites across multiple droplets be more effective than upgrading the current droplet?

  4. How do I handle PHP-FPM tuning? I suspect the current PHP-FPM settings are not optimized for handling multiple WordPress sites. What values should I adjust to reduce bottlenecks?

  5. What are some DigitalOcean-specific tools or resources I can use? I’ve explored tutorials on DO, but I’m wondering if there are best practices or tools specific to droplets hosting WordPress sites that I might have overlooked.

If anyone has experience running high-traffic WordPress sites on DigitalOcean, I’d love to hear your insights or see examples of your optimized configurations.

Thanks for your time and help!


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Bobby Iliev
Site Moderator
Site Moderator badge
December 23, 2024

Hey 👋

Indeed, Nginx is great, but a few tweaks can make it even better for handling high traffic:

  • Increase the worker_connections to handle more simultaneous requests:
    events {
        worker_connections 4096;
    }
    
  • Enable FastCGI Cache to reduce the load on PHP-FPM. This caches dynamic content so it doesn’t need to be reprocessed:
    fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    

For more details, check out this guide: 🔗 How To Optimize Nginx Configuration

On the caching side of things, caching is essential for reducing server load:

  • Use a Plugin: Plugins like WP Super Cache or W3 Total Cache can generate static HTML pages, making your site load much faster.
  • Object Caching with Redis: Set up Redis to cache database queries and sessions. This is especially useful for dynamic WordPress sites. DigitalOcean makes it easy to get started with Managed Databases for Redis: 🔗 Redis Managed Databases

On another note, a CDN like Cloudflare can handle your static content (images, CSS, JS), reducing load on your server and speeding up delivery for users worldwide. Cloudflare’s free plan works great for most WordPress setups.

On the server side configuration updates, PHP-FPM is responsible for handling PHP requests, and tuning it properly can make a huge difference during high-traffic periods. The key settings to adjust are based on your server’s resources:

Key PHP-FPM Settings

In your /etc/php/8.1/fpm/pool.d/www.conf (adjust for your PHP version), you’ll find these parameters:

  • pm.max_children: The maximum number of PHP-FPM processes that can run at the same time.
  • pm.start_servers: The number of processes to start when PHP-FPM starts.
  • pm.min_spare_servers and pm.max_spare_servers: The minimum and maximum idle processes.

How to Calculate pm.max_children

The value of pm.max_children depends on the available RAM and the average memory usage of each PHP process. Here’s how you can calculate it:

  1. Check Available RAM: Use the following command to check your server’s available memory:

    free -m
    

    For example, if you have 4 GB RAM, reserve some memory for the system and MySQL (let’s say 1.5 GB), leaving 2.5 GB for PHP.

  2. Determine Average PHP Process Memory: Use top or htop during peak usage to monitor the memory usage of a PHP-FPM process. Let’s say each process uses 50 MB.

  3. Calculate pm.max_children: Divide the available memory for PHP by the average memory usage per process:

    pm.max_children = Available RAM for PHP / Memory per PHP Process
    

    Example:

    pm.max_children = 2500 MB / 50 MB = 50
    

    So, you’d set:

    pm.max_children = 50
    

Here’s a good starting point for your setup:

pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15

Monitor your server during peak traffic and adjust as needed.

On the WordPress side of things, make sure ot remove any plugins or themes you’re not using. Extra plugins not only slow down your site but also increase resource usage. Stick to lightweight, well-maintained plugins.

One other thing that you can consider is using a managed database cluster to offload the database load from your server. This can help improve performance and scalability:

🔗 Managed Databases

Finally, if traffic spikes are consistent and you’re maxing out resources, here are your options:

  • Scale Up: Upgrade to a droplet with 4 vCPUs and 8 GB RAM to handle more traffic.
  • Scale Horizontally: Add a Load Balancer to distribute traffic across multiple droplets. This is a great option for long-term scalability.

Hope that this helps!

- Bobby

KFSys
Site Moderator
Site Moderator badge
December 24, 2024

Heya,

I would try and focus on Nginx:

  • Increase worker_connections: Your worker_connections 1024; is the default but may be insufficient for high traffic. Update it to a higher value based on your server’s capacity:
events {
    worker_connections 4096;  # Or higher based on load
}

Enable fastcgi_cache: Set up fastcgi_cache to cache PHP responses directly at the Nginx level:

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout updating http_500 http_503;

server {
    ...
    location ~ \.php$ {
        fastcgi_cache WORDPRESS;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_bypass $http_cookie;
        fastcgi_no_cache $http_cookie;
        ...
    }
}

Fine-tune keepalive_timeout: Reduce keepalive_timeout to balance performance and resource usage:

keepalive_timeout 15;

Adjust client_body_buffer_size and fastcgi_buffers: Optimize handling large POST requests:

client_body_buffer_size 128k;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;

Also, PHP-FPM

Dynamic process management: Set pm to dynamic and adjust the limits:

pm = dynamic
pm.max_children = 50  # Based on available RAM
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
  • Use pm.max_children based on this formula: (Available RAM - other services) / average memory per PHP process

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.