• 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 MongoDB on DigitalOcean for Magento 2

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

Nginx Configuration for Magento 2 Performance

Optimizing Nginx is crucial for serving Magento 2 efficiently. We’ll focus on key directives that impact request handling, caching, and resource utilization. This assumes a standard DigitalOcean droplet setup with Nginx installed.

Worker Processes and Connections

The worker_processes directive dictates how many worker processes Nginx will spawn. Setting this to auto is generally recommended, allowing Nginx to determine the optimal number based on available CPU cores. worker_connections defines the maximum number of simultaneous connections a worker process can handle. A common starting point is 1024, but this can be increased based on anticipated traffic.

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

user www-data;
worker_processes auto;
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
}

Gzip Compression

Enabling Gzip compression significantly reduces the size of static and dynamic content sent to the client, improving load times. Configure it within the http block.

http {
    # ... other http configurations

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6; # Compression level (1-9)
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
}

Browser Caching

Leverage browser caching for static assets to reduce server load and improve perceived performance for repeat visitors. This is typically configured within your Magento 2 site’s server block.

server {
    # ... other server configurations

    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|eot|otf|ttf|woff|woff2)$ {
        expires 30d; # Cache for 30 days
        add_header Cache-Control "public, no-transform";
        access_log off;
    }

    # ... other location blocks
}

PHP-FPM Configuration (for PHP-FPM setup)

If you’re using PHP-FPM to serve your Magento 2 application, tuning its process manager is critical. We’ll focus on the pm.max_children, pm.start_servers, pm.min_spare_servers, and pm.max_spare_servers directives. These control how PHP-FPM manages its worker processes.

Locate your PHP-FPM pool configuration file. For PHP 8.1, this is often /etc/php/8.1/fpm/pool.d/www.conf. Adjust the values based on your server’s RAM. A common rule of thumb is to set pm.max_children such that the total memory usage of all child processes does not exceed 70-80% of your server’s available RAM.

[global]
pid = /run/php/php8.1-fpm.pid
error_log = /var/log/php8.1-fpm.log
log_level = notice

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

pm = dynamic
pm.max_children = 100      ; Adjust based on RAM. Example: 100 processes * ~30MB/process = ~3GB RAM usage.
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.process_idle_timeout = 10s
pm.max_requests = 500      ; Restart child processes after this many requests to prevent memory leaks.

access.log = /var/log/php8.1-fpm.access.log
access.format = "%R - %u %t \"%m %r%q%Q\" %s %O \"%{Referer}i\" \"%{User-Agent}i\""

slowlog = /var/log/php8.1-fpm.slow.log
request_slowlog_timeout = 10s

catch_workers_output = yes

After modifying the PHP-FPM configuration, restart the service:

sudo systemctl restart php8.1-fpm

Gunicorn Configuration (for Gunicorn setup)

If you’re using Gunicorn as your Python WSGI HTTP Server, tuning its worker count and type is essential. For Magento 2, which is PHP-based, Gunicorn is not typically used directly. However, if you have a microservice or a separate Python component that interacts with Magento, here’s a typical Gunicorn tuning example.

The number of workers is often calculated as (2 * number_of_cores) + 1. The worker class can be sync (default, blocking) or gevent/eventlet (asynchronous, non-blocking) for I/O-bound tasks.

# Example command line for starting Gunicorn
# Assuming 4 CPU cores
gunicorn --workers 9 --worker-class gevent --bind 0.0.0.0:8000 myapp.wsgi:application

For a production deployment, you’d typically manage Gunicorn with a process manager like systemd.

[Unit]
Description=Gunicorn instance to serve myapp
After=network.target

[Service]
User=myappuser
Group=www-data
WorkingDirectory=/path/to/your/myapp
ExecStart=/path/to/your/venv/bin/gunicorn --workers 9 --worker-class gevent --bind unix:/run/gunicorn.sock myapp.wsgi:application

[Install]
WantedBy=multi-user.target

MongoDB Performance Tuning

MongoDB’s performance is heavily influenced by its configuration, indexing, and hardware. For Magento 2, MongoDB is often used for session storage, caching, and sometimes for specific features like the Page Builder. We’ll focus on server configuration and basic indexing strategies.

MongoDB Configuration File

The primary configuration file is mongod.conf, typically located at /etc/mongod.conf. Key parameters include:

  • storage.engine: For modern MongoDB versions, wiredTiger is the default and recommended engine.
  • storage.wiredTiger.engineConfig.cacheSizeGB: This is critical. Allocate a significant portion of your server’s RAM to the WiredTiger cache. A common recommendation is 50-75% of available RAM, leaving enough for the OS and other processes.
  • operationProfiling.mode: Set to slowOp or all for profiling slow queries.
  • net.bindIp: Ensure it’s set to bind to the correct network interface (e.g., 0.0.0.0 for all interfaces, or a specific private IP).
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 4 # Example: For an 8GB RAM server, leave 4GB for OS/other services.
operationProfiling:
  mode: slowOp # Or 'all' for more detailed profiling
  slowOpThresholdMs: 100
net:
  port: 27017
  bindIp: 0.0.0.0 # Or your specific private IP

After modifying mongod.conf, restart MongoDB:

sudo systemctl restart mongod

Indexing Strategies

Proper indexing is paramount for MongoDB performance. Magento 2’s session and cache collections can become bottlenecks if not indexed correctly. Use the MongoDB shell to inspect and create indexes.

Connect to your MongoDB instance:

mongo

Example: Indexing the Magento session collection (assuming your database is named magento_db):

use magento_db;
db.sessions.createIndex( { "id": 1 }, { unique: true, expireAfterSeconds: 1800 } ); // Index for session ID with TTL
db.sessions.createIndex( { "modified": 1 } ); // Index for session modification time

For cache collections, the specific fields to index depend on your Magento configuration (e.g., cache type, tags). Inspect your application’s usage patterns.

Monitoring and Diagnostics

Continuous monitoring is key to identifying performance regressions. Utilize tools like:

  • Nginx: Access logs, error logs, nginx -s reload for configuration reloads, htop for process monitoring.
  • PHP-FPM: Slow log, error log, php-fpm -t for configuration test, systemctl status phpX.Y-fpm.
  • Gunicorn: Application logs, systemctl status gunicorn.
  • MongoDB: mongostat, mongotop, slow query logs, db.serverStatus(), db.stats().
  • System: htop, iotop, vmstat, dmesg.

For Nginx, consider enabling the stub_status module for real-time connection metrics:

http {
    # ... other http configurations

    server {
        listen 80;
        server_name your_domain.com;

        location /nginx_status {
            stub_status;
            allow 127.0.0.1; # Restrict access to localhost
            deny all;
        }

        # ... other Magento configurations
    }
}

Access http://your_domain.com/nginx_status to see metrics like active connections, accepted connections, handled connections, and requests.

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