2

I have a .net core application in which I am using c# and MongoDB. Within the application, I am using MongoDB driver (Version 2.7) for any database related operation and I have a MongoDB database (Version 4.0.9). I am facing one strange issue and not able to find out the root cause for it. The very first request to the database is taking significantly more time than the subsequent requests. As an example, if the first request is taking 1 second and if we make immediate more requests it is taking ~200-250 milliseconds

Does anyone know the solution to the above situation?

Bhushan Shah
  • 121
  • 1
  • 1
  • 6

1 Answers1

2

this is not an error. it is the default behavior of the c# driver. the driver only establishes the connection to the database server when the very first operation is initiated and will take a few hundred milliseconds to establish connection.

subsequent operations do not need to establish new connections because of the driver's connection pooling mechanisms. more connections will only be established only if they are really needed. if the app is not multi-threaded, the driver will usually open about 2 connections for the entirety of the app from what i have seen. if you inspect your mongodb log file, it will be apparent.

my suggestion is to just ignore the time it takes to initialize the connection if you're doing any kind of testing/ benchmarks.

UPDATE:

if your database is hosted across a network, something like a firewall may be interfering with idle connections. if that's the case you could try doing the following so that idle connections get recycled/renewed every minute.

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1)

if all else fails to work, the only remaining option i can think of is to fire off a keep-alive task like the following:

        public void InitKeepAlive()
        {
            Task.Run(async () =>
            {
                while (true)
                {
                    await client.GetCollection<Document>("Documents")
                                .AsQueryable()
                                .Select(d => d.Id)
                                .FirstOrDefaultAsync();
                    await Task.Delay(TimeSpan.FromMinutes(1));
                }
            });            
        }
Dĵ ΝιΓΞΗΛψΚ
  • 5,068
  • 3
  • 13
  • 26
  • Thanks, @Ryan for the response. I understand it takes more time to the first operation but what about the scenario where we did multiple requests and after that app is idle for 20-30 minutes or even 15 minutes, if we do make a request, it is again taking significantly more time. What I am looking is to have a consistent performance so that I have an idea how the app is behaving. – Bhushan Shah May 14 '19 at 18:02
  • @BhushanShah are you not re-using the mongo client? if not, can you try making the mongo client a singleton/ static class and see? because established connections in the mongodb pool should only close when the app terminates. if already using as a singleton, try setting the [max connection idle time](https://docs.mongodb.com/manual/reference/connection-string/#maxIdleTimeMS) to a large value. if you'd like to see how i use the client as a singleton, check out the source code of [the wrapper library](https://github.com/dj-nitehawk/MongoDB.Entities) i've written for mongodb. – Dĵ ΝιΓΞΗΛψΚ May 15 '19 at 02:22
  • Thanks, @Ryan for the response. I am using static class only and also kept max connection idle time as 60 minutes. Still, if I make a couple of request at 10:05 AM and then I make another couple of requests at 10:25 AM, the second batch of requests are taking more time but if I make a request at 10:06 AM or 10:07 AM or 10:08 AM, I am getting response pretty fast. What I would like to achieve is that, even if I make a request after 30-40 minutes from the first request, I should get a response quickly. Any suggestions on it? – Bhushan Shah May 15 '19 at 21:19
  • @BhushanShah i updated my answer above with a couple more suggestions. – Dĵ ΝιΓΞΗΛψΚ May 16 '19 at 01:57
  • The .NET driver seems to have no client option to set the TCP socket KeepAlive to true, like the Java driver has. I got here from https://stackoverflow.com/questions/35597930/sockettimeout-with-opened-connection-in-mongodb but I'm also using the C# driver. – Markus May 28 '20 at 13:22