The cache eviction algorithm for query plan caching in Entity Framework is described in section 3.2.2 as this:
Once the cache contains a set number of entries (800), we start a timer that periodically (once‐per‐minute) sweeps the cache.
During cache sweeps, entries are removed from the cache on a LFRU (Least frequently – recently used) basis. This algorithm takes both hit count and age into account when deciding which entries are ejected.
At the end of each cache sweep, the cache again contains 800 entries.
Whenever an attempt to execute a query is made, the query pipeline looks up its query plan cache to see whether the exact query is already compiled and available. If so, it reuses the cached plan rather than building a new one. If a match is not found in the query plan cache, the query is compiled and cached.
Question
Why is the cache being reduced to 800 entries and not Min(800, all_cached_queries_below_some_ratio)?
In a hypothetical scenario where I have one cached query used extensively which is used 80% of the time and 799 others which are used once. From this point on, each time I start using a new frequently used query, it will trigger a sweep to remove one of the non-frequently used queries and store the new one.
Granted, this only happens once every 60 seconds but it doesn't strike me as the cheapest action there is.