March 12th, 2025

Hello HybridCache! Streamlining Cache Management for ASP.NET Core Applications

Claudia Regio
Senior Product Manager

HybridCache is a new .NET 9 library available via the Microsoft.Extensions.Caching.Hybrid package and is now generally available! HybridCache, named for its ability to leverage both in-memory and distributed caches like Redis, ensures that data storage and retrieval is optimized for performance and security, regardless of the scale or complexity of your application.

Why use HybridCache?

HybridCache reliably simplifies the boilerplate code like object serialization, cache-aside pattern implementation, and data consistency down to a single line of code. It also optimizes the data performance by combining in-memory and distributed cache stores enabling the application to run faster. If you’re building ASP.NET Core applications that use repeated or complicated data queries, have a microservice-based architecture, or require real-time data processing, you should use HybridCache to improve the performance and responsiveness of your applications.

Key features

  • Built on top of IDistributedCache which means it is compatible with all existing cache backends such as Redis, SQL Server, CosmosDB, Garnet, etc.
  • Simple and easy-to-use API
  • Cache-stampede protection
  • Cache invalidation with tags
  • Performance enhancements such as inbuilt support for the newer IBufferDistributedCache API
  • Fully configurable serialization for JSON and Protobuf
  • Secure-by-default with authentication and data handling

Keep reading to learn more about the key features!

Simple API – GetOrCreateAsync

If you’ve previously tried caching in your ASP.NET Core applications, you may be familiar with other abstractions such as IDistributedCache or IMemoryCache. With these you’d have to write the code to generate keys, try to retrieve the data matching the key from the cache, deserialize the data if it does exist in the cache, or serialize the data and push it into the cache if it did not exist. This is a very manual process and hooking up all the different components is time consuming, requires the knowledge of multiple APIs, and is difficult to get right.

// This is the code without HybridCache
public class SomeService(IDistributedCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        var key = $"someinfo:{name}:{id}"; // Unique key for this combination.
        var bytes = await cache.GetAsync(key, token); // Try to get from cache.
        SomeInformation info;
        if (bytes is null)
        {
            // Cache miss; get the data from the real source.
            info = await SomeExpensiveOperationAsync(name, id, token);

            // Serialize and cache it.
            bytes = SomeSerializer.Serialize(info);
            await cache.SetAsync(key, bytes, token);
        }
        else
        {
            // Cache hit; deserialize it.
            info = SomeSerializer.Deserialize<SomeInformation>(bytes);
        }
        return info;
    }

    // This is the work we're trying to cache.
    private async Task<SomeInformation> SomeExpensiveOperationAsync(string name, int id,
        CancellationToken token = default)
    { /* ... */ }
}

HybridCache simplifies the cache-aside pattern down to one single line of code while significantly accelerating your application data performance.

// Same code as above, now using HybridCache
public class SomeService(HybridCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        return await cache.GetOrCreateAsync(
            $"someinfo:{name}:{id}", // Unique key for this entry.
            async cancel => await SomeExpensiveOperationAsync(name, id, cancel),
            token: token
        );
    }
}

Cache-stampede protection

A cache stampede occurs when multiple clients request the same data simultaneously after it expires from the cache, leading to a surge of redundant computations and database queries. This can significantly slow down a web application and degrade the user experience, especially under high traffic conditions. HybridCache prevents cache stampedes by ensuring that when multiple requests for the same data arrive, it only performs the necessary computations once. Instead of allowing every request to independently regenerate the data, HybridCache detects the situation, processes the request a single time, and returns the result to all queued requests. This approach maintains data consistency and optimizes performance at scale.

Cache invalidation with tags

When you add an item to a cache, you can assign one or more tags to it, which are simply string values that help categorize this data. HybridCache now makes it easier to manage and invalidate data in bulk via tagging. For example, when needing to invalidate many items at a time from a cache, instead of deleting the keys one-by-one, you can delete all items with a specific tag with one API call. You can even delete items with multiple tags at a time simply by passing a set of tags. It’s no longer necessary to rely exclusively on unique keys for identifying, grouping, and deleting data from the cache.

Summary

With all these new features hot off the press, it’s time to try the new .NET 9 HybridCache! To get started or learn more, visit the documentation.

Author

Claudia Regio
Senior Product Manager

0 comments