Magento's indexing system is one of the most misunderstood parts of the platform. Run it wrong and you get store lockups, slow admin saves, and customers seeing stale prices. Run it right and indexing becomes invisible.
What indexers actually do
Magento uses indexers to pre-compute expensive derived data and store it in flat tables optimized for reads:
| Indexer | What it computes |
|---|---|
catalog_product_flat |
Flat product data (faster reads than EAV) |
catalog_category_flat |
Flat category data |
catalog_category_product |
Category-to-product mappings |
cataloginventory_stock |
Stock status and availability |
catalog_product_price |
Computed prices (after discounts, tier pricing) |
catalogsearch_fulltext |
Search index (Elasticsearch/OpenSearch) |
catalogrule_rule |
Catalog price rule applications |
When an indexer is "invalid," Magento serves stale data from the last valid index. When it's "processing," database tables are locked.
Scheduled vs. real-time indexing
Each indexer can run in two modes:
Real-time (realtime): Reindexes automatically when data changes. Safe for small catalogs, dangerous for large ones — a single product save can trigger minutes of reindexing.
Scheduled (schedule): Queues changes and processes them in batches via cron. Much better for production.
Switch all indexers to scheduled:
bin/magento indexer:set-mode schedule
Verify:
bin/magento indexer:info
With scheduled indexing, product saves complete instantly. The cron job processes the queue periodically (every minute by default).
The indexer cron configuration
Magento's default cron runs indexers every minute. For large catalogs, this can cause cron jobs to overlap.
Check your cron is running:
bin/magento cron:run
bin/magento cron:status
For high-traffic stores, run indexers during off-peak hours:
<!-- app/code/YourVendor/CronOverride/etc/crontab.xml -->
<config>
<group id="index">
<job name="indexer_reindex_all_invalid" instance="Magento\Indexer\Cron\ReindexAllInvalid" method="execute">
<schedule>*/5 * * * *</schedule> <!-- Every 5 minutes instead of every 1 -->
</job>
</group>
</config>
Partial reindexing
Running a full reindex on a store with millions of products takes hours. Partial reindexing processes only the changed rows:
# Full reindex (avoid in production during business hours)
bin/magento indexer:reindex
# Check which indexers need reindexing
bin/magento indexer:status
# Reindex only a specific indexer
bin/magento indexer:reindex catalog_product_price
With scheduled mode, partial reindexing happens automatically. The mview (materialized view) system tracks changed rows in changelog tables and only processes those.
Diagnosing slow reindexing
If your indexers consistently take too long, the culprits are usually:
1. Catalog price rule complexity
Complex pricing rules with many conditions force Magento to evaluate every product against every rule. Simplify rules where possible, or use customer group pricing instead.
2. Large EAV tables without indexes
The indexer reads from EAV tables. Missing database indexes on these tables make full reindexes extremely slow.
-- Check if these indexes exist
SHOW INDEX FROM catalog_product_entity_decimal;
SHOW INDEX FROM catalog_product_entity_int;
-- If missing, add them
ALTER TABLE catalog_product_entity_decimal
ADD INDEX IDX_ATTRIBUTE (attribute_id, store_id);
3. Elasticsearch document size
The catalogsearch_fulltext indexer pushes data to Elasticsearch/OpenSearch. If you're indexing too many attributes, documents get large and indexing slows down.
Only index attributes that users actually search on:
Admin → Stores → Attributes → Product → [attribute] → Use in Search → Yes/No
Turn off "Use in Search" for attributes like internal SKUs, supplier codes, and technical specs that customers never search for.
Monitoring indexer health
Add indexer status to your monitoring:
#!/bin/bash
# check-indexers.sh
STATUS=$(bin/magento indexer:status | grep -c "Reindex required")
if [ "$STATUS" -gt "0" ]; then
echo "ALERT: $STATUS indexers require reindexing"
exit 1
fi
echo "All indexers valid"
Run this in your monitoring cron every 30 minutes. Alert if any indexer has been invalid for > 15 minutes.
Before a major import
When you're importing thousands of products (e.g., catalog update from ERP), disable observers and run a full reindex after:
# Before import
bin/magento indexer:set-mode realtime cataloginventory_stock # Keep stock live
bin/magento indexer:set-mode schedule catalog_product_flat catalog_category_flat catalog_product_price catalogsearch_fulltext
# Run import
bin/magento import:run ...
# After import - full reindex of affected indexers
bin/magento indexer:reindex catalog_product_flat catalog_category_flat catalog_product_price catalogsearch_fulltext
# Flush caches
bin/magento cache:flush
This pattern keeps your store responsive during the import and runs the reindex as a single batch operation after.
Summary
- Switch all indexers to
schedulemode in production - Ensure cron is running and not overlapping
- Monitor indexer status — alert on invalid indexers > 15 minutes
- Add database indexes to EAV tables to speed up full reindexes
- Only index attributes in Elasticsearch that users actually search on
- Batch large imports and reindex after, not during
Originally published on magevanta.com
Top comments (0)