• 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 » Eliminating Elasticsearch Bottlenecks: Tuning Queries for High-Performance Magento 2 Stores

Eliminating Elasticsearch Bottlenecks: Tuning Queries for High-Performance Magento 2 Stores

Understanding Elasticsearch Performance in Magento 2

Magento 2’s reliance on Elasticsearch for product catalog search, layered navigation, and other critical functionalities makes its performance directly impact user experience and conversion rates. When Elasticsearch becomes a bottleneck, it manifests as slow page loads, unresponsive search results, and timeouts. This isn’t typically due to Elasticsearch’s core engine but rather how it’s queried and configured within the Magento ecosystem. The primary culprits are often inefficient query structures, excessive data retrieval, and suboptimal cluster settings.

Diagnosing Elasticsearch Bottlenecks

Before tuning, accurate diagnosis is paramount. Elasticsearch provides extensive logging and monitoring capabilities. The first step is to enable slow query logging to identify specific queries that exceed a defined threshold. This is typically configured in the elasticsearch.yml file.

Enabling Slow Query Logging

Locate your Elasticsearch configuration directory (often /etc/elasticsearch/ or within your Magento installation’s vendor/magento/module-elasticsearch/etc/ for specific Magento settings). Modify elasticsearch.yml to include or adjust the following settings:

# In elasticsearch.yml
indices.query.slowlog.threshold: 10s
index.indexing.slowlog.threshold: 2s
action.search.slowlog.threshold: 5s
logger.org.elasticsearch.indices.indexing.slowlog: INFO
logger.org.elasticsearch.indices.search.slowlog: INFO

Restart your Elasticsearch service for these changes to take effect. Monitor the Elasticsearch logs (typically found in /var/log/elasticsearch/) for entries matching these slow logs. These logs will reveal the exact query DSL being executed, the time taken, and the shard it originated from.

Optimizing Magento 2 Elasticsearch Queries

Magento 2 generates complex Elasticsearch queries, especially for faceted navigation. These queries often involve multiple aggregations and filters. The goal is to simplify these queries where possible and ensure they are efficient.

Analyzing and Rewriting Product Collection Queries

Magento’s product collection is a frequent source of performance issues. The Magento\Elasticsearch\Model\Adapter\QueryBuilder is responsible for constructing these queries. While direct modification of this class is discouraged (due to upgrades), understanding its output is key. We can intercept and analyze these queries using Magento’s built-in debugging tools or custom observers.

Example: Intercepting and Logging Elasticsearch Queries

Create a plugin for Magento\Elasticsearch\Model\Adapter\QueryBuilder::build to log the generated query. This requires creating a custom module.

Module Structure:

app/code/Vendor/ElasticsearchLogger/
├── etc/
│   ├── module.xml
│   └── di.xml
└── Plugin/
    └── QueryBuilderPlugin.php

etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_ElasticsearchLogger" setup_version="1.0.0"></module>
</config>

etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Elasticsearch\Model\Adapter\QueryBuilder">
        <plugin name="vendor_elasticsearch_logger_query_builder"
                type="Vendor\ElasticsearchLogger\Plugin\QueryBuilderPlugin"
                sortOrder="10" />
    </type>
</config>

Plugin/QueryBuilderPlugin.php

<?php

namespace Vendor\ElasticsearchLogger\Plugin;

use Magento\Framework\App\ObjectManager;
use Psr\Log\LoggerInterface;

class QueryBuilderPlugin
{
    /**
     * @var LoggerInterface
     */
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    /**
     * Log the generated Elasticsearch query.
     *
     * @param \Magento\Elasticsearch\Model\Adapter\QueryBuilder $subject
     * @param array $result
     * @return array
     */
    public function afterBuild(\Magento\Elasticsearch\Model\Adapter\QueryBuilder $subject, array $result): array
    {
        // Log only if it's a search query to avoid excessive logging
        if (isset($result['body']['query'])) {
            $this->logger->debug(json_encode($result, JSON_PRETTY_PRINT));
        }
        return $result;
    }
}

After enabling this module and setting your logging level to DEBUG (in app/etc/env.php), you can find the logged queries in var/log/debug.log. Analyze these queries for common patterns of inefficiency.

Common Inefficiencies and Solutions

  • Excessive `_source` fields: By default, Elasticsearch returns the entire document (`_source`). If you only need a few fields, explicitly specify them using the _source parameter in the query. Magento’s query builder might not always do this optimally.
  • Deep Pagination: Queries with very large `from` and `size` values are extremely inefficient. Elasticsearch uses a “deep pagination” approach that requires significant resources. Use search_after for true deep pagination if absolutely necessary, or redesign the UI to avoid it.
  • Complex Aggregations: Overlapping or redundant aggregations, especially on high-cardinality fields, can be costly.
  • Wildcard Queries: Leading wildcards (e.g., *term) are notoriously slow as they require scanning many terms.
  • `script` queries: Scripts are powerful but can be a performance drain.

Tuning Aggregations for Layered Navigation

Layered navigation often generates queries with multiple `terms` aggregations. If you have many attributes or attributes with many unique values, this can strain Elasticsearch. Consider:

  • Reducing the number of filterable attributes: Only make attributes that are frequently used for filtering available in layered navigation.
  • Using `composite` aggregations: For complex scenarios, `composite` aggregations can be more efficient than multiple independent `terms` aggregations.
  • `terms` aggregation `execution_hint`: For specific use cases, setting execution_hint: map can sometimes improve performance for `terms` aggregations.

Optimizing Elasticsearch Cluster Settings

Beyond query tuning, the Elasticsearch cluster configuration itself plays a vital role. These settings are managed in elasticsearch.yml on each node.

JVM Heap Size

This is arguably the most critical setting. Elasticsearch is JVM-based, and insufficient heap can lead to frequent garbage collection pauses and OutOfMemory errors. A common recommendation is to set it to 50% of the system’s RAM, but not exceeding 30-31GB (due to compressed ordinary object pointers). This is configured in jvm.options (or jvm.options.d/ directory).

# In jvm.options
-Xms4g
-Xmx4g

Adjust 4g based on your server’s RAM. Restart Elasticsearch after changes.

Shard Allocation and Sizing

Magento 2 typically creates one index per store view. Each index has primary shards. The number of shards impacts performance: too few can lead to large shards that are slow to manage, while too many can increase overhead. Magento’s default is often 1 primary shard per index. For very large catalogs, consider increasing this, but be mindful of the overhead. The number of replicas (index.number_of_replicas) affects read performance and resilience. For a single-node setup, set replicas to 0. For multi-node, 1 or 2 is common.

Circuit Breakers

Elasticsearch uses circuit breakers to prevent requests that would consume too much memory. If you see “CircuitBreakerException” in your logs, it indicates memory pressure. You might need to increase the JVM heap or tune queries. Be cautious when increasing circuit breaker limits, as it can lead to instability.

# In elasticsearch.yml
indices.breaker.total.limit: 85% # Default is 70%
indices.breaker.fielddata.limit: 80% # Default is 70%
indices.breaker.request.limit: 85% # Default is 70%

Index Refresh Interval

The refresh interval (index.refresh_interval) controls how often changes become visible to search. The default is 1 second. For high-volume indexing (e.g., during imports or updates), increasing this to 30s or even 60s can significantly reduce indexing load. For read-heavy sites, the default is usually fine.

# In elasticsearch.yml or via Index API
index.refresh_interval: 30s

Magento 2 Specific Configurations

Magento’s configuration for Elasticsearch is managed via app/etc/env.php and the Admin Panel. Ensure these are set appropriately.

app/etc/env.php Settings

The Elasticsearch connection details and some basic settings are defined here. Pay attention to the index_prefix and timeout.

'indexer' => [
    'elasticsearch' => [
        'indexer_elasticsearch_client' => [
            'host' => 'localhost',
            'port' => '9200',
            'timeout' => 15, // Increase if you experience timeouts during indexing or complex searches
            'index_prefix' => 'magento2',
            'enable_auth' => '0', // Set to '1' if using authentication
            'username' => '',
            'password' => '',
            'scheme' => 'tcp',
            'http_compression' => '1' // Enable HTTP compression
        ]
    ]
],

Admin Panel Configuration

Navigate to Stores > Configuration > Catalog > Catalog Search. Here you can configure:

  • Search Engine: Ensure Elasticsearch is selected.
  • Elasticsearch Server Options: Host, Port, Index Name, Timeout.
  • Advanced Search Options: Enable spellcheck, suggestions, etc. These features add overhead and should be enabled only if necessary and tested for performance impact.

Re-indexing Strategies

Re-indexing is a critical operation that can heavily load Elasticsearch. Magento’s default re-indexing can be slow. Consider these strategies:

  • Schedule re-indexing during off-peak hours.
  • Use the --optimize-concurrency flag for Magento CLI commands (available in newer versions) to improve indexing performance.
  • For large catalogs, consider partial re-indexing if possible, though Magento’s built-in support for this is limited.
  • Monitor Elasticsearch cluster health during re-indexing.
# Example of optimized re-indexing
bin/magento indexer:reindex --optimize-concurrency

Conclusion

Eliminating Elasticsearch bottlenecks in Magento 2 is an ongoing process of monitoring, diagnosing, and tuning. By understanding the queries Magento generates, optimizing Elasticsearch cluster settings, and employing smart re-indexing strategies, you can significantly improve search performance, leading to a better customer experience and higher conversions. Always test changes in a staging environment before deploying to production.

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

  • 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
  • Leveraging PHP 8.3 JIT and Vectorization for High-Throughput Microservices in a Laravel Ecosystem
  • Leveraging Laravel Octane and Docker Swarm for High-Performance, Scalable WordPress Headless Deployments

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)
  • PHP (19)
  • 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 (24)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (26)
  • WordPress Plugin Development (728)
  • WordPress Theme Development (357)

Recent Posts

  • 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

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