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

Vengala Vinay

Having 12+ Years of Experience in Software Development

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

The Ultimate DevOps Playbook: Tuning Nginx, Gunicorn/FPM, and Redis on OVH for Magento 2

Nginx Configuration for Magento 2 on OVH

Optimizing Nginx is paramount for serving Magento 2 efficiently, especially on OVH infrastructure where resource allocation and network latency are key considerations. We’ll focus on directives that directly impact request handling, caching, and static file delivery.

Core Nginx Performance Directives

The nginx.conf file, typically located at /etc/nginx/nginx.conf or within /etc/nginx/conf.d/, is the primary configuration point. Ensure your worker_processes directive is set to the number of CPU cores available. For a typical OVH VPS with 4 cores, this would be:

worker_processes 4;
# Or auto to let Nginx decide
# worker_processes auto;

The worker_connections directive controls 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 expected load and system limits. Ensure your system’s file descriptor limit (ulimit -n) is high enough to accommodate this.

events {
    worker_connections 4096; # Increased from default 1024
    multi_accept on;
}

Magento 2 Specific Nginx Configuration

Magento 2 requires specific Nginx configurations for static file serving, caching, and proxying to the PHP-FPM or Gunicorn backend. The recommended configuration is usually provided by Magento or third-party modules, but understanding the key components is crucial.

Static File Serving and Caching

Leveraging Nginx’s ability to serve static files directly is a significant performance win. Configure aggressive caching for static assets like CSS, JS, and images. The expires directive controls the Cache-Control and Expires headers.

location ~ ^/(media|static)/ {
    expires 30d; # Cache static assets for 30 days
    add_header Cache-Control "public, immutable";
    access_log off; # Optionally disable access logs for static files
    try_files $uri $uri/ /index.php?$args; # Fallback for dynamic content if file not found
}

For the static directory, Magento generates files. Ensure the try_files directive correctly points to the PHP handler if a static file is not found, allowing Magento to serve it dynamically.

Proxying to PHP-FPM/Gunicorn

The core of Magento 2’s dynamic content is handled by PHP-FPM (for PHP) or Gunicorn (for Python-based frameworks, though less common for Magento). Nginx acts as a reverse proxy. Key directives include proxy_pass, proxy_set_header, and timeouts.

location ~ \.php$ {
    # For PHP-FPM
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # Adjust PHP version and path as needed
    fastcgi_read_timeout 300; # Increase timeout for long-running PHP scripts

    # For Gunicorn (if applicable)
    # proxy_pass http://unix:/var/run/gunicorn.sock;
    # proxy_set_header Host $host;
    # proxy_set_header X-Real-IP $remote_addr;
    # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # proxy_read_timeout 300s;
    # proxy_connect_timeout 75s;
    # proxy_send_timeout 300s;
}

For PHP-FPM, fastcgi_read_timeout is crucial. Magento operations like indexing or complex product imports can take a long time. Setting this to 300 seconds (5 minutes) is a reasonable starting point.

Buffering and Timeouts

Disable client request body buffering if you encounter issues with large uploads or POST requests. Adjust proxy timeouts to prevent premature disconnections during long operations.

proxy_buffering off;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;

Gunicorn Configuration for Magento 2 (if applicable)

While Magento 2 is primarily PHP-based, some custom setups or related services might use Python with Gunicorn. The configuration focuses on worker processes, threads, and binding.

Gunicorn Worker Processes and Threads

The number of worker processes should generally be (2 * number_of_cores) + 1. Threads can be used to handle more concurrent requests per worker, but can also increase memory usage. Start with a conservative number of threads.

# Example command line for Gunicorn
gunicorn --workers 5 --threads 2 --bind unix:/var/run/gunicorn.sock myapp:app

For a 4-core CPU, 5 workers is a good starting point. If using threads, 2 threads per worker is a common balance.

Gunicorn Timeouts

Similar to Nginx, Gunicorn has its own timeout settings. These should be aligned with Nginx’s proxy timeouts to avoid conflicts.

# Example command line with timeouts
gunicorn --workers 5 --threads 2 --bind unix:/var/run/gunicorn.sock --timeout 300 myapp:app

The --timeout 300 directive sets the worker timeout to 300 seconds.

Redis Configuration for Magento 2 Caching

Redis is essential for Magento 2’s caching mechanisms (sessions, cache types). Tuning Redis involves memory management, persistence, and network settings.

Memory Management

The maxmemory directive is critical. Set it to a value that leaves sufficient RAM for the OS and other services. Magento can consume significant memory, especially during high traffic or intensive operations.

# redis.conf
maxmemory 2gb # Adjust based on available RAM and Magento's needs
maxmemory-policy allkeys-lru # Eviction policy: LRU is generally good for Magento cache

The maxmemory-policy determines how Redis evicts keys when maxmemory is reached. allkeys-lru (Least Recently Used) is a common and effective choice for caching scenarios.

Persistence and RDB/AOF

For caching purposes, disabling or minimizing persistence is often preferred to reduce I/O overhead. If you need persistence for other reasons, configure it carefully.

# redis.conf
save "" # Disable RDB snapshots if Redis is purely for cache and sessions
appendonly no # Disable AOF if not needed for durability

If persistence is required, consider the trade-offs. RDB snapshots are more compact but can cause latency during saving. AOF logs every write operation, providing better durability but potentially larger files and higher I/O.

Network and Client Settings

Ensure Redis is accessible only from trusted sources. Binding to a specific IP or using a Unix socket can enhance security. Adjust client timeouts if necessary.

# redis.conf
bind 127.0.0.1 # Bind to localhost if Nginx/PHP-FPM are on the same server
# Or use a Unix socket for local communication
# unixsocket /var/run/redis/redis-server.sock
# unixsocketperm 770

tcp-keepalive 300 # Adjust keepalive for long-lived connections

If using a Unix socket, ensure the user running Nginx/PHP-FPM has the correct permissions to access it (e.g., by adding them to the redis group).

Monitoring and Diagnostics

Continuous monitoring is key to identifying bottlenecks. Use tools like htop, netdata, Prometheus/Grafana, and Redis-specific commands.

Nginx Diagnostics

Check Nginx error logs (/var/log/nginx/error.log) for common issues like upstream connection failures or timeouts. Use nginx -t to test configuration changes before reloading.

# Test Nginx configuration
sudo nginx -t

# Reload Nginx gracefully
sudo systemctl reload nginx

PHP-FPM/Gunicorn Diagnostics

Monitor PHP-FPM logs (e.g., /var/log/php7.4-fpm.log) for errors and slow script execution. For Gunicorn, check its stdout/stderr logs.

# Example: Check PHP-FPM slow log (if enabled)
sudo tail -f /var/log/php7.4-fpm/slow.log

Redis Diagnostics

Use Redis CLI commands to inspect memory usage, cache hit rates, and latency.

# Connect to Redis CLI
redis-cli

# Check memory usage
INFO memory

# Check cache hit rate (requires monitoring over time)
INFO stats

# Monitor latency (run in a separate terminal)
redis-cli --latency-history -h your_redis_host -p your_redis_port

For OVH environments, pay close attention to network latency between your application server and Redis if they are on different instances. Consider placing them within the same OVH network zone for reduced latency.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Go Goroutines vs. Node.js Event Loop: Scaling I/O-Bound Microservices Under High Load
  • Elixir Phoenix vs. Go Gin: Concurrency Models and Fault Tolerance Under Peak Request Volume
  • Python Celery vs. Go Channels: Distributed Task Queue Overhead and Memory Reliability
  • Scala Pekko vs. Go Goroutines: Actor Model vs. CSP for Event-Driven Reactive Systems
  • Java Loom Virtual Threads vs. Go Goroutines: Under-the-Hood Scheduler and Thread Overhead Comparison

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (584)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (806)
  • PHP (5)
  • PHP Development (21)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (19)
  • Ruby on Rails (1)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (7)
  • WordPress Theme Development (357)

Recent Posts

  • Go Goroutines vs. Node.js Event Loop: Scaling I/O-Bound Microservices Under High Load
  • Elixir Phoenix vs. Go Gin: Concurrency Models and Fault Tolerance Under Peak Request Volume
  • Python Celery vs. Go Channels: Distributed Task Queue Overhead and Memory Reliability

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (806)
  • Debugging & Troubleshooting (584)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala