The Error
Youβre pushing a critical update or running a database migration when your CI/CD pipeline suddenly grinds to a halt. The logs show a blunt rejection from the database:
MongoServerError: add index fails, too many indexes for ns: mydb.mycollection
This isn't a bug or a temporary glitch. You have hit the hard-coded limit of 64 indexes per collection. It is a protective ceiling built into the WiredTiger storage engine to prevent your database from crawling to a standstill.
Why This Happens
While 64 indexes sounds like a generous amount, complex applications often hit this wall faster than expected. Every index you add isn't free. Each one adds roughly 10β20% overhead to write operations because MongoDB must update every relevant B-tree for every insert, update, or delete.
Common culprits include:
- ORM Over-indexing: Tools like Mongoose or TypeORM might be auto-creating indexes for every field defined in your schema.
- Legacy Bloat: Old features are deleted, but the indexes supporting them remain active and consuming resources.
- Query-Per-Index Habit: Creating a unique index for every single permutation of a
find()query instead of using compound structures.
If your collection holds 100 million documents, a single redundant index could be wasting 5GB of RAM that your working set desperately needs.
Immediate Fix: Audit and Cleanup
You cannot increase this limit via configuration. The only way to move forward is to make room by removing what you don't need.
Step 1: Inventory your current indexes
Open mongosh and list every index currently active on the collection:
db.mycollection.getIndexes()
Look closely at the key definitions. You are looking for overlaps.
Step 2: Eliminate redundant prefixes
MongoDB indexes work from left to right. If you have a compound index, any query using the "prefix" (the first field or fields) is already covered. Consider these two indexes:
- Index A:
{ "tenant_id": 1 } - Index B:
{ "tenant_id": 1, "created_at": -1 }
Index A is 100% redundant. Index B can handle any query that Index A was handling. Deleting Index A immediately frees up a slot and reduces write latency without affecting query performance.
Step 3: Drop the dead weight
Once you find a redundant index, drop it by its name:
db.mycollection.dropIndex("tenant_id_1")
Check your progress by counting the remaining indexes:
db.mycollection.getIndexes().length
Long-term Resolution Strategies
If your application genuinely requires more than 60 data access patterns, you need to change your indexing strategy.
1. Consolidate with Compound Indexes
A single well-planned compound index like { shop_id: 1, status: 1, category: 1 } can support three different query types. It covers searches on shop_id alone, shop_id + status, and all three fields combined. Use this "ESR" (Equality, Sort, Range) rule to make your indexes more versatile.
2. Switch to Wildcard Indexes
Are you indexing dozens of custom user fields or dynamic metadata? Stop. Use a Wildcard Index instead:
db.mycollection.createIndex({ "user_metadata.$**": 1 })
This covers every nested field inside the user_metadata object. The best part? It counts as exactly one index toward your 64-index limit, regardless of how many sub-fields it tracks.
3. Identify Unused Indexes with $indexStats
Don't guess which indexes are useful. Use the $indexStats aggregation to see real-world usage since the last restart:
db.mycollection.aggregate([ { $indexStats: {} } ])
Check the accesses.ops field. If an index shows 0 operations after a week of production traffic, it is safe to delete.
Verification
After cleaning up, try creating your new index again. It should now succeed:
db.mycollection.createIndex({ "new_feature_key": 1 }, { name: "idx_feature_v1" })
// Should return: { "ok": 1 }
Run db.mycollection.explain("executionStats").find(...) on your common queries to ensure that removing the old indexes didn't cause a performance regression like a collection scan.
Prevention Checklist
- Disable Auto-Indexing: In Mongoose, set
autoIndex: false. Manage your indexes via migration scripts so they don't surprise you in production. - Monitor Limits: Set an alert in MongoDB Atlas or Datadog to trigger when a collection hits 50 indexes.
- Review TTLs: Time To Live (TTL) indexes are useful but count toward the limit. Use them sparingly.
- Audit Quarterly: Schedule a recurring task to run
$indexStatsand prune unused indexes.

