Magento 2 Indexers Explained: Types, Modes & Troubleshooting

If you have ever run bin/magento indexer:status and stared at a wall of “invalid” or “working” statuses, you already know that Magento 2’s indexer system is both essential and sometimes mysterious. This guide cuts through that mystery: what each indexer actually does, which update mode to choose, how the changelog mechanism works under the hood, and the exact steps to diagnose and fix the most common indexer problems.

What Is an Indexer in Magento 2?

Magento stores raw data in normalized relational tables — products, prices, attributes, stock levels. Querying that raw data in real time for every storefront request would be brutally slow. Indexers solve this by pre-computing derived data and storing it in flat, optimized tables that the frontend reads directly.

Think of indexers as the layer between your admin edits and what customers actually see. When you change a product price, that change does not immediately appear in the flat price table — the indexer has to run first and propagate the new value.


All Magento 2 Indexer Types Explained

Magento 2.4.x ships with eleven indexers by default. Here is every one of them, with its indexer code and what it builds:

1. catalog_category_product

Builds the mapping between categories and their assigned products. Used by category pages to know which products belong to which category. Any change to category assignment or category hierarchy triggers this.

2. catalog_product_category

The reverse of the above — maps each product to its parent categories. Used for breadcrumbs and layered navigation.

3. catalog_product_attribute

Flattens EAV product attribute data into a single flat table (catalog_product_flat_*). This makes storefront product queries dramatically faster because instead of doing dozens of EAV joins, Magento reads one row per product. Requires the Flat Product setting to be enabled in admin (Stores > Configuration > Catalog > Storefront > Use Flat Catalog Product).

4. catalog_product_price

Computes the final price for every product across every customer group, website, and currency. This includes tier prices, special prices, catalog price rules, and tax. The output lands in catalog_product_index_price. This is typically the most expensive indexer to run because of the permutations involved.

5. cataloginventory_stock

Rebuilds stock status for all products, combining source stock (MSI) data with salability rules. Without a valid stock index, “In Stock / Out of Stock” labels and add-to-cart availability are unreliable.

6. catalogrule_rule

Applies catalog price rules to products and writes the results to catalogrule_product and catalogrule_product_price. This runs automatically at midnight via cron but must be forced manually after rule changes.

7. catalogrule_product

Depends on catalogrule_rule. Calculates the discounted prices per product after rules are applied and feeds those values into the price index.

8. catalogsearch_fulltext

Builds the search index inside Elasticsearch or OpenSearch. Every change to a product’s name, SKU, description, or searchable attributes must be indexed here before the product appears in search results or layered navigation.

9. design_config_grid

Indexes design configuration data (themes, header/footer settings) for display in the admin design grid. Rarely a performance concern.

10. customer_grid

Flattens customer data for the admin customer grid (Customers > All Customers). Does not affect the storefront.

11. catalog_product_flat (optional)

A secondary flat table indexer, separate from catalog_product_attribute. It enables fast attribute queries across all product types when flat catalog is on.


The Two Update Modes

Every indexer operates in one of two modes. You can check them all at once with:

bin/magento indexer:status

Update on Save

bin/magento indexer:set-mode realtime catalogsearch_fulltext

In this mode, Magento re-indexes immediately whenever relevant data changes — the moment you save a product, update a price, or assign a category. For small stores with low admin traffic, this is convenient: the storefront is always current.

The downside is that every save triggers a potentially expensive reindex operation synchronously, making admin saves slow and causing timeouts on bulk imports.

Update by Schedule (Recommended for Production)

bin/magento indexer:set-mode schedule catalogsearch_fulltext

In schedule mode, Magento records what changed — not the full reindex — into a changelog table, then processes those changes asynchronously via cron.

How the Changelog Mechanism Works

Every indexer in schedule mode gets a pair of changelog tables in the database. For example, catalog_product_price gets:

  • catalog_product_index_price_cl — the changelog table
  • A database trigger on catalog_product_entity that inserts the entity_id of any modified product into the changelog table on UPDATE

When cron runs indexer:reindex, Magento reads the changelog, processes only the affected entity IDs, and removes them from the log. This means that if 3 products changed since the last cron run, only those 3 products are reindexed — not your entire catalog of 50,000 SKUs.

To verify changelog tables exist for all schedule-mode indexers:

SHOW TABLES LIKE '%_cl';

If changelog tables are missing, re-running bin/magento setup:upgrade will recreate them.


Choosing the Right Mode Per Indexer

Not all indexers benefit equally from each mode. Here is a practical guide:

Indexer Recommended Mode Reason
catalog_product_price Schedule Expensive; slow on every save
catalogsearch_fulltext Schedule ES/OS writes are costly
cataloginventory_stock Schedule Bulk imports need async
catalog_product_attribute Schedule Flat rebuild is heavy
catalog_category_product Schedule Tree changes are infrequent
customer_grid Realtime Admin-only; low volume
design_config_grid Realtime Rarely changes

For most production stores: put all performance-sensitive indexers on Schedule and ensure cron is running every minute.


Running a Reindex

Full reindex of all indexers:

bin/magento indexer:reindex

Reindex a specific indexer:

bin/magento indexer:reindex catalog_product_price

Check status before and after:

bin/magento indexer:status
bin/magento indexer:show-mode

Reset an indexer to “invalid” (forces a full reindex on next run):

bin/magento indexer:reset catalog_product_price

For large catalogs, always run reindex from CLI — never from admin — and consider using nohup or a terminal multiplexer so a dropped SSH connection does not abort mid-run:

nohup bin/magento indexer:reindex > /var/log/magento_reindex.log 2>&1 &

Common Indexer Problems and How to Fix Them

Problem 1: “One or more indexers are invalid. Make sure your Magento cron job is running.”

This admin banner appears when indexer status is invalid. It means data changed but the indexer has not run yet.

Fix:

  1. Confirm cron is running: ps aux | grep cron
  2. Check the cron schedule table: SELECT * FROM cron_schedule WHERE job_code LIKE 'indexer%' ORDER BY scheduled_at DESC LIMIT 20;
  3. Manually trigger: bin/magento indexer:reindex
  4. If cron is missing entries entirely, verify crontab -l has Magento’s cron entry

Problem 2: Indexer stuck in “working” status

Magento marks an indexer as “working” when a reindex process starts and uses a database lock. If the process crashes mid-run, the lock persists and the indexer never returns to “ready.”

Fix:

bin/magento indexer:reset
bin/magento indexer:reindex

If that does not work, check for orphaned locks:

SELECT * FROM indexer_state WHERE status = 'working';
UPDATE indexer_state SET status = 'invalid' WHERE status = 'working';

Problem 3: Reindex runs but products still not appearing in search

The search index may have rebuilt correctly in MySQL but the data has not been pushed to Elasticsearch or OpenSearch.

Fix:

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

Also check that the search engine connection is healthy:

bin/magento config:show catalog/search/engine

Then verify connectivity from the Magento server to your search host on port 9200 (Elasticsearch) or 9200/9300 (OpenSearch).

Problem 4: Price changes not reflecting on the storefront

Usually a stale catalog_product_price index combined with full-page cache.

Fix:

bin/magento indexer:reindex catalog_product_price catalogrule_rule catalogrule_product
bin/magento cache:clean full_page block_html

Problem 5: Changelog tables missing after indexer set to schedule mode

SHOW TABLES LIKE 'catalog_product_index_price_cl';

If empty: changelog tables were not created. This happens after upgrades where setup:upgrade was not run cleanly.

Fix:

bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento indexer:set-mode schedule

Performance Tips for Large Catalogs

1. Use schedule mode for all heavy indexers. The changelog mechanism means only changed entities are processed — the most important optimization for stores with 10,000+ SKUs.

2. Separate cron processes. Magento 2 supports cron groups (catalog, default). The catalog group handles indexing. You can run it on a dedicated cron process with higher resource limits.

3. Avoid running reindex during peak traffic. Full reindexes lock tables or create high DB load. Schedule them during off-peak windows.

4. Monitor with n98-magerun2:

n98-magerun2 sys:cron:list
n98-magerun2 index:list

5. Watch changelog table size. If cron is not running, changelog tables grow unboundedly. Check periodically:

SELECT COUNT(*) FROM catalog_product_index_price_cl;

A very large count (100k+ rows) means cron has been down for a while and your next reindex will be slow.


Summary

Magento 2’s indexer system is designed to keep storefront performance high by pre-computing data that would be expensive to calculate on the fly. Understanding what each indexer builds, why schedule mode with changelogs is the right production choice, and how to diagnose stuck or invalid indexers gives you direct control over one of the most impactful subsystems in the platform.

The key takeaways:

  • Schedule mode + cron is the correct setup for any store with meaningful catalog size or admin activity
  • Changelog tables are the mechanism behind schedule mode — if they are missing, the system falls back silently
  • Never ignore the “indexers invalid” banner in production — it means customers may be seeing stale prices, stock, or search results
  • When in doubt, indexer:statusindexer:resetindexer:reindex is your diagnostic sequence

Keep your indexers healthy and your storefront stays fast and accurate.

 

5 1 vote
Article Rating

Callula Huy

Callula is the Marketing Executive at Magetop. With more than 5 years of copywriting under his belt, Callula is into creating valuable content that is straight to the point. Life student. Workaholic. Foreign languages and traveling aficionado.

Leave a Reply or put your Question here

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x