• 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 Elasticsearch on AWS for WooCommerce

The Ultimate DevOps Playbook: Tuning Nginx, Gunicorn/FPM, and Elasticsearch on AWS for WooCommerce

Nginx Tuning for High-Traffic WooCommerce

Optimizing Nginx is paramount for serving static assets, handling SSL termination, and acting as a reverse proxy for your WooCommerce application. On AWS, leveraging EC2 instances with appropriate instance types (e.g., compute-optimized or memory-optimized) is the first step. Beyond instance selection, fine-tuning Nginx configuration parameters directly impacts performance and resource utilization.

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 on your instance. For I/O-bound workloads, setting it to ‘auto’ allows Nginx to determine the optimal number based on CPU cores. The worker_connections directive defines the maximum number of simultaneous connections that each worker process can handle. This value, multiplied by worker_processes, gives you the total maximum connections Nginx can manage. Ensure this value is sufficiently high to avoid connection exhaustion, but not so high that it leads to excessive memory consumption or context switching overhead.

Example Nginx Configuration Snippet

worker_processes auto; # Or set to the number of CPU cores
worker_connections 4096; # Adjust based on expected load and memory
multi_accept on;

events {
    worker_connections 4096;
    use epoll; # For Linux systems, epoll is generally preferred for high concurrency
}

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

    # Gzip compression for static assets and API responses
    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;

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

    # Proxy to Gunicorn/PHP-FPM
    location / {
        proxy_pass http://your_app_backend; # e.g., http://127.0.0.1:8000 or unix:/path/to/socket.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_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s; # Increase timeout for potentially long requests
        proxy_connect_timeout 75s;
    }

    # ... other http configurations ...
}

SSL/TLS Optimization

For SSL/TLS, leverage modern protocols and ciphers, and enable session caching/resumption to reduce handshake overhead for returning clients. AWS Certificate Manager (ACM) is highly recommended for managing SSL certificates, as it integrates seamlessly with Elastic Load Balancers (ELBs) and CloudFront, offloading SSL termination from your Nginx instances.

SSL Configuration Example

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; # 10MB shared cache
ssl_session_timeout 10m;
ssl_session_tickets off; # Consider enabling if performance is critical and security implications are understood

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s; # Use public DNS or your VPC's DNS resolver
resolver_timeout 5s;

Gunicorn/PHP-FPM Tuning for Application Performance

The application server (Gunicorn for Python/Django/Flask, or PHP-FPM for PHP) is where your WooCommerce logic executes. Tuning these servers is critical for handling application requests efficiently.

Gunicorn Tuning (Python)

Gunicorn’s performance is heavily influenced by its worker class, number of workers, and timeouts. For I/O-bound applications like WooCommerce, the gevent or eventlet worker classes are often preferred due to their asynchronous nature, allowing a single process to handle many concurrent connections efficiently. The number of workers is typically set to (2 * number_of_cores) + 1 as a starting point, but this can vary significantly based on application memory usage and I/O patterns. Adjusting --timeout and --keepalive can also prevent premature request termination.

Example Gunicorn Command Line

gunicorn --workers 3 \
         --worker-class gevent \
         --bind 0.0.0.0:8000 \
         --timeout 120 \
         --keepalive 60 \
         your_project.wsgi:application

Explanation:

  • --workers 3: Start with 3 worker processes. Adjust based on your instance’s CPU and memory.
  • --worker-class gevent: Use the gevent worker class for asynchronous I/O.
  • --bind 0.0.0.0:8000: Bind to all network interfaces on port 8000.
  • --timeout 120: Set request timeout to 120 seconds.
  • --keepalive 60: Keep connections alive for 60 seconds.

PHP-FPM Tuning (PHP)

PHP-FPM offers several process management strategies: static, dynamic, and ondemand. For high-traffic sites, dynamic or static are generally recommended. dynamic allows FPM to scale the number of child processes based on load, while static pre-forks a fixed number of processes. The key parameters are pm.max_children (maximum number of child processes), pm.start_servers (number of children to start), pm.min_spare_servers (minimum idle processes), and pm.max_spare_servers (maximum idle processes). For static, pm.max_children is the primary setting.

Example PHP-FPM Configuration (www.conf)

; /etc/php/8.1/fpm/pool.d/www.conf (example path)
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock ; Or a TCP/IP socket like 127.0.0.1:9000

; Process Manager settings
pm = dynamic
pm.max_children = 100       ; Adjust based on memory and CPU
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500       ; Restart child processes after this many requests

; Other settings
request_terminate_timeout = 120s
; ... other php settings ...

Tuning `pm.max_children`: This is the most critical setting. A common formula is (Total RAM - RAM for OS/Nginx) / Average RAM per PHP-FPM process. Monitor memory usage closely. If you see OOM killer activity, reduce this value. If your server is consistently underutilized, you might increase it.

Elasticsearch Tuning for WooCommerce Search

Elasticsearch is often used for advanced search capabilities in WooCommerce. Optimizing its performance involves JVM heap size, shard allocation, and query optimization.

JVM Heap Size

The Java Virtual Machine (JVM) heap size is crucial. It’s recommended to set Xms and Xmx to the same value to prevent heap resizing. A common guideline is to allocate no more than 50% of the system’s RAM to the JVM heap, and never exceed 30-32GB due to compressed ordinary object pointers (compressed oops). On AWS, choose instance types with sufficient RAM (e.g., memory-optimized R-series).

Example Elasticsearch JVM Settings

# /etc/elasticsearch/jvm.options (example path)
-Xms8g
-Xmx8g
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+AlwaysPreTouch

Note: The specific GC settings might vary based on Elasticsearch version and JVM. Always consult the official Elasticsearch documentation for your version.

Shard Allocation and Indexing Strategy

For WooCommerce, consider the number of primary shards per index. Too many shards can increase overhead. A common strategy is to have one primary shard per GB of data, but for WooCommerce, especially if using a plugin like “ElasticPress,” you might start with a smaller number of shards (e.g., 1-3 primary shards per index) and scale up if necessary. Ensure your indices are configured with appropriate replicas for high availability and read performance.

Example Index Settings (via API)

{
  "settings": {
    "index": {
      "number_of_shards": 3,
      "number_of_replicas": 1
    }
  }
}

When creating or updating indices, use the Elasticsearch Index Management APIs. For WooCommerce, this often involves managing product indices, order indices, etc. Monitor shard health and rebalancing operations. AWS Elasticsearch Service (now OpenSearch Service) provides managed options that simplify many of these configurations.

Query Optimization

Slow Elasticsearch queries can cripple WooCommerce. Analyze slow query logs and optimize queries. For WooCommerce, common slow queries might involve complex product filtering, faceted search, or order lookups. Use the profile API to understand query execution plans. Avoid leading wildcards in `wildcard` queries and prefer `match` or `multi_match` queries with appropriate analyzers. Ensure your mapping is optimized for search (e.g., using `keyword` for exact matches and `text` with appropriate analyzers for full-text search).

Example of Profiling a Query

GET /your_index/_search
{
  "profile": true,
  "query": {
    "match": {
      "product_name": "example product"
    }
  }
}

The output of the profile API will detail the time spent in different query phases, helping you pinpoint bottlenecks.

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