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

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

Nginx Configuration for Magento 2 on AWS

Optimizing Nginx is crucial for serving static assets efficiently and proxying dynamic requests to your Magento 2 application. On AWS, leveraging Elastic Load Balancers (ELBs) or Application Load Balancers (ALBs) in front of Nginx instances requires specific configurations to ensure proper health checks, SSL termination, and request routing.

SSL Termination and HTTP/2

When using an ALB for SSL termination, Nginx will receive unencrypted HTTP traffic. It’s essential to enable HTTP/2 for improved performance. If Nginx is directly exposed (less common in production AWS setups), you’d configure SSL here.

Here’s a sample Nginx configuration snippet for a server block, assuming traffic is coming from an ALB (port 80):

Example Nginx Server Block (from ALB)

server {
    listen 80 http2;
    server_name your-magento-domain.com;

    # Enable 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;

    # Define root and index files
    root /var/www/magento2/public_html;
    index index.php index.html index.htm;

    # Magento 2 specific location blocks
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # Static assets caching
    location ~* ^/(media|static)/ {
        expires 365d;
        add_header Cache-Control "public, immutable";
        access_log off;
        log_not_found off;
    }

    # PHP-FPM configuration (assuming FPM is running on a separate socket or port)
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Adjust PHP version and path
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_param MAGE_RUN_CODE "your_magento_store_code"; # Set your Magento store code
        fastcgi_param MAGE_RUN_TYPE "store"; # Or "website"
    }

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

    # Deny access to .git directory
    location ~ /\.git {
        deny all;
    }

    # Error pages
    error_page 404 /errors/404.php;
    error_page 500 502 503 504 /errors/50x.php;
}

Tuning Nginx Worker Processes and Connections

The worker_processes directive controls how many worker processes Nginx will spawn. Setting it to auto is often a good starting point, allowing Nginx to determine the optimal number based on CPU cores. worker_connections defines the maximum number of simultaneous connections that each worker process can handle.

Nginx Global Configuration Snippet

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 4096; # Adjust based on system limits and expected load
    multi_accept on;
}

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

    # Include other configurations
    include /etc/nginx/mime.types;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Tuning Considerations:

  • worker_processes: Set to auto or the number of CPU cores.
  • worker_connections: This is limited by the system’s file descriptor limit. Ensure ulimit -n is set high enough (e.g., 65536 or more) for the Nginx user.
  • keepalive_timeout: A shorter timeout can free up connections faster, but too short can increase overhead.
  • sendfile on;: Crucial for efficient file transfers.
  • tcp_nopush on; and tcp_nodelay on;: Optimize TCP packet sending.

Gunicorn/PHP-FPM Tuning for Magento 2

Magento 2 is a PHP application. The choice is typically between PHP-FPM (for Nginx) or Gunicorn (if using a Python-based framework or a reverse proxy setup for PHP, which is less common for direct Magento deployments).

PHP-FPM Tuning

PHP-FPM (FastCGI Process Manager) is the standard way to interface PHP with web servers like Nginx. Tuning its process management is critical for handling concurrent requests.

PHP-FPM Pool Configuration (`www.conf`)

The primary configuration file is usually located at /etc/php/8.1/fpm/pool.d/www.conf (adjust version and path as needed). The most important directives are related to process management.

; /etc/php/8.1/fpm/pool.d/www.conf

[www]
user = www-data
group = www-data
listen = /var/run/php/php8.1-fpm.sock ; Or a TCP port like 127.0.0.1:9000

; Process Manager Control
; pm = dynamic ; Options: static, dynamic, ondemand
pm = dynamic

; If pm.max_children is set to 'static', this is the number of child processes.
; If pm.max_children is set to 'dynamic' or 'ondemand', this is the maximum number of child processes that will be spawned.
pm.max_children = 100 ; Adjust based on available RAM and expected load

; If pm.max_children is set to 'dynamic', this is the desired number of child processes on average.
pm.min_spare_servers = 10 ; Adjust based on expected load fluctuations
pm.max_spare_servers = 20 ; Adjust based on expected load fluctuations

; If pm.max_children is set to 'ondemand', this is the number of child processes to be created on startup.
; pm.max_children = 5

; If pm.max_children is set to 'ondemand', this is the maximum number of child processes that will be spawned.
; pm.max_children = 10

; If pm.max_children is set to 'ondemand', this is the number of seconds each child process will live before being killed.
; pm.process_idle_timeout = 10s

; The number of requests each child process should execute before reexecuting.
; Setting this to 0 means infinite.
pm.max_requests = 500 ; Helps prevent memory leaks

; Other important settings
request_terminate_timeout = 60s ; Timeout for script execution
; rlimit_files = 1024 ; Adjust based on system limits
; rlimit_core = 0 ; Set to 0 to disable core dumps
; listen.owner = www-data
; listen.group = www-data
; listen.mode = 0660
; listen.acl =
; listen.backlog = -1
; pm.status_path = /status
; pm.ping.path = /ping
; pm.ping.response = pong
; pm.emergency_restart_threshold = 10
; pm.emergency_restart_interval = 10s
; pm.process_max = 128

Tuning Considerations:

  • pm: dynamic is generally recommended. static can offer slightly better performance but consumes more memory. ondemand is good for very low traffic but can have higher latency on initial requests.
  • pm.max_children: This is the most critical setting. It dictates how many PHP processes can run concurrently. Calculate this based on your server’s RAM. A rough estimate: (Total RAM - RAM for OS/Nginx/DB) / Average RAM per PHP process. Magento processes can be memory-intensive. Start conservatively and monitor.
  • pm.max_requests: Setting this prevents memory leaks from accumulating over time. A value between 250-1000 is common.
  • request_terminate_timeout: Ensure this is long enough for your longest-running Magento operations but not so long that it hangs indefinitely.

Gunicorn Tuning (If Applicable)

While not directly used for serving Magento 2 PHP, Gunicorn might be used in a microservices architecture or for other components. Its tuning focuses on worker processes and threads.

Example Gunicorn Command Line

gunicorn --workers 3 --threads 2 --bind 0.0.0.0:8000 myapp.wsgi:application

Tuning Considerations:

  • --workers: Typically set to (2 * number_of_cpu_cores) + 1.
  • --threads: For I/O-bound applications, increasing threads can improve concurrency.
  • --worker-class: Consider gevent or eventlet for asynchronous I/O.

Elasticsearch Tuning on AWS

Elasticsearch is vital for Magento 2’s catalog search and other features. Performance tuning involves JVM heap size, shard allocation, and indexing settings.

JVM Heap Size Configuration

The JVM heap size is configured in jvm.options, typically found in /etc/elasticsearch/jvm.options or similar paths depending on your installation method (e.g., Docker, package manager).

Example `jvm.options`

# /etc/elasticsearch/jvm.options

# Enable GC logging
-Xlog:gc*:file=/var/log/elasticsearch/gc.log:time,uptime,level,tags:filecount=32,filesize=64m

# Heap Size
# Set Xms and Xmx to the same value to prevent resizing
# Rule of thumb: No more than 50% of system RAM, and not exceeding 30-32GB.
-Xms4g
-Xmx4g

Tuning Considerations:

  • Set -Xms and -Xmx to the same value.
  • Allocate no more than 50% of the server’s RAM to the Elasticsearch heap.
  • Avoid exceeding 30-32GB due to compressed ordinary object pointers (compressed oops). If you need more than 32GB, consider alternative JVMs or architectures.
  • Monitor garbage collection (GC) activity. Frequent or long GC pauses indicate heap issues.

Shard Allocation and Indexing Settings

Proper shard management and indexing settings are crucial for search performance and stability.

Index Settings API Example

You can adjust settings dynamically using the Index Settings API. For Magento 2, the primary index is usually named `magento2`. You can check current settings with:

GET /magento2/_settings

To update settings (e.g., number of replicas, refresh interval):

PUT /magento2/_settings
{
  "index" : {
    "number_of_shards" : "5",
    "number_of_replicas" : "1",
    "refresh_interval" : "30s"
  }
}

Tuning Considerations:

  • number_of_shards: Should ideally match the number of data nodes in your cluster for even distribution. Too many shards can increase overhead. Magento’s default is often reasonable, but can be tuned.
  • number_of_replicas: Set to 1 for high availability. Increase for read-heavy workloads if performance is bottlenecked by read capacity.
  • refresh_interval: The default is 1s, making documents searchable almost immediately. For high-volume indexing, increasing this to 5s, 10s, or even 30s can significantly improve indexing throughput at the cost of slightly delayed search visibility.
  • Consider using Index Lifecycle Management (ILM) for managing indices over time, especially if you have time-series data or need to archive/delete old data.

AWS Specific Considerations

When deploying on AWS, leverage managed services and instance types optimized for your workload.

  • EC2 Instance Types: Choose instance types with sufficient vCPUs and RAM for Nginx, PHP-FPM, and Elasticsearch. Memory-optimized (R series) or compute-optimized (C series) instances are often suitable.
  • EBS Volumes: Use provisioned IOPS (io1/io2) or General Purpose SSD (gp3) volumes for Elasticsearch data directories to ensure consistent I/O performance.
  • Security Groups: Configure security groups to allow traffic only from necessary sources (e.g., ALB to Nginx, Nginx to PHP-FPM, application to Elasticsearch).
  • CloudWatch: Set up comprehensive monitoring for CPU utilization, memory usage, disk I/O, network traffic, and application-specific metrics (e.g., PHP-FPM active processes, Elasticsearch cluster health).
  • Elasticsearch Service (AWS Managed Elasticsearch): Consider using AWS Elasticsearch Service for managed Elasticsearch clusters. This offloads operational burden but requires careful configuration of instance types, storage, and access policies.

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

  • Leveraging PHP 8.3 JIT and FFI for High-Performance Microservices with Laravel Octane and Docker Swarm
  • Leveraging PHP 8.3 JIT and Vector API for Sub-Millisecond WordPress REST API Responses with Laravel Octane
  • Orchestrating Serverless PHP 9 with AWS Lambda and API Gateway: A Deep Dive into Performance and Cost Optimization
  • Leveraging PHP 8.3 JIT and Vectorization for Extreme Performance in Laravel Applications
  • Leveraging PHP 9’s JIT Compiler and Concurrent Execution for High-Performance Laravel Microservices

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (664)
  • Desktop Applications (14)
  • DevOps (11)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (6)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • Performance & Security Optimization (1)
  • PHP (20)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (10)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (650)
  • SEO & Growth (492)
  • Server (118)
  • Softwares (1)
  • Ubuntu (9)
  • Uncategorized (26)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (26)
  • WordPress Plugin Development (728)
  • WordPress Theme Development (357)

Recent Posts

  • Leveraging PHP 8.3 JIT and FFI for High-Performance Microservices with Laravel Octane and Docker Swarm
  • Leveraging PHP 8.3 JIT and Vector API for Sub-Millisecond WordPress REST API Responses with Laravel Octane
  • Orchestrating Serverless PHP 9 with AWS Lambda and API Gateway: A Deep Dive into Performance and Cost Optimization

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (728)
  • Debugging & Troubleshooting (664)
  • Security & Compliance (650)
  • SEO & Growth (492)

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