Sling Academy
Home/Node.js/How to Set Timeouts in Mongoose (with Examples)

How to Set Timeouts in Mongoose (with Examples)

Last updated: December 30, 2023

Introduction

As a NoSQL database, MongoDB is known for its scalability and performance, especially when coupled with Mongoose, an elegant MongoDB object modeling for Node.js. However, as with any database, operations can sometimes take longer than expected due to various factors such as network latency, database load, or inefficient queries. In such cases, setting a timeout can be crucial to prevent backend services from hanging indefinitely. In this tutorial, we will explore how to set timeouts in Mongoose, guaranteeing more robustness and stability inside your Node.js applications.

Timeouts in Mongoose

Mongoose provides several mechanisms to control the length of time for an operation to be allowed to execute. These include connection timeouts, query timeouts, and transaction timeouts, and they can be tailored to fit different scenarios ranging from individual queries to entire connections. Knowing which timeout to use and under which circumstances can help in building efficient and fail-safe applications.

Setting up a Basic Timeout on a Query

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/myapp_db', { useNewUrlParser: true });

const kittySchema = new mongoose.Schema({
  name: String
});

const Kitten = mongoose.model('Kitten', kittySchema);

Kitten.find({}).maxTimeMS(5000).exec();

The maxTimeMS method applies a timeout to the execution of this particular query, limiting it to 5000 milliseconds (5 seconds). If the query execution time exceeds the specified duration, MongoDB throws a timeout error, and the exec callback receives an error object.

Connection Timeouts

Managing the connection timeout is different from setting timeouts on individual queries as it dictates how long a connection can remain idle before being closed. This setting can be particularly useful when starting up a server and attempting to connect to MongoDB.

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/myapp_db', {
  useNewUrlParser: true,
  serverSelectionTimeoutMS: 5000  // Wait 5 seconds before throwing a connection error.
});

Advanced Usage: Transaction Timeouts

In a scenario where many operations have to happen altogether or none at all, we use transactions. They guarantee atomicity, which is one of the ACID properties. However, transactions in MongoDB can be long-running and need timeout configurations to avoid extended locking periods on documents. Let’s dive into setting a timeout for MongoDB transactions with Mongoose.

// Assume we already have a Mongoose connection
(async () => {
  const session = await mongoose.startSession();
  session.startTransaction();
  try {
    await someOperationInvolvingMultipleWrites({ session });// added options including session
    await session.commitTransaction();
  } catch (error) {
    await session.abortTransaction();
    throw error;
  } finally {
    session.endSession();
  }
})();

This code snippet assumes that some database operations have to be done in a transaction. The key here would be to ensure MongoDB server parameters are set to limit the length of transactions, as there is no way to specify transaction timeout directly through Mongoose API.

Handling Timeouts Gracefully

Timeouts are often unavoidable, and how you handle them can vary. These can range from retries with exponential backoff to informing users of the delay, depending on the application’s nature and structure. Implementing comprehensive error handling strategies in response to timeouts can differentiate between a resilient system and one that fails under pressure.

Conclusion

In this in-depth guide, we have discussed various approaches to setting timeouts in Mongoose for robust database operations. From adjusting maximum execution times for queries to managing connection and transaction timeouts, Mongoose provides you with adequate configurations to ensure your application stays responsive and prevents issues related to database operation hiccups. Remember to handle timeouts with proper error management techniques to maintain a smooth user experience within your application.

Next Article: Using the Mongoose Model.find() function (with examples)

Previous Article: Virtuals in Mongoose: Explained with Examples

Series: Mongoose.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates