question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Kestrel memory pool does not reliably decrease with load

See original GitHub issue

Describe the bug

While load testing a new service using SignalR, we noticed that memory usage does not always decrease after connections drop off. Sometimes it decreases a minute or two after the connections end, but sometimes it just never recovers. This causes us two problems:

  1. When an instance nears its memory limit, it will reject new connections (achieved using custom middleware that responds with a 503) in order to protect its existing connections. But since memory usage does not decrease, the instance will never accept new connections, even after most of its existing connections end
  2. Our service autoscales on memory, but because memory usage stays high our service will rarely scale-down when under low load. This is less of a problem, it just costs a bit to run with extra capacity

This shows memory usage increasing with number of connections (tracked using the OnConnectedAsync/OnDisconnectedAsync methods of our Hub), but not reliably decreasing afterwards:

image

The service is running in an Alpine 3.12 docker container, but we notice similar behaviour when running locally in Windows 10. We initially assumed this was a simple memory leak, but when making a large number of connections over time while keeping the number of concurrent connections low, memory usage does not increase.

When taking a heap dump, we see memory fairly dominated by Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets!Buffers.MemoryPoolBlock:

image

To Reproduce

  1. Make a large number of concurrent connections to a SignalR Core service
  2. End connections
  3. Monitor memory - it should decrease, but usually does not

Further technical details

  • ASP.NET Core version 3.1.6, using docker image based on mcr.microsoft.com/dotnet/core/aspnet:3.1.6-alpine3.12
  • Built with SDK 3.1.302, using docker image based on mcr.microsoft.com/dotnet/core/sdk:3.1.302-alpine3.12
  • Reproduced locally on Windows 10 using ASP.NET Core 3.1.6, SDK 3.1.202

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
BrennanConroycommented, Aug 17, 2020

Kestrel will pool internal buffer up to a limit and will not let them go. We should consider having a settable limit or release strategy for the pool.

cc @halter73

0reactions
adityamandaleekacommented, Feb 15, 2022
Read more comments on GitHub >

github_iconTop Results From Across the Web

ASP.NET Core Best Practices
By Mike Rousos. This article provides guidelines for maximizing performance and reliability of ASP.NET Core apps.
Read more >
Performance improvements in ASP.NET Core 7
NET 7 brings a great amount of performance improvements to ASP.NET Core developers. Find out what is new and how to take adavantage...
Read more >
Solving complex performance problems in .NET Core ...
Join performance expert Matt Warren for a tutorial on solving complex problems in .NET Core, and how Raygun APM can help.
Read more >
Why ASP Net Core 2.2 do not release memory?
In theory, the application should be able to reduce its memory footprint when your server faces a memory pressure.
Read more >
Cold start? Why does my application take a long time to ...
The initially request usually doesn't matter because if the app is utilized enough, connections will remain in the connection pool thereafter.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found