Mongoose
database management
connection closing
Node.js
MongoDB

Properly close mongoose's connection once you're done

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Mongoose is an elegant and schema-based solution for modeling data in MongoDB, a NoSQL database that's popular among developers for building modern applications. While connecting to the database is a frequent task, ensuring that the connection is properly closed when your application is done is just as critical. Properly closing a Mongoose connection frees up resources, avoids potential memory leaks, and ensures that your application performs optimally.

Importance of Closing Mongoose Connections

Failing to close a Mongoose connection can lead to several issues:

  • Resource Leaks: Open connections consume system and network resources, which can degrade application performance.
  • Memory Usage: Unclosed connections contribute to increased memory usage, risking application crashes.
  • Database Limitations: MongoDB has a limit on the number of connections it can handle. Leaving connections open unnecessarily may lead to your database not being able to accept new incoming connections.

Technical Steps to Close Mongoose Connection

Using disconnect()

To close a Mongoose connection, you employ the disconnect() method. Below is a simple implementation to open and then close a connection:

javascript
1const mongoose = require('mongoose');
2
3// URL to your MongoDB cluster
4const uri = 'mongodb://yourMongoDBURL';
5
6// Connect to the database
7mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true })
8  .then(() => {
9    console.log('MongoDB connected');
10    
11    // Your DB operations go here
12
13  })
14  .catch(err => {
15    console.error('Connection error', err);
16  });
17
18// Function to close the connection
19function closeConnection() {
20  mongoose.disconnect()
21    .then(() => console.log('MongoDB connection closed'))
22    .catch(err => console.error('Error closing connection', err));
23}
24
25// Usage example
26process.on('SIGINT', () => {
27  closeConnection();
28});

Using Async/Await

Mongoose connect() and disconnect() are promise-based, so using async/await enhances code readability.

javascript
1const mongoose = require('mongoose');
2
3async function connectDB(uri) {
4  try {
5    await mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
6    console.log('MongoDB connected');
7    // Your DB operations
8  } catch (err) {
9    console.error('Connection error', err);
10  }
11}
12
13async function closeConnection() {
14  try {
15    await mongoose.disconnect();
16    console.log('MongoDB connection closed');
17  } catch (err) {
18    console.error('Error closing connection', err);
19  }
20}
21
22(async function() {
23  const uri = 'mongodb://yourMongoDBURL';
24  await connectDB(uri);
25  
26  // Trigger closing connection
27  process.on('SIGINT', closeConnection);
28})();

Event Listeners for Graceful Shutdown

A graceful shutdown ensures that your application does not abruptly terminate connections, risking data corruption or loss.

Handling Node.js Signals

Events like SIGINT (CTRL-C in most environments) and SIGTERM are typically used to trigger shutdown processes.

javascript
process.on('SIGINT', closeConnection);
process.on('SIGTERM', closeConnection);

Handling Uncaught Exceptions

To avoid leaving connections open after uncaught exceptions, catch them and attempt a graceful shutdown.

javascript
1process.on('uncaughtException', (err) => {
2  console.error('Uncaught Exception:', err);
3  closeConnection().finally(() => process.exit(1));
4});

Key Points Summary

Key AspectDescription
Resource ManagementFrees up system resources, avoids memory leaks
Method to Close Connectiondisconnect() method
Asynchronous HandlingUse async/await for better readability
Graceful ShutdownHandling through Node.js signals like SIGINT/SIGTERM and uncaught exceptions

Additional Tips

  • Connection Pooling: Mongoose supports connection pooling out of the box, reducing the overhead of connecting and disconnecting. Adjust pool size if needed through poolSize option while connecting.
  • Health Checks: Regularly monitor the number of connections and ensure they do not exceed your database's limit, which can be essential in high-traffic applications.
  • Logging: Enable logging to track open and closed connections, assisting in identifying issues early.

By adhering to these practices, you can ensure that your use of Mongoose is efficient, and your MongoDB resources are optimally utilized, minimizing the risk of downtime or performance issues.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.