• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 9+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » The Ultimate DevOps Playbook: Tuning Nginx, Gunicorn/FPM, and MongoDB on OVH for WooCommerce

The Ultimate DevOps Playbook: Tuning Nginx, Gunicorn/FPM, and MongoDB on OVH for WooCommerce

Nginx Configuration for WooCommerce High Traffic

Optimizing Nginx is paramount for serving high-traffic WooCommerce sites. We’ll focus on key directives that directly impact performance and resource utilization on an OVH VPS or dedicated server. This assumes a standard Ubuntu/Debian setup.

Worker Processes and Connections

The worker_processes directive controls how many worker processes Nginx will spawn. A common recommendation is to set this to the number of CPU cores available. For highly concurrent scenarios, tuning worker_connections is also critical. This defines the maximum number of simultaneous connections that each worker process can handle.

Edit your main Nginx configuration file, typically /etc/nginx/nginx.conf:

user www-data;
worker_processes auto; # Or set to the number of CPU cores, e.g., worker_processes 4;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 1024; # Default is 1024, consider increasing for high concurrency
    multi_accept on;
}

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

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # ... other http configurations
}

After modifying nginx.conf, test the configuration and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Gzip Compression and Caching

Enabling Gzip compression significantly reduces the size of text-based assets (HTML, CSS, JS, JSON), leading to faster page loads. Browser caching via expires headers tells the client’s browser how long to cache specific file types, reducing server load for repeat visitors.

Add or modify these directives within your http block or a specific server block for your WooCommerce site:

http {
    # ... other http configurations

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

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

    # ... other http configurations
}

HTTP/2 and TLS/SSL Optimization

Leveraging HTTP/2 offers multiplexing, header compression, and server push, which are crucial for modern web applications. Proper TLS/SSL configuration, including cipher suites and session caching, is also vital for security and performance.

Ensure your server block is configured for HTTP/2 and optimized SSL:

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    server_name your_domain.com www.your_domain.com;

    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;

    # Modern TLS configuration (e.g., from Mozilla SSL Config Generator)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_session_cache shared:SSL:10m; # Adjust size as needed
    ssl_session_timeout 10m;
    ssl_session_tickets off; # Consider security implications

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s; # Use your preferred DNS resolvers
    resolver_timeout 5s;

    # ... other server configurations (root, index, location blocks)
}

Gunicorn/PHP-FPM Tuning for WooCommerce

The choice between Gunicorn (for Python-based frameworks like Django/Flask, less common for direct WooCommerce but possible with custom setups) and PHP-FPM (standard for WooCommerce) dictates the tuning approach. We’ll cover PHP-FPM as it’s the most relevant.

PHP-FPM Process Manager Settings

PHP-FPM’s process manager controls how worker processes are spawned and managed. The pm setting can be static, dynamic, or ondemand. For a busy WooCommerce site, dynamic or static often provides the best balance.

Edit your PHP-FPM pool configuration file. This is typically located in /etc/php/[version]/fpm/pool.d/www.conf (replace [version] with your PHP version, e.g., 7.4, 8.1).

; /etc/php/8.1/fpm/pool.d/www.conf

[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock # Or a TCP/IP socket if preferred

; Process Manager settings
pm = dynamic
pm.max_children = 50       ; Max number of children always running. Adjust based on RAM.
pm.start_servers = 5       ; Number of servers started when PHP-FPM is started.
pm.min_spare_servers = 5   ; Min number of idle servers.
pm.max_spare_servers = 10  ; Max number of idle servers.
pm.max_requests = 500      ; Max requests per child process. Helps prevent memory leaks.

; If using static, set a fixed number of children
; pm = static
; pm.max_children = 100

; If using ondemand, it spawns processes as needed
; pm = ondemand
; pm.max_children = 100
; pm.process_idle_timeout = 10s

; Other important settings
; request_terminate_timeout = 120s ; Timeout for script execution
; rlimit_files = 1024
; rlimit_core = 0

Tuning Considerations:

  • pm.max_children: This is the most critical. Monitor your server’s RAM. If you run out of memory, decrease this. If you have plenty of RAM and see processes waiting, increase it. A common starting point is (Total RAM - OS/Nginx/DB RAM) / Average PHP Process RAM.
  • pm.max_requests: Setting this to a reasonable number (e.g., 500-1000) helps recycle child processes, mitigating potential memory leaks in plugins or themes.
  • pm.start_servers, pm.min_spare_servers, pm.max_spare_servers: These are for dynamic mode. Adjust them to ensure enough idle workers are ready without consuming excessive memory.

After changes, restart PHP-FPM:

sudo systemctl restart php8.1-fpm

Nginx FastCGI Cache for WooCommerce

For static pages (like product listings, category pages, homepage) that don’t change per user, Nginx’s FastCGI cache can dramatically reduce PHP-FPM load and database queries. This is a powerful optimization for WooCommerce.

First, ensure the FastCGI cache module is enabled (it usually is by default). Then, configure it in your Nginx server block.

server {
    # ... other server configurations

    set $skip_cache 0;

    # Don't cache logged-in users or admin pages
    if ($http_cookie ~* "wordpress_logged_in_|comment_author_|woocommerce_items_in_cart") {
        set $skip_cache 1;
    }

    # Don't cache AJAX requests or POST requests
    if ($request_method = POST) {
        set $skip_cache 1;
    }
    if ($http_x_requested_with = "XMLHttpRequest") {
        set $skip_cache 1;
    }

    # Don't cache specific WooCommerce query parameters (e.g., add-to-cart)
    if ($args ~* "(add-to-cart|remove-from-cart|apply_coupon)") {
        set $skip_cache 1;
    }

    # Cache key based on request URI
    set $cache_key "$scheme$request_method$host$request_uri";
    # Use the cache key for logged-out users
    add_header X-Cache-Status $skip_cache; # For debugging

    # FastCGI Cache configuration
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Match your PHP-FPM socket

        # FastCGI Cache directives
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
        fastcgi_cache_valid 200 60s; # Cache successful responses for 60 seconds
        fastcgi_cache_valid 301 302 10m; # Cache redirects for 10 minutes
        fastcgi_cache_valid 404 1m; # Cache 404s for 1 minute
        fastcgi_cache_lock on; # Prevent multiple requests from hitting backend simultaneously
        fastcgi_cache_use_stale error timeout updating http_500; # Serve stale cache if backend fails
        fastcgi_cache_bypass $skip_cache;
        fastcgi_cache_revalidate on; # Revalidate cache before serving stale content
        add_header X-FastCGI-Cache $upstream_cache_status; # For debugging

        # Other fastcgi params
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Serve static files directly
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public";
        access_log off;
        try_files $uri =404;
    }

    # ... other location blocks for WordPress/WooCommerce
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

Cache Purging: You’ll need a mechanism to purge the cache when content is updated (e.g., new product, updated price). This can be done via a custom Nginx purge module or by using a WordPress plugin that integrates with Nginx cache purging (e.g., WP Rocket, W3 Total Cache with Nginx helper). A common approach is to use a custom Nginx location block:

location ~ ^/purge(/.*)$ {
    allow 127.0.0.1; # Allow purging only from localhost
    allow ::1;
    allow your_server_ip; # Allow purging from your management IP
    deny all;
    fastcgi_cache_purge  MY_CACHE_ZONE "$scheme$request_method$host$1"; # Replace MY_CACHE_ZONE with your cache zone name
    access_log purged.log;
    return 204;
}

Reload Nginx after applying these changes:

sudo nginx -t
sudo systemctl reload nginx

MongoDB Performance Tuning for WooCommerce

While WooCommerce primarily uses MySQL, many advanced plugins, custom solutions, or analytics platforms might leverage MongoDB. Optimizing MongoDB involves indexing, query analysis, and resource allocation.

Indexing Strategy

Proper indexing is the single most effective way to speed up MongoDB queries. Analyze your slow queries using MongoDB’s profiler.

Enable the profiler (for testing/debugging, disable in production unless actively monitoring):

# Connect to MongoDB shell
mongosh

# Enable profiling for the 'local' database (or your specific database)
db.setProfilingLevel(1) // 0=off, 1=slow queries, 2=all queries
db.getProfilingStatus()

Examine slow queries:

db.system.profile.find({ op: "query", millis: { $gt: 100 } }).pretty()

Based on slow queries, create appropriate indexes. For example, if you have a collection orders and frequently query by customer_id and order_date:

// Connect to your WooCommerce MongoDB database
use my_woocommerce_db;

// Create a compound index
db.orders.createIndex( { customer_id: 1, order_date: -1 } )

// Create an index for a common lookup field
db.products.createIndex( { sku: 1 } )

Use explain() to verify if your queries are using the indexes:

db.orders.find({ customer_id: "user123" }).explain("executionStats")

MongoDB Configuration (`mongod.conf`)

The mongod.conf file (typically /etc/mongod.conf) contains crucial settings for MongoDB’s performance and resource usage.

systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true
  logRotate: reopen

storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
  engine: wiredTiger # Default and recommended engine

# WiredTiger specific cache settings
# The default is 50% of RAM, but can be tuned.
# For a dedicated MongoDB server, you might allocate more.
# For a shared OVH server, be more conservative.
# Example: Allocate 4GB of RAM for WiredTiger cache
# wiredTiger:
#   engineConfig:
#     cacheSizeGB: 4

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod.pid
  # Ensure the user running mongod has correct permissions for dbPath and log paths

net:
  port: 27017
  bindIp: 0.0.0.0 # Or specific IPs for security

# Security settings (essential for production)
# security:
#   authorization: enabled

# Sharding settings (if applicable)
# sharding:
#   clusterRole: configsvr
#   # or shardsvr

Tuning Considerations:

  • storage.journal.enabled: Should always be true for data durability.
  • storage.engineConfig.cacheSizeGB: This is critical. Allocate a significant portion of RAM to the WiredTiger cache, but leave enough for the OS, Nginx, PHP-FPM, and other services. Monitor RAM usage closely.
  • net.bindIp: For security, bind to specific IP addresses rather than 0.0.0.0 if MongoDB is not intended to be accessible from all interfaces.
  • security.authorization: Enable this in production to control access.

After modifying mongod.conf, restart MongoDB:

sudo systemctl restart mongod

Monitoring and Iteration

Performance tuning is an iterative process. Continuously monitor your system’s health and performance metrics:

  • Nginx: Use ngx_http_stub_status_module for active connections, requests per second. Monitor error logs (/var/log/nginx/error.log).
  • PHP-FPM: Monitor the process manager status (if enabled) and PHP error logs.
  • MongoDB: Use mongostat, mongotop, and the profiler. Monitor system resource usage (CPU, RAM, I/O).
  • System: Use tools like htop, vmstat, iostat, and Prometheus/Grafana for comprehensive monitoring.

Regularly review these metrics, identify bottlenecks, and adjust configurations accordingly. For OVH environments, understanding the underlying hardware and network can also inform tuning decisions.

Primary Sidebar

A little about the Author

Having 9+ Years of Experience in Software Development.
Expertised in Php Development, WordPress Custom Theme Development (From scratch using underscores or Genesis Framework or using any blank theme or Premium Theme), Custom Plugin Development. Hands on Experience on 3rd Party Php Extension like Chilkat, nSoftware.

Recent Posts

  • Disaster Recovery 101: Architecting Auto-Failovers for Redis and PHP Deployments on OVH
  • How We Audited a High-Traffic WooCommerce Enterprise Stack on Google Cloud and Mitigated Race conditions during high-concurrency payment processing
  • Disaster Recovery 101: Architecting Auto-Failovers for Elasticsearch and Magento 2 Deployments on DigitalOcean
  • An Auditor’s Checklist for Securing WordPress Backends on OVH
  • Step-by-Step: Diagnosing Perl script high CPU throttling due to unoptimized regular expressions on AWS Servers

Copyright © 2026 · Vinay Vengala