← All articles >
magento 2magento developmentperformance optimizationdevopsmagento cachinge-commercetutorial

Magento 2 Indexers Explained: Complete Developer Guide (2026)

Share: LinkedIn X Facebook

Magento 2 indexers keep your storefront fast by pre-computing data that would otherwise require expensive joins at runtime — product prices, stock status, category assignments, and search results. When indexers fall behind or get stuck, you see wrong prices, empty categories, and search that returns nothing. This guide explains how indexers work, how to manage them from the CLI, and how to keep them healthy in production.

In short: Indexers transform raw database data into optimized flat tables and search indexes. Run them on a schedule in production (Update on Schedule), monitor indexer_status, and never leave a store in Update on Save mode under real traffic.

Table of Contents

  1. What Are Magento 2 Indexers?
  2. Update on Save vs Update on Schedule
  3. Key Indexers Every Developer Should Know
  4. CLI Commands Reference
  5. How mview and Changelog Tables Work
  6. Troubleshooting Stuck or Invalid Indexers
  7. Performance Tuning for High-Traffic Stores
  8. Best Practices for Production
  9. Technical FAQ

What Are Magento 2 Indexers?

In Magento 2, many storefront operations rely on pre-computed data stored in flat tables and search indexes rather than live SQL queries across dozens of joined tables.

For example, when a customer views a category page, Magento reads from catalog_product_index_price and catalog_category_product_index instead of recalculating tier prices, special prices, and category rules on every request.

Without indexers: Every product listing would run complex price rules, inventory checks, and attribute lookups in real time — unacceptable at scale.

With indexers: Data is rebuilt in the background and served from optimized tables in milliseconds.

Product saved in Admin
        ↓
Changelog entry written (mview)
        ↓
Cron job picks up pending changes
        ↓
Indexer processes affected rows
        ↓
Flat tables / Elasticsearch updated
        ↓
Storefront serves fresh data

Update on Save vs Update on Schedule

Magento 2 supports two indexer modes, configured per indexer:

ModeBehaviorBest For
Update on SaveReindexes immediately when data changesLocal development, small catalogs
Update on ScheduleQueues changes; cron processes themProduction stores (always)

Switch all indexers to Update on Schedule

bin/magento indexer:set-mode schedule

Switch back to Update on Save (dev only)

bin/magento indexer:set-mode realtime

Production rule: Never use Update on Save on a live store. A single bulk import can trigger full reindexes that lock tables and spike CPU for minutes.


Key Indexers Every Developer Should Know

Indexer IDPurposeCommon Symptoms When Broken
catalog_product_priceFinal customer-facing prices (special, tier, catalog rules)Wrong prices on PLP/PDP
cataloginventory_stockSalable quantity per website/stock“Out of stock” when items exist
catalog_product_attributeEAV → flat attribute valuesMissing filters, blank attributes
catalog_category_productCategory ↔ product assignmentsProducts missing from categories
catalogsearch_fulltextSearch index (Elasticsearch/OpenSearch)Search returns no results
catalogrule_productCatalog price rulesPromotional prices not applied
inventoryMSI (Multi-Source Inventory) stock indexWrong stock per source/website

Check current status:

bin/magento indexer:status

Example output:

+----------------------------------+-------------+-----------+---------------------+---------------------+
| ID                               | Title       | Status    | Update On           | Schedule Status     |
+----------------------------------+-------------+-----------+---------------------+---------------------+
| catalog_product_price            | Product Price | Ready   | Schedule            | idle (0 in backlog) |
| catalogsearch_fulltext           | Catalog Search| Reindex required | Schedule | suspended           |
+----------------------------------+-------------+-----------+---------------------+---------------------+

CLI Commands Reference

Reindex everything

bin/magento indexer:reindex

Reindex a specific indexer

bin/magento indexer:reindex catalog_product_price
bin/magento indexer:reindex catalogsearch_fulltext

Reindex multiple indexers

bin/magento indexer:reindex catalog_product_price cataloginventory_stock

Reset an indexer (marks it invalid)

bin/magento indexer:reset catalog_product_price

Use reset when an indexer is stuck in Processing state before running reindex again.

Show indexer info

bin/magento indexer:info

Temporarily disable an indexer (advanced)

bin/magento indexer:set-dimensions-mode catalog_product_price none

Use dimension modes only when you understand MSI/website-scoped indexing — incorrect configuration can cause silent data mismatches.


How mview and Changelog Tables Work

When indexers run in Update on Schedule mode, Magento uses the Materialized View (mview) framework:

  1. A database trigger writes a row to a changelog table (e.g. catalog_product_price_cl) when source data changes.
  2. The indexer_update_all_views cron job reads pending changelog entries.
  3. The indexer processes only changed entity IDs — not the entire catalog.

Inspect changelog backlog

SELECT COUNT(*) FROM catalog_product_price_cl;
SELECT COUNT(*) FROM catalogsearch_fulltext_cl;

A growing backlog means cron is not keeping up. Check:

bin/magento cron:run --group=index
grep -i indexer var/log/cron.log
grep -i indexer var/log/system.log

Reset a suspended mview

bin/magento indexer:reset catalog_product_price
bin/magento cron:run --group=index

If the view stays suspended, check mview_state in the database:

SELECT * FROM mview_state WHERE view_id = 'catalog_product_price';

Set status = 'idle' only after confirming no indexer process is running — otherwise you risk duplicate processing.


Troubleshooting Stuck or Invalid Indexers

Symptom: Indexer stuck in “Processing”

Cause: A previous reindex was killed (OOM, timeout, manual kill).

Fix:

# Confirm no PHP process is still running
ps aux | grep indexer

# Reset and reindex
bin/magento indexer:reset catalog_product_price
bin/magento indexer:reindex catalog_product_price

If it persists, check for lock files:

ls -la var/locks/

Remove stale locks only when no indexer process is active.

Symptom: “Could not rebuild index for empty catalog”

Cause: Usually a data integrity issue — orphaned rows, missing attribute values, or corrupt EAV data.

Fix: Enable indexer logging and inspect the exception:

bin/magento indexer:reindex catalog_product_attribute -vvv

Then query for products with missing required attributes or broken category links.

Symptom: Search index out of sync

After bulk imports or Elasticsearch cluster restarts:

bin/magento indexer:reindex catalogsearch_fulltext
bin/magento cache:flush

Verify Elasticsearch connectivity:

curl -s http://localhost:9200/_cluster/health?pretty

Symptom: Prices wrong after catalog price rule change

Catalog rules require two indexers:

bin/magento indexer:reindex catalogrule_rule catalogrule_product catalog_product_price

Always reindex in dependency order — catalogrule_product before catalog_product_price.


Performance Tuning for High-Traffic Stores

1. Run indexers off-peak via cron

Ensure these cron groups are active in crontab:

* * * * * /usr/bin/php /var/www/html/bin/magento cron:run --group=index
* * * * * /usr/bin/php /var/www/html/bin/magento cron:run --group=default

2. Parallel reindexing (Magento 2.4.4+)

Magento supports parallel indexers for some types. Check env.php:

'indexer' => [
    'use_parallel' => true,
    'threads' => 4,
],

Increase threads based on available CPU — monitor memory usage; price indexing is memory-intensive.

3. Bulk operations: use the Bulk API

For large imports, use Magento’s Bulk API or Magento_Indexer mass actions rather than saving products one-by-one in Admin. Each save triggers changelog writes; batch operations reduce overhead.

4. Separate indexer workers (Adobe Commerce / custom setup)

On high-volume stores, run a dedicated cron worker for the index group:

bin/magento cron:run --group=index --bootstrap=standaloneProcessStarted=1

This prevents indexer jobs from competing with order processing crons.

5. Monitor backlog as a metric

Alert when changelog tables exceed a threshold (e.g. 10,000 rows). A growing backlog is an early warning before customers see stale data.


Best Practices for Production

  1. Always use Update on Schedule — never Update on Save on live stores.
  2. Reindex after deployments that touch di.xml, price rules, or attribute configuration.
  3. Never run indexer:reindex during peak traffic unless urgent — schedule maintenance windows.
  4. Verify cron is running — a silent cron failure is the #1 cause of stale storefront data.
  5. Check indexer status after bulk imports — import modules often skip automatic reindex.
  6. Keep Elasticsearch/OpenSearch healthy — search indexer failures cascade to empty SERP pages.
  7. Log and alert on Reindex required status — treat it like a production incident for catalog stores.

Post-deployment checklist

bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f
bin/magento indexer:reindex
bin/magento cache:flush
bin/magento indexer:status

Technical FAQ

How often should indexers run?

With Update on Schedule, the index cron group processes changelogs every minute. Full reindexes are only needed after major data changes or when status shows Reindex required.

Does cache:flush replace reindexing?

No. Cache flush clears block/FPC/config cache. Indexers rebuild database flat tables and search indexes — completely separate systems.

Can I disable an indexer I don’t use?

Some indexers (e.g. design_config_grid) are Admin-only and low impact. Never disable catalog_product_price, cataloginventory_stock, or catalogsearch_fulltext on a live storefront.

Why does reindexing use so much memory?

Price and catalog rule indexers load large product collections into memory. Increase PHP memory_limit for CLI (e.g. -d memory_limit=2G) and use parallel threads cautiously.

What’s the difference between indexer:reset and cache:clean?

indexer:reset marks an indexer as invalid so the next reindex runs from scratch. cache:clean only clears cached blocks and configuration — it does not rebuild index tables.


Conclusion

Magento 2 indexers are the backbone of storefront performance and data accuracy. Treat Update on Schedule + healthy cron as non-negotiable in production, monitor changelog backlogs, and know how to reset stuck indexers before they affect customers.

Need help tuning indexers or fixing a production indexing crisis? Get in touch — I work with Magento 2 and Adobe Commerce stores on performance optimization , DevOps, and custom module development.