• 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 MySQL on OVH for WooCommerce

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

Nginx as a High-Performance Frontend for WooCommerce

When deploying WooCommerce on OVH, Nginx serves as the de facto standard for a high-performance web server and reverse proxy. Its event-driven architecture excels at handling concurrent connections, making it ideal for the often-spiky traffic patterns of e-commerce sites. We’ll focus on tuning Nginx for static asset delivery, request buffering, and efficient SSL/TLS termination.

Optimizing Static File Serving

Efficiently serving static assets (images, CSS, JS) is crucial. Nginx’s `sendfile` directive and `open_file_cache` are key. Ensure `sendfile` is enabled to bypass user space and directly transfer data from the file descriptor to the socket. The `open_file_cache` directive caches file descriptors and metadata, reducing the overhead of repeated `stat()` calls.

Nginx Configuration Snippet

# In your http block or a dedicated conf file included in http
http {
    # ... other http configurations ...

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off; # Important for security

    # Open file cache configuration
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    # Gzip compression for text-based assets
    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;

    # ... other http configurations ...
}

Request Buffering and Client Limits

To prevent resource exhaustion from slow or malicious clients, configure request buffering. This limits the amount of data Nginx will buffer from a client. For a PHP-based application like WooCommerce, it’s also vital to set appropriate client body size limits.

Nginx Configuration Snippet

# In your http or server block
client_body_buffer_size 128k;
client_max_body_size 50m; # Adjust based on expected media uploads
client_header_buffer_size 1k;
large_client_header_buffers 4 128k;

# Buffering for proxying to Gunicorn/FPM
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 8 128k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;

SSL/TLS Tuning

Secure connections are non-negotiable. Optimize SSL/TLS by enabling HTTP/2, using modern cipher suites, and configuring session caching. OVH often provides managed SSL certificates, simplifying deployment.

Nginx Configuration Snippet

# In your server block for SSL
listen 443 ssl http2;
listen [::]:443 ssl http2;

ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; # Path to your OVH managed cert
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; # Path to your OVH managed key

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;
ssl_session_timeout 10m;
ssl_session_tickets off; # Consider security implications if enabling

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

Gunicorn/PHP-FPM: The Application Backend

For a PHP-based application like WooCommerce, you’ll typically use PHP-FPM. If you’re using a Python framework with WooCommerce integrations (less common but possible), Gunicorn would be the WSGI HTTP Server. We’ll cover PHP-FPM tuning, as it’s the standard for WordPress/WooCommerce.

PHP-FPM Process Management

PHP-FPM’s process manager is critical for performance and stability. The choice between `dynamic` and `static` (or `ondemand`) depends on your server’s resources and traffic patterns. For most WooCommerce sites, `dynamic` offers a good balance.

PHP-FPM Configuration (`php-fpm.conf` or pool configuration)**

; In your PHP-FPM pool configuration file (e.g., /etc/php/8.1/fpm/pool.d/www.conf)

; Choose one process manager: dynamic, static, or ondemand
; 'dynamic' is generally recommended for variable loads.
; 'static' is good for consistent high load but can waste resources.
; 'ondemand' is resource-efficient but can have higher initial latency.
pm = dynamic

; For 'dynamic' pm:
; pm.max_children: The maximum number of children that can be started.
; Adjust based on available RAM. A common starting point is (Total RAM - OS/Nginx RAM) / Average PHP Process Size.
pm.max_children = 100

; pm.start_servers: Number of child processes to start when the FPM master process is started.
pm.start_servers = 10

; pm.min_spare_servers: Minimum number of "idle" (free) processes.
pm.min_spare_servers = 5

; pm.max_spare_servers: Maximum number of "idle" (free) processes.
pm.max_spare_servers = 20

; For 'static' pm:
; pm.max_children = 100 ; Fixed number of children

; For 'ondemand' pm:
; pm.max_children = 100 ; Max children allowed

; Process idle timeout. If a child process has been idle for this amount of time, it will be killed.
; This is useful for 'dynamic' and 'ondemand' to free up resources.
pm.process_idle_timeout = 10s

; Maximum number of requests each child process should execute before respawning.
; This helps to prevent memory leaks.
pm.max_requests = 500

; Request termination timeout with signal after 0 seconds.
; Default value is 0 (disabled).
request_terminate_timeout = 30s

; Slowlog - logs scripts that take too long to execute.
; slowlog = /var/log/php-fpm/slowlog
; request_slowlog_timeout = 10s

; Set user and group for the pool
user = www-data
group = www-data

; Listen on a Unix socket for better performance than TCP/IP
; listen = /run/php/php8.1-fpm.sock
; listen.owner = www-data
; listen.group = www-data
; listen.mode = 0660

; Or listen on a TCP port if Nginx is on a different server
; listen = 127.0.0.1:9000
; listen.owner = www-data
; listen.group = www-data
; listen.mode = 0660

PHP Configuration Tuning (`php.ini`)

Beyond FPM process management, core PHP settings significantly impact WooCommerce performance. Key directives include memory limits, execution times, and opcache settings.

PHP `php.ini` Snippet

; In your php.ini file (e.g., /etc/php/8.1/fpm/php.ini)

; Increase memory limit for complex operations (e.g., product imports, large queries)
memory_limit = 512M

; Increase max execution time for long-running processes (e.g., cron jobs, imports)
max_execution_time = 120

; Increase max input vars for handling large POST requests (e.g., many form fields)
; WooCommerce often requires this to be higher.
max_input_vars = 3000

; Enable and configure OPcache for significant performance gains
opcache.enable=1
opcache.enable_cli=1 ; Enable for CLI scripts too (e.g., WP-CLI)
opcache.memory_consumption=128 ; MB
opcache.interned_strings_buffer=16 ; MB
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60 ; Check for file updates every 60 seconds
opcache.validate_timestamps=1 ; Set to 0 in production for maximum performance if you have a robust deployment process
opcache.save_comments=1
opcache.enable_file_override=0
opcache.fast_shutdown=0
opcache.optimization_level=0xFFFFFFFF ; Full optimization

; Error reporting for debugging in development, adjust for production
; error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
; display_errors = Off
; log_errors = On
; error_log = /var/log/php/php-error.log

MySQL/MariaDB Tuning for WooCommerce Data Loads

The database is often the bottleneck for dynamic content generation in WooCommerce. Tuning MySQL/MariaDB focuses on query optimization, efficient caching, and connection management.

InnoDB Buffer Pool

The InnoDB buffer pool is the most critical setting for InnoDB performance. It caches data and indexes. Aim to set `innodb_buffer_pool_size` to 50-75% of your server’s total RAM on a dedicated database server.

MySQL Configuration (`my.cnf` or `mysqld.cnf`)

[mysqld]
# General Settings
user                    = mysql
pid-file                = /var/run/mysqld/mysqld.pid
socket                  = /var/run/mysqld/mysqld.sock
port                    = 3306
basedir                 = /usr
datadir                 = /var/lib/mysql
tmpdir                  = /tmp
lc_messages_dir         = /usr/share/mysql
lc_messages             = en_US
skip-external-locking

# InnoDB Settings
default_storage_engine  = InnoDB
innodb_file_per_table   = 1 ; Recommended for better management and performance
innodb_flush_log_at_trx_commit = 1 ; For ACID compliance. Set to 2 for higher performance with slight risk on crash.
innodb_flush_method     = O_DIRECT ; Recommended for Linux with hardware RAID or SSDs

# Buffer Pool - CRITICAL for performance. Adjust based on available RAM.
# Example for a 16GB RAM server (adjust accordingly)
innodb_buffer_pool_size = 10G ; 10 Gigabytes

# Other InnoDB Tuning
innodb_log_file_size = 512M ; Adjust based on workload, larger can improve write performance
innodb_log_buffer_size = 16M
innodb_io_capacity = 2000 ; Adjust based on disk I/O capabilities (e.g., 200 for HDDs, 2000+ for SSDs)
innodb_io_capacity_max = 4000 ; Max value for IO capacity

# Query Cache (Deprecated in MySQL 5.7, removed in 8.0. Use application-level caching instead.)
# query_cache_type = 0
# query_cache_size = 0

# Connection Settings
max_connections         = 200 ; Adjust based on application needs and server resources
thread_cache_size       = 16
table_open_cache        = 2000
table_definition_cache  = 1000

# Sort and Join Buffers
sort_buffer_size        = 1M
join_buffer_size        = 1M
read_buffer_size        = 1M
read_rnd_buffer_size    = 2M

# Temporary Tables
tmp_table_size          = 64M
max_heap_table_size     = 64M

# Logging (Adjust for production)
# log_error = /var/log/mysql/error.log
# general_log = 0
# general_log_file = /var/log/mysql/mysql.log
# slow_query_log = 1
# slow_query_log_file = /var/log/mysql/mysql-slow.log
# long_query_time = 2 ; Log queries taking longer than 2 seconds

# Character Set
character-set-server    = utf8mb4
collation-server        = utf8mb4_unicode_ci

Query Optimization and Slow Query Log

Regularly analyze your slow query log to identify and optimize inefficient queries. WooCommerce and WordPress can generate complex queries, especially with many plugins or custom code. Use tools like `pt-query-digest` from Percona Toolkit for analysis.

Enabling and Analyzing Slow Query Log

Ensure `slow_query_log = 1` and `long_query_time` are set appropriately in your `my.cnf`. After enabling, monitor the log file (e.g., `/var/log/mysql/mysql-slow.log`).

# Install Percona Toolkit (example for Debian/Ubuntu)
sudo apt-get update
sudo apt-get install percona-toolkit

# Analyze the slow query log
sudo pt-query-digest /var/log/mysql/mysql-slow.log > /var/log/mysql/mysql-slow-report.txt

# Review the report for common problematic queries
less /var/log/mysql/mysql-slow-report.txt

OVH Specific Considerations

OVH’s infrastructure, particularly their Public Cloud instances, offers various storage options (e.g., SSD, NVMe). Ensure your MySQL data directory is on the fastest available storage. For managed database services (if used), consult OVH’s documentation for their specific tuning parameters and best practices.

Putting It All Together: Monitoring and Iteration

Performance tuning is an ongoing process. Implement robust monitoring for Nginx, PHP-FPM, and MySQL. Key metrics include:

  • Nginx: Active connections, requests per second, error rates (4xx, 5xx), upstream response times.
  • PHP-FPM: Process usage (active, idle, waiting), request duration, memory usage.
  • MySQL: Query throughput, slow queries, connection usage, buffer pool hit rate, disk I/O.

Tools like Prometheus with Node Exporter, Grafana for visualization, and specialized exporters for Nginx, PHP-FPM, and MySQL are invaluable. Regularly review these metrics after making configuration changes and iterate on your tuning strategy based on real-world performance data.

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

  • Step-by-Step: Diagnosing indexing lock conflicts and high CPU during bulk stock updates on DigitalOcean Servers
  • How to Debug and Fix memory leaks and socket exhaustion in daemon processes in Modern C++ Applications
  • Infrastructure as Code: Provisioning Secure PHP Clusters on DigitalOcean Using Terraform
  • Fixing Slow Largest Contentful Paint (LCP) caused by unoptimized database queries in Legacy Laravel Codebases Without Breaking API Contracts
  • An Auditor’s Checklist for Securing Laravel Backends on Google Cloud

Copyright © 2026 · Vinay Vengala