Why Your MongoDB Queries Are Slow — and How Indexes Can Speed Them Up

Nidhin MNidhin M
5 min read

If you've ever run a MongoDB query and thought,

“Why is this suddenly taking forever?”
Yeah, I’ve been there too.

Everything starts off fine. Queries are fast, the app feels responsive. Then the data grows. And suddenly, things go from snappy to sluggish. Welcome to the world of collection scans.

Here’s the deal:
It’s probably not your code.
It’s probably not MongoDB being weird.
It’s almost always this one thing: missing indexes.

Let’s break this down — no fluff, just what you actually need to know.


🧠 What Is an Index Anyway?

Imagine your MongoDB collection is a giant book — but with no table of contents. If you want to find a specific chapter (document), you’ve gotta flip through everything. That’s a collection scan.

Now imagine you do have a table of contents. You jump straight to the chapter. That’s what an index does — it helps MongoDB skip the guessing and go straight to the data.

  • No index? MongoDB checks every document.

  • With an index? MongoDB jumps straight to the right place.

Big difference when your collection has millions of records.


⚡ Why Indexes Matter (for Real)

Say you run:

db.users.find({ email: "alice@example.com" });

If there's no index on email, MongoDB goes document by document, checking each one. That might be fine if you have 50 users.

But what if you have 500,000?

Now add an index:

db.users.createIndex({ email: 1 });

Boom — MongoDB can now use a B-tree structure to find the email in logarithmic time. Faster queries, less CPU, and your app doesn't feel like it’s gasping for air under load.

Moral of the story:
When queries slow down, check your indexes first.


🔧 Common Index Types (And When to Use Them)

1. Single-Field Index

The go-to, everyday index.

db.users.createIndex({ email: 1 });

Use it when you’re:

  • Filtering or sorting on a single field (email, username, createdAt, etc.)

Doesn’t matter if it's 1 (ascending) or -1 (descending) — that only affects sort order, not performance for equality queries.


2. Compound Index

Useful when you often filter or sort by multiple fields together.

db.users.createIndex({ name: 1, age: 1 });

This works for:

  • { name: "Alice" }

  • { name: "Alice", age: 30 }

But not for just { age: 30 }.
Order matters — put the most commonly queried field first.

Use when:

  • You’re paginating (createdAt + _id)

  • Filtering by two or more fields regularly


3. Multikey Index

MongoDB automatically creates these if your field is an array.

db.users.createIndex({ tags: 1 });

Example document:

{ tags: ["node", "mongodb", "backend"] }

Query:

db.users.find({ tags: "mongodb" });

Returns documents where any tag matches.

Use when:

  • You're storing arrays (tags, roles, skills) and need to search inside them.

4. Text Index

For basic full-text search.

db.users.createIndex({ bio: "text" });

Query:

db.users.find({ $text: { $search: "developer" } });

MongoDB will tokenize and match relevant words.

Things to know:

  • Only one text index per collection

  • Not as powerful as Elastic, but good enough for simple use cases

Use when:

  • You want lightweight search in bios, product descriptions, blog posts, etc.

5. Geospatial Index

If you're dealing with locations (maps, delivery zones, etc.)

db.users.createIndex({ location: "2dsphere" });

Query nearby users:

db.users.find({
  location: {
    $near: {
      $geometry: {
        type: "Point",
        coordinates: [77.5946, 12.9716], // [lng, lat]
      },
      $maxDistance: 5000, // meters
    },
  },
});

Use when:

  • You're building a map, delivery app, or “nearby” feature.

🧪 Checking Performance: .explain()

Want to know if your query is using an index? Run:

db.users.find({ email: "bob@example.com" }).explain("executionStats");

Look for:

  • "stage": "IXSCAN" → using an index ✅

  • "stage": "COLLSCAN" → full collection scan ❌

Also check:

  • nReturned: how many docs it found

  • totalDocsExamined: how many docs it had to check

  • executionTimeMillis: how long it took


✅ Indexing Tips I Wish I Knew Sooner

  • Index the fields you actually query. Not everything. Just the ones in .find(), .sort(), or $match.

  • Compound indexes > multiple single-field indexes when used right.

  • Use .explain() to prove your index is helping.

  • Don’t overdo it — too many indexes can hurt writes and eat memory.

  • Periodically clean up unused indexes (MongoDB Compass or Atlas helps here).


When I first used MongoDB, I didn’t touch indexes until something broke. Then I’d be deep-diving into .explain() output at 2am trying to figure out why a simple query was taking 5 seconds.

Eventually, I learned:
Add the right indexes early. Saves you from painful debugging later.


🏁 Final Thoughts

Indexes aren’t an optimization — they’re a requirement if you want performance at scale.

So next time a query is slow, don’t just blame your app or MongoDB. Check your indexes. Add what you need. And clean up the ones you don’t.

If you want to dive deeper into advanced stuff like partial indexes, TTL, or wildcard indexes — let me know. Happy to nerd out with you.

And I got one more thing—I found a super useful YouTube series on MongoDB. I used that tutorial along with ChatGPT.And I'm sharing the link below—hope you find it useful on your journey!

https://www.youtube.com/watch?v=4EjKroJCpFA&list=PLA3GkZPtsafZydhN4nP0h7hw7PQuLsBv1

0
Subscribe to my newsletter

Read articles from Nidhin M directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nidhin M
Nidhin M

Hey there! I'm a passionate software developer who thrives in the TypeScript world and its companions. I enjoy creating tutorials, sharing tech tips, and finding ways to boost performance. Let's explore coding and tech together! 🚀