Forem

shruti jain
shruti jain

Posted on

Stop Wasting Memory: Use .lean() Like a Pro

Introduction

Alright, let’s talk about something that should be common sense but somehow isn’t: using .lean() in Mongoose. If you’ve ever written a simple query and thought, “Why is my app using so much memory?”, chances are you’re not using .lean(). And if you're the kind of developer who likes to flex about performance optimizations but still ignores .lean(), this one's for you.

What the Heck is .lean()?

Mongoose normally returns full-fat documents, loaded with built-in magic: getters, setters, hooks, change tracking—you name it. But let’s be real: 90% of the time, you don’t need that extra fluff when you're just reading data.

Enter .lean(), a simple method that tells Mongoose:

“Hey, don’t give me a fancy, bloated document. Just give me a plain JavaScript object.”

And boom! You just saved memory, improved query speed, and maybe even made your API 10% less of a dumpster fire.

How .lean() Works (With Examples)

Without .lean() (The Memory Hog Approach)

const article = await ArticlesModel.findOne({ title: "How to Waste Memory" });
console.log(article);
// Output: Mongoose Document with tons of hidden properties

console.log(typeof article); // "object" (but a heavy Mongoose object)
console.log(article.save); // Function exists! (But you never needed it, did you?)
Enter fullscreen mode Exit fullscreen mode

Here’s the problem: this returns a full Mongoose document, packed with hidden features like .save(), .validate(), and other things you will never use in a read operation.

With .lean() (The Smart Way)

const article = await ArticlesModel.findOne({ title: "How to Optimize Performance" }).lean();
console.log(article);
// Output: { _id: "abc123", title: "How to Optimize Performance" }

console.log(typeof article); // "object" (plain JavaScript object)
console.log(article.save); // undefined (because you never needed it!)
Enter fullscreen mode Exit fullscreen mode

Boom! Faster, lighter, and without unnecessary Mongoose baggage.


Why Should You Care?

1. .lean() Makes Queries Faster

  • Full Mongoose documents come with extra processing.
  • .lean() skips that overhead and returns raw JSON objects.

2. .lean() Saves Memory 🧠

  • Mongoose docs retain a reference to the database (more memory).
  • Plain objects? Lighter, easier to work with, and don’t bloat your app.

3. Avoids Unnecessary Features 🚀

  • Do you need .save() on a read query? No.
  • Do you need schema validation on an already stored document? Nope.
  • Do you need virtuals? Then don’t use .lean() (more on this below).

When NOT to Use .lean()

I get it—.lean() sounds like magic. But don’t get too excited; it’s not always the right choice. Here’s when you shouldn’t use it:

🚨 If You Need Schema Features (Virtuals, Hooks, Middleware)

const userSchema = new mongoose.Schema({
  firstName: String,
  lastName: String,
}, {
  toJSON: { virtuals: true },
});

userSchema.virtual("fullName").get(function () {
  return `${this.firstName} ${this.lastName}`;
});

const user = await UserModel.findOne({ firstName: "John" }).lean();
console.log(user.fullName); // undefined (because `.lean()` removes virtuals!)
Enter fullscreen mode Exit fullscreen mode

💡 Solution? Don’t use .lean() if you need schema-based transformations.

🚨 If You Need to Modify and Save the Document

const user = await UserModel.findOne({ name: "Alice" }).lean();
user.age = 30;
await user.save(); // ❌ ERROR! save() doesn't exist on plain objects.
Enter fullscreen mode Exit fullscreen mode

💡 Solution? If you plan to update and save the document, skip .lean().


The TL;DR for Lazy Developers

✅ Use .lean() when:

  • You only need to read data.
  • You want faster, lightweight queries.
  • You don’t need .save(), hooks, or virtuals.

⛔ Don’t use .lean() when:

  • You need virtuals, middleware, or hooks.
  • You’re going to modify and save the document.

Final Thoughts

Mongoose is great, but blindly using full documents everywhere is just bad practice. If your app is sluggish or consuming too much memory, .lean() is a simple, one-line fix that can make a big difference.

So next time someone asks “Why is our API so slow?”, just reply:

“Did you use .lean()?”

And if they say no, well… you know who to blame. 😎

Top comments (1)

Collapse
 
abhivyaktii profile image
Abhinav

Thank you for sharing your expert tips on how to use .lean() with Mongoose queries. I especially like the part about understanding the purpose of .lean() and when to use it, and I will definitely apply that to my own applications. That's really useful!