Skip to content

Mongo Db Atlas data READ/WRITE becomes slower after 3 or 4 hours #15278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
AndrewsSharvinFindmena opened this issue Feb 27, 2025 · 8 comments
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary

Comments

@AndrewsSharvinFindmena
Copy link

await mongoose.connect(process.env.MONGO_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  serverSelectionTimeoutMS: 15000, 
  socketTimeoutMS: 45000, 
});

This is how the code looks,

I am currently using a paid cluster in Atlas. I have monitored the RAM and CPU usage while this happens. The RAM and CPU are perfectly normal, but the data READ/WRITE process becomes slower, and the following event is triggered multiple times before this

mongoose.connection.on('disconnected', async () => {
console.log('MongoDB disconnected, attempting to reconnect...');
});

I am using node js with express

{
"mongoose": "^7.8.6",
"express": "^4.19.2",
}

the node version on the local system is v22.3.0

@AndrewsSharvinFindmena
Copy link
Author

Image

The connection Number is way too high, but whenever I restart the server it gets normal to 64 connections as you can see

@vkarpov15
Copy link
Collaborator

Without a repro script, there's no way we can reasonably repro this or make any informed recommendations.

@vkarpov15 vkarpov15 added the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Mar 6, 2025
@AndrewsSharvinFindmena
Copy link
Author

AndrewsSharvinFindmena commented Mar 19, 2025

Here` is the index file for the node server

There are 3 watch functions and a total of 16 collections

The problem is that whenever I start or restart my server, the total number of connections is around 85. After some time, it rises to 160-180. However, after 4 to 5 hours of inactivity, the number of connections remains at 160-180, and any requests made afterward take longer to respond.


import express from "express";
import mongoose from "mongoose";
import http from 'http';
import path from "path";
import bodyParser from "body-parser";
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
const __dirname = path.dirname(__filename); // get the name of the directory
import cors from "cors";
import {Server, Socket} from 'socket.io';
import { createServer } from 'http';

import dotenv from 'dotenv'
dotenv.config()
mongoose.set("strictQuery", true);
const corsOptions = {
    origin:[ process.env.FRONTEND,process.env.FRONTEND2],
    credentials: true, //access-control-allow-credentials:true
    optionSuccessStatus: 200,
};



const app = express();
const server = createServer(app);
const io =new Server(server, {
    cors: {
        origin:[ process.env.FRONTEND, process.env.FRONTEND2],  // Allow any origin (you can specify your frontend URL here)
        methods: ['GET', 'POST']
    }
});
app.use(cors(corsOptions));
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.set('view engine', 'ejs');


//time out after 10 seconds
app.use((req, res, next) => {
    req.setTimeout(10 * 1000); // 10 seconds
    res.setTimeout(10 * 1000);
    next();
});
async function connect(reconnect) {

    try {
        await mongoose.connect(process.env.MONGO_URL, {
            useNewUrlParser: true,
            useUnifiedTopology: true,
            serverSelectionTimeoutMS: 15000, 
            socketTimeoutMS: 45000, 
            maxIdleTimeMS:60000,
        });
        if(reconnect){
            console.log('MongoDB re-connected successfully');
        }else{
            console.log('MongoDB connected successfully');
        }

    } catch (error) {

        if(reconnect){
            console.error('MongoDB connection error:', error.message);
        }else{
            console.error('MongoDB connection error:', error.message);
        }
        setTimeout(connect, 5000); // Retry connection after 5 seconds
    }
}
connect();






app.get("/", function (req, res) {
    res.send("<h1>hello backend </h1>");
});

//
//
//
//
//      .........   My other APIs    .........
//
//
//
//




// handle socket connection
io.on('connection', (socket) => {





    socket.on('disconnect', (data) => {
        if (!socket?.token) {

            return socket.emit('error', 'Authentication required');
        }
    });





    socket.on('getNotifications', async (data) => {


        // ActivityChat.watch().on('change',async (change)=>{
        //
        // A watch function is there for ActivityChat
        //
        // })
        //
        // Notification.watch().on('change',async (change)=>{
        //
        // A watch function is there for Notification
        //
        // })


    })


});


//watch functions
// Trends.watch().on('change',(change)=>{
//
//  Another Watch Function
//
// })

//There is only 3 watch functions in the entire code and a total of 16 collections


server.listen(process.env.PORT || 3011, function () {
    console.log("Server is running at http://localhost:3011");
});

function closeConnection() {

    mongoose.disconnect().then(()=>{
        console.log("mongoose disconnected")
    })

}


mongoose.connection.on('disconnected', async () => {
    console.log('MongoDB disconnected, attempting to reconnect...');
});

mongoose.connection.on('error', (error) => {
    console.error('MongoDB connection error:', error);
});



process.on('SIGINT',  () => {
    closeConnection();
    process.exit(0);
});

@vkarpov15 vkarpov15 removed the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Mar 31, 2025
@vkarpov15 vkarpov15 modified the milestones: 8.13.2, 8.13.3 Mar 31, 2025
@vkarpov15
Copy link
Collaborator

A potential explanation is the following code:

    socket.on('getNotifications', async (data) => {


        // ActivityChat.watch().on('change',async (change)=>{
        //
        // A watch function is there for ActivityChat
        //
        // })
        //
        // Notification.watch().on('change',async (change)=>{
        //
        // A watch function is there for Notification
        //
        // })


    })

If you receive several getNotifications events, you will have a bunch of open change streams, which can clog up your connection pool as described here: https://www.mongodb.com/docs/manual/changeStreams/#change-stream-performance-considerations.

Does your server receive multiple getNotifications events, or is getNotifications an event that gets received at most once per server? If multiple, you would move the ActivityChat.watch() and Notification.watch() calls outside of the event handler so you only keep max 3 change streams per server.

@vkarpov15 vkarpov15 added the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Apr 6, 2025
@vkarpov15 vkarpov15 removed this from the 8.13.3 milestone Apr 6, 2025
@AndrewsSharvinFindmena
Copy link
Author

The getNotifications event is called once every time a user logs in or opens an additional tab. But the problem isn't with the watch() functions, because I tested the server without the watch() function, and the same thing happened, so I don't think it is the issue.

@vkarpov15
Copy link
Collaborator

Ok, what about:

// Trends.watch().on('change',(change)=>{
//
//  Another Watch Function
//
// })

What's "Another Watch Function"?

Also, I see a reconnect parameter to your connect() function, what is that parameter used for?

@AndrewsSharvinFindmena
Copy link
Author

I added a reconnect parameter if needed any reconnect function but right now, I don't have any reconnect mechanism, the comment " Another Watch Function " is there not to say there is another watch function inside Trends.watch(), I'm, trying to say that it is just another watch function, total there is only 3 watch function

@vkarpov15
Copy link
Collaborator

Another possibility is that, given you have 4-5 hours of inactivity, the MongoDB driver's sockets are timing out. You might try setting keepAlive: true on mongoose.connect() to have the MongoDB driver try to keep the sockets open, but there's no guarantee that keepAlive will work in all cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary
Projects
None yet
Development

No branches or pull requests

2 participants