Технически это продолжение публикации Как не дать пользователю заснуть во время загрузки большого набора данных. Провожу "капитальный рефакторинг" корпоративной системы, которая используется 20 лет. Некоторые свои решения излагаю здесь в надежде, что кому-то пригодится, а также чтобы узнать что-то новое из комментариев. Как следует из упомянутой публикации, разрабатываемый сервер является "stateful" хотя бы потому, что загрузка данных для подкачки происходит между последовательными запросами клиента. Также полноценная сессия может понадобиться для каких-то других задач.  Соглашаясь с мнением в комментариях, что это ограничивает масштабируемость, всё же считаю, что инструмент должен соответствовать задаче. Для высоконагруженной системы с миллионами запросов в секунду важна распределённость, но за неё мы платим необязательностью предоставления актуальных данных в конкретный момент. Ни того ни другого нельзя сказать о системе, в которой при самых оптимистичных предположениях будет работать сотня операторов. Так что предположим, что запрос на полноценные сессии всё же имеется. И эти сессии надо как-то утилизировать после окончания их срока жизни. Навскидку можно предложить следующие решения.  Запуск параллельной задачи при очередном запросе с клиента. Запуск специального потока. Использование таймера. Всё же осмелюсь предложить ещё одну идею. А давайте поручим убирать "мусор", то есть сессии с истекшим "сроком годности" сборщику мусора. Идея подписки на событие сборки мусора не моя, встречал её применение в демонстрационных целях и немного переработал на свой лад.  Мы вводим в систему источник события сборки мусора и каждую сессию на него подписываем. Когда событие происходит, сессия сама смотрит, стухла она или нет и в случае положительного ответа самоудаляется из словаря. Дальше в тексте будем называть сессию, на которую есть ссылка в словаре, присоединённой. Класс-источник события сборки мусора GCNotifier.cs: Соответствующий делегат и его аргумент GCEvent.cs: Базовый класс сессии, которая это умеет GCManagedSession.cs: Мы будем в течение определённого времени совершать запросы с клиента на сервер из нескольких потоков. Сервер будет создавать какое-то количество объектов и возвращать статистику, которую мы будем показывать в интерфейсе клиента. Будет вариант с сессиями и без сессий, чтобы сравнить.  Чтобы испытать, как всё работает, создадим в VisualStudio Studio  Community 2022 три проекта. Исходники доступны  тут. GCMSessionContract -  библиотека классов, общих для сервера и клиента. Здесь находится класс с некоторыми константами и интерфейс класса для сбора и передачи статистики на клиента.   GCMSessionServer -  проект ASP.NET Core.  В Program.cs Мы обрабатываем три маршрута с параметрами:   В классе HardWorker расположен метод наполняющий лист какими-то ненужными объектами. Так мы влияем на  частоту сборки мусора. Класс Session унаследован от GCManagedSession. Мы выводим кое-что на консоль и сообщаем статистике при отсоединении сессии. Класс Stat реализует интерфейс IStat, также содержит методы для сбора статистики. Для краткости не буду приводить его полностью, можно при желании посмотреть в исходнике. GCMSessionClient -  проект WPF. Разметку рассматривать не будем, а в code-behind для  простоты размещены методы, посылающие много запросов на сервер и отображающие статистику. Код для краткости привожу не полностью, он доступен в  исходниках.    Запустим сервер и клиент.  Будем из 10 потоков в течение 60 секунд делать запросы на создание 1000000 объектов без сессий. Получилось 374 запроса в среднем по 1.4 секунды. Теперь запустим с теми же параметрами с сессиями живущими по 10 секунд. Видим, как и ожидали, что полное количество открытых сессий CountSessionsTotal равно количеству запросов CountRequests, 387. Количество одновременно присоединённых сессий стабилизировалось на уровне ~80, при этом каждая сессия в среднем является присоединённой после истечения около 1.8 секунд. Также мы видим, что нет заметной разницы в производительности между работой с сессиями и без них. Использование сборщика мусора для инициирования утилизации истекших сессий представляется жизнеспособной идеей. Кажется, в этом случае проверка сессий на возможность утилизации происходит в "ритме" необходимой очистки памяти в конкретных условиях работы сервера, а не по воле разработчика или какой-то специальной настройки. Обновление: благодарю @Politura - комментарий о MemoryCache оказался очень полезным! Проверил и решил так и сделать.