Uh oh!
There was an error while loading. Please reload this page.
Add an in-memory cache for CRLs on Linux - #123562
Conversation
Tagging subscribers to this area: @bartonjs, @vcsjones, @dotnet/area-system-security |
bartonjs
commented
Jan 23, 2026
Testing with a cert that has a large CRL, revocation-enabled chain building is significantly reduced. This is from building a chain 5 times in a row, the last build: Before: After: |
There was a problem hiding this comment.
Pull request overview
This PR introduces an in-memory LRU cache layer for Certificate Revocation Lists (CRLs) on Linux to improve performance by reducing disk I/O. The cache sits between the caller and the existing disk cache, with a fixed capacity of 30 entries that evicts least-recently-used items when full. The implementation uses a GC-based pruning mechanism similar to ArrayPool, where a finalizable sentinel object triggers periodic cache cleanup to manage memory pressure.
Changes:
- Added 5 new event source events for tracking in-memory cache hits, misses, expiration, pruning, and capacity events
- Updated existing event messages to clarify they refer to disk cache operations
- Implemented MruCrlCache class with thread-safe LRU eviction, reference counting via DangerousAddRef/DangerousRelease, and GC-triggered pruning
- Refactored CRL loading to check in-memory cache first, then disk cache, then download
- Added proper SafeHandle management to prevent premature finalization during cache operations
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 12 comments.
| File | Description |
|---|---|
| OpenSslX509ChainEventSource.cs | Added 5 new event IDs and methods for in-memory cache telemetry; updated existing event messages to distinguish disk cache operations |
| OpenSslCrlCache.cs | Added MruCrlCache class implementing thread-safe LRU cache with GC-based pruning; refactored CRL loading logic to check memory cache before disk; added proper SafeHandle reference management |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
grbell-ms
commented
Jan 23, 2026
Might be simpler to check directly with |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
bartonjs
commented
Feb 4, 2026
Verified with a high memory utilization app (just makes a bunch of HTTPS requests to a large-enough number of different endpoints that it's not always just one CRL) that purge still runs with the GC.GetGeneration deferral check. |
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
bartonjs
commented
Apr 29, 2026
/backport to release/10.0 |
Started backporting to |
bartonjs
commented
Apr 29, 2026
/backport to release/9.0-staging |
Started backporting to |
bartonjs
commented
Apr 29, 2026
/backport to release/8.0-staging |
Started backporting to |
Introduce an extra layer of caching for CRLs.
This implementation ignores any finalizations that happen in the first minute of the sentinel object's life, to allow the object a chance to get into Gen2 before hyper-eagerly evicting things.