• 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 WordPress

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

Nginx as a High-Performance Reverse Proxy and Static File Server

For WordPress deployments, Nginx excels as a reverse proxy, efficiently handling incoming HTTP requests and serving static assets directly. This offloads significant work from the PHP-FPM or Gunicorn processes, leading to substantial performance gains. Our OVH environment benefits from Nginx’s non-blocking, event-driven architecture, making it ideal for high-concurrency scenarios.

Optimizing Nginx Configuration for WordPress

The core Nginx configuration file, typically located at /etc/nginx/nginx.conf, and site-specific configurations in /etc/nginx/sites-available/ (symlinked to /etc/nginx/sites-enabled/) are critical. We’ll focus on tuning worker processes, caching, and static file serving.

Worker Processes and Connections

The worker_processes directive should ideally be set to the number of CPU cores available on your server. This allows Nginx to utilize all available processing power. The worker_connections directive defines the maximum number of simultaneous connections that each worker process can handle. A common starting point is 1024, but this can be increased based on server load and available RAM.

Example Nginx Configuration Snippet
# /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 4096; # Increased from default 1024
    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
}

Caching and Static File Serving

Leveraging Nginx’s ability to serve static files directly and implementing browser caching significantly reduces the load on your backend application. We’ll configure aggressive caching for common WordPress static assets like images, CSS, and JavaScript.

WordPress Site Configuration Example
# /etc/nginx/sites-available/your-wordpress-site

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    root /var/www/your-wordpress-site/public_html;
    index index.php index.html index.htm;

    # Serve static files directly from Nginx
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|webp|woff|woff2|ttf|eot)$ {
        expires 365d; # Cache for 1 year
        add_header Cache-Control "public, no-transform";
        access_log off; # Don't log access for static files
        try_files $uri =404;
    }

    # Deny access to sensitive files
    location ~ /\.ht {
        deny all;
    }

    # Pass PHP scripts to FastCGI server
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        # With php-fpm (adjust socket path if needed)
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        # Or with gunicorn (if using Python backend for WordPress)
        # fastcgi_pass unix:/run/gunicorn.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Deny access to wp-config.php
    location ~* wp-config.php {
        deny 777;
    }

    # Block access to hidden files
    location ~ /\. {
        deny all;
    }

    # Gzip compression
    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;
}

Optimizing PHP-FPM or Gunicorn for WordPress

The choice between PHP-FPM and Gunicorn depends on your WordPress setup. For traditional PHP WordPress, PHP-FPM is the standard. If you’re using a Python-based WordPress framework or a custom PHP setup with a Python WSGI server, Gunicorn is the choice. Both require careful tuning to handle concurrent requests efficiently.

Tuning PHP-FPM

PHP-FPM’s performance is largely dictated by its process management. The pm (process manager) setting is crucial. For busy sites, a dynamic or ondemand approach can save resources, while a static approach offers more predictable performance under heavy load.

PHP-FPM Pool Configuration Example
; /etc/php/8.1/fpm/pool.d/www.conf (or your custom pool name)

[www]
user = www-data
group = www-data
listen = /var/run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Process Manager settings
; pm = dynamic | static | ondemand
pm = dynamic
pm.max_children = 100       ; Max number of child processes at any time
pm.start_servers = 5        ; Number of child processes started at boot
pm.min_spare_servers = 2    ; Min number of idle processes
pm.max_spare_servers = 10   ; Max number of idle processes
pm.max_requests = 500       ; Max requests per child process before respawning

; Other important settings
request_terminate_timeout = 60s ; Timeout for script execution
; memory_limit = 256M           ; Adjust based on WordPress plugin needs
; upload_max_filesize = 64M     ; Adjust as needed
; post_max_size = 64M           ; Adjust as needed

Tuning Strategy: Start with pm = dynamic. Monitor your server’s CPU and memory usage. If you see consistent high load and many requests waiting, consider increasing pm.max_children. If memory is a concern, pm = ondemand might be better, but it can introduce slight latency on initial requests. pm.max_requests helps prevent memory leaks by respawning processes.

Tuning Gunicorn (for Python-based WordPress or custom setups)

Gunicorn’s performance is controlled by its worker class and the number of workers. The sync worker class is the default and simplest, but gevent or eventlet can offer better concurrency for I/O-bound tasks.

Gunicorn Command Line Example
# Example command to start Gunicorn for a Python WordPress app
# Assuming your app is in 'wsgi.py' and listens on a Unix socket

gunicorn --workers 4 --worker-class gevent --bind unix:/run/gunicorn.sock --timeout 120 your_app_module:app

Tuning Strategy: The optimal number of workers is typically (2 * number_of_cores) + 1. For I/O-bound applications (like many WordPress sites interacting with databases or external APIs), using --worker-class gevent or eventlet can significantly improve throughput by allowing workers to handle multiple requests concurrently without blocking. Adjust --timeout based on your longest expected request processing time.

MongoDB Optimization for WordPress Data Storage

While WordPress traditionally uses MySQL, some advanced setups or plugins might leverage MongoDB for specific data types (e.g., caching, user profiles, analytics). Optimizing MongoDB is crucial for maintaining application responsiveness.

Key MongoDB Tuning Parameters

Tuning MongoDB involves several aspects: memory allocation, indexing, and query optimization. On OVH, ensuring sufficient RAM is paramount, as MongoDB heavily relies on RAM for its working set.

Memory and WiredTiger Cache

The WiredTiger storage engine (default since MongoDB 3.2) uses a cache that is typically sized to 50% of the available RAM on systems with 1GB RAM or more, up to a maximum of 1TB. You can explicitly set this using the storage.wiredTiger.engineConfig.cacheSizeGB parameter in the MongoDB configuration file (/etc/mongod.conf).

MongoDB Configuration Snippet
# /etc/mongod.conf

storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 4 # Example: Allocate 4GB of RAM for WiredTiger cache

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1 # Or the appropriate IP for your OVH setup

# security:
#   keyFile: /path/to/keyfile.pem
#   authorization: enabled

# logging:
#   loggers:
#     component:
#       verbosity: 0
#       append: true
#   path: /var/log/mongodb/mongod.log

# processManagement:
#   fork: true
#   pidFilePath: /var/run/mongodb/mongod.pid
#   timeZoneInfo: /usr/share/zoneinfo

Tuning Strategy: Monitor MongoDB’s cache hit ratio using db.serverStatus().wiredTiger.cache. A ratio above 90% is generally considered good. If it’s lower, you might need more RAM or a larger cache size. Ensure your bindIp is set correctly for network access within your OVH environment.

Indexing Strategies

Proper indexing is paramount for query performance. Analyze slow queries using MongoDB’s profiler and ensure appropriate indexes are in place. Avoid over-indexing, as indexes consume disk space and slow down write operations.

Example Index Creation
// Connect to your MongoDB instance
// use your_database_name;

// Example: Indexing a 'posts' collection by 'author_id' and 'publish_date'
db.posts.createIndex( { author_id: 1, publish_date: -1 } )

// Example: Compound index for searching user profiles by 'username' and 'email'
db.users.createIndex( { username: 1, email: 1 } )

// Use explain() to analyze query performance and identify missing indexes
db.collection.find({ field1: value1 }).explain("executionStats")

Tuning Strategy: Regularly review slow query logs (if enabled) and use explain() to understand query execution plans. For WordPress-specific data, consider indexes on fields frequently used in queries, such as post IDs, user IDs, categories, tags, and timestamps.

Putting It All Together: A Holistic Approach

Optimizing a WordPress stack on OVH involves a layered approach. Nginx handles the edge, efficiently serving static content and proxying dynamic requests. PHP-FPM or Gunicorn processes these dynamic requests, and MongoDB (if used) stores and retrieves data. Each layer must be tuned independently and then observed holistically.

Monitoring and Iteration

Performance tuning is an ongoing process. Implement robust monitoring using tools like Prometheus, Grafana, Datadog, or OVH’s built-in monitoring. Key metrics to track include:

  • Nginx: Request rate, error rate (4xx, 5xx), connection count, upstream response times.
  • PHP-FPM/Gunicorn: Process count, request latency, CPU/memory usage per process.
  • MongoDB: Query latency, cache hit ratio, disk I/O, network traffic, connection count.
  • System: Overall CPU, memory, disk I/O, network bandwidth.

Use this data to identify bottlenecks and iteratively adjust configurations. Remember to test changes in a staging environment before deploying to production. For OVH, consider the specific network configurations and potential latency between services if they are not on the same host or availability zone.

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

  • How to Optimize Largest Contentful Paint (LCP) and Interaction to Next Paint (INP) in Large-Scale WooCommerce Enterprise Sites
  • Server Monitoring Best Practices: Keeping Your Laravel App and Elasticsearch Clusters Alive on Linode
  • Resolving thread pools deadlock during concurrent ActiveRecord transaction processing Under Peak Event Traffic on OVH
  • Eliminating PostgreSQL Bottlenecks: Tuning Queries for High-Performance Laravel Stores
  • The Ultimate DevOps Playbook: Tuning Nginx, Gunicorn/FPM, and DynamoDB on OVH for Magento 2

Copyright © 2026 · Vinay Vengala