DocsHub
Indexes

What Are Indexes?

Understand what indexes are, why they matter, and how MongoDB uses them to speed up queries.

What Are Indexes?

Every time you run a query, MongoDB needs to find the matching documents. Without an index, it does this by scanning every single document in the collection one by one — checking if each one matches your filter. This is called a collection scan.

For a small collection with 10 or 20 documents, this is fine. But imagine your school system has 50,000 students. Scanning all 50,000 documents every time someone searches for a student by name is very slow.

An index solves this problem. It is a separate, small data structure that MongoDB maintains alongside your collection. It stores the values of specific fields in a sorted order, with pointers back to the actual documents. Instead of scanning every document, MongoDB looks up the index — finds the matching entries in milliseconds — and jumps directly to the right documents.


Collection Scan vs Index Scan

Without Index — Collection Scan With Index — Index Scan Query: find student named 'Ali' D1 Check document 2 — Umar Farooq ❌ Check document 3 — Ali Hassan ✅ Check document 4 — Ayesha Khan ❌ Check document 5 — Bilal Ahmed ❌ Return Ali HassanChecked: 5 documents Query: find student named 'Ali' I1 Jump directly to doc 3Checked: 1 entryReturn Ali Hassan

With a collection scan, MongoDB reads every document. With an index scan, MongoDB looks up the value in the index and jumps straight to the right document. The larger your collection, the bigger this difference becomes.


A Real Example

Let's say our school has 50,000 students and you run this query:

db.students.find({ name: "Ali Hassan" })

Without an index on name: MongoDB reads all 50,000 documents one by one. If Ali Hassan is document number 49,832 — MongoDB has to check 49,832 documents before finding him.

With an index on name: MongoDB looks up "Ali Hassan" in the index — which is sorted alphabetically — finds the pointer to his document, and retrieves it directly. It checks maybe 10–15 index entries instead of 50,000 documents.

The difference in query time goes from hundreds of milliseconds to under a millisecond.


The Default _id Index

Every MongoDB collection automatically has one index — the index on _id. This is why querying by _id is always fast, even on huge collections. MongoDB created this index for you when the collection was first created.

// This is always fast — _id is always indexed
db.students.findOne({ _id: new ObjectId("64a1f2c3e4b0a1b2c3d4e5f6") })

For any other field — name, grade, email — there is no index by default. You have to create them yourself.


How an Index is Structured

An index stores field values in a sorted B-tree structure. Think of it like the index at the back of a textbook — instead of reading the whole book to find a topic, you look it up alphabetically in the index and go directly to the right page.

For a name index on the students collection, MongoDB maintains a sorted list like this:

Ali Hassan      → pointer to document
Ayesha Khan     → pointer to document
Bilal Ahmed     → pointer to document
Sara Ahmed      → pointer to document
Umar Farooq     → pointer to document

When you query { name: "Sara Ahmed" }, MongoDB does a binary search on this sorted list — finding the entry in a fraction of the time it would take to scan all documents.


The Cost of Indexes

Indexes are not free. They come with tradeoffs you should understand:

Storage space — each index takes up disk space. A collection with many indexes uses significantly more storage than one with none.

Slower writes — every time you insert, update, or delete a document, MongoDB must also update every index on that collection. More indexes means slower write operations.

Memory usage — MongoDB tries to keep indexes in RAM for fast access. Too many indexes can fill up your RAM and slow everything down.

This means you should not create an index on every field. Create indexes on fields you actually query frequently.

A good rule of thumb — create indexes based on your query patterns, not your data structure. Look at which queries run most often and which fields they filter, sort, or search on. Those are the fields that need indexes.


When to Use an Index

Create an index when:

  • You frequently query a collection by a specific field — like searching students by name or grade
  • You sort results by a field often — like ordering students by enrollmentDate
  • A field is used in a join condition — like matching a studentId in another collection
  • A field must be unique across all documents — like email or rollNumber

Do not create an index when:

  • The collection is very small and collection scans are fast enough
  • A field is rarely queried
  • The collection has very heavy write traffic and you cannot afford the write slowdown

Indexes in Our School System

Right now our students collection has only the default _id index. As our school grows, these queries will get slower without indexes:

// Slow without index — scans all students
db.students.find({ name: "Ali Hassan" })

// Slow without index — scans all students
db.students.find({ grade: "10th" })

// Slow without index — scans all students
db.students.find({ enrolled: true }).sort({ name: 1 })

In the next file, we will create indexes on these fields and make them fast.


Quick Summary

Collection ScanIndex Scan
How it worksReads every documentLooks up sorted index, jumps to document
Speed on small collectionsFast enoughFast
Speed on large collectionsVery slowVery fast
Storage costNoneExtra disk space per index
Write speed impactNoneSlightly slower writes

If a query feels slow during development — even with a small dataset — add an index. It is much better to add the right indexes early than to debug performance problems in production with millions of documents.

On this page