.NET 9 is now live, and it comes with a new set of features. Some are great, and some are just icing on the cake. But what really stands out is the new HybridCache
!
HybridCache is not just another caching API in .NET; it’s designed to solve problems we didn’t even know we had. It combines the best of two worlds by bridging the gap between IMemoryCache
and IDistributedCache
. It also introduces advanced features like cache stampede protection and efficient serialization.
In this blog, I’m going to review the existing caching mechanisms, highlight their strengths and weaknesses, and demonstrate how to implement the new HybridCache
. We’ll see how it simplifies caching and makes it incredibly easy to use.
Download the source code from here
You can also watch my YouTube video on the same topic here: https://youtu.be/PDIKTbbkmCk
Understanding Existing Caching Mechanisms
IMemoryCache
The IMemoryCache
provides fast, in-memory caching within the application’s process. It has also few limitations, such as the cache is limited to only a single instance and data is lost if the application restarts or craches.
IDistributedCache
In the other hand, IDistributedCache
offers a caching mechanism that can be shared across multiple instances, giving you the ability to preserve and distribute cache data across your distributed system. And as for the drawbacks, accessing the distributed cache can be slower than the in-memory cache due to network overhead, and it does require additional setup and configuration.
Introducting HybridCache
HybridCache
in .NET 9 combines both IMemoryCache
and IDistributedCache
, providing a unified API that leverages a two level caching strategy:
- Primary Cache (L1): In-memory cache for fast access.
- Secondary Cache (L2): Distributed cache for scalability and persistance
HybridCache
comes with some interesting features, one of which is the cache stampede protenction, where it prevents multiple concurrent requests from overwhelming the data source by ensuring only one request populate the cache for a given key.
It also support various serialization options, making it a serialization optimized solution where you can chose the right option for your application.
And my favorite option is, the tag based invalidation, where it enables you to invalidate a group of cache entries related to a specific tag for efficient invalidations.
Implementing HybridCache
First, you need to install the nuget package
dotnet add package Microsoft.Extensions.Caching.Hybrid --version "X.X.X" # add the latest version here
Then you need to register the HybridCache
inside your DI
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddHybridCache();
You can also configure options such as serialization and cache entry settings:
builder.Services.AddHybridCache(options =>
{
options.MaximumPayloadBytes = 1024 * 1024; // 1 MB
options.MaximumKeyLength = 1024;
options.DefaultEntryOptions = new HybridCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(5),
LocalCacheExpiration = TimeSpan.FromMinutes(5)
};
});
And to use it in your application, simply inject the HybridCache
into your service or endpoint and use it to cache data:
public class BookService
{
private readonly HybridCache _hybridCache;
public BookService(HybridCache hybridCache)
{
_hybridCache = hybridCache;
}
public async Task<Book?> GetBookAsync(int id)
{
var key = $"book-{id}";
return await _hybridCache.GetOrCreateAsync(key, async (cancellation) =>
{
// Get the book from the database
});
You can also use _hybridCache.SetAsync
to set the cache directly.
public async Task<Book?> UpdateYearAsync(int id, int year)
{
var book = await _context.Books.FindAsync(id);
if (book is null) return null;
book.Year = year;
await _context.SaveChangesAsync();
await _hybridCache.SetAsync($"book-{id}", book);
return book;
}
Or you can use _hybridCache.RemoveAsync
to remove and invalidate a cache entry
await _hybridCache.RemoveAsync($"book-{id}");
HybridCache
in .NET 9 offers a robust solution for caching by combining the speed of in-memory access with the scalability of distributed caching. Its advanced features like stampede protection and configurable serialization make it a valuable addition to any .NET application.
Happy Coding!