ASP.NET Core  

Benchmarking HybridCache vs Redis in ASP.NET Core 11

Caching is one of the most effective ways to improve the performance of ASP.NET Core applications. It reduces database load, decreases response times, and improves scalability. Traditionally, distributed caching with Redis has been the preferred choice for cloud-native applications. However, ASP.NET Core 11 introduces improvements around HybridCache, which combines the speed of in-memory caching with the reliability of distributed caching through a single API.

If you're building high-traffic APIs, understanding when to use HybridCache instead of Redis—or together with Redis—is important.

In this article, you'll learn how HybridCache works, how it compares to Redis, how to implement both approaches, and how to design your own benchmark methodology without relying on fabricated performance numbers.

Note: This article intentionally does not include benchmark results because no benchmark environment or measurements were provided in the research brief. Instead, it explains how to perform reproducible benchmarks in your own environment.

What Is HybridCache?

HybridCache is a caching abstraction introduced in ASP.NET Core that simplifies cache access while supporting multiple cache layers.

Instead of manually checking memory cache first and then Redis, HybridCache handles this workflow through a unified API.

Typical cache flow:

Application
      │
      ▼
 HybridCache
      │
 ┌────┴────┐
 ▼         ▼
Memory   Redis
 Cache    Cache
      │
      ▼
 Database

The first request loads data from the database, stores it in cache, and subsequent requests are served from cache until expiration.

How Redis Differs

Redis is a distributed cache that runs as an independent server.

Instead of storing data inside your application process, Redis stores cached values externally, allowing multiple application instances to share the same cache.

Advantages include:

  • Shared cache across servers

  • High availability

  • Large cache capacity

  • Suitable for cloud deployments

The tradeoff is network latency because every cache lookup requires communication with the Redis server.

HybridCache vs Redis

FeatureHybridCacheRedis
In-memory cacheYesNo
Distributed cacheYes (when configured)Yes
Single APIYesNo
Network round-tripOften avoidedRequired
Multi-server supportYesYes
Best forHigh-performance applicationsDistributed systems

HybridCache is not intended to replace Redis. Instead, it provides a cleaner programming model while allowing Redis to remain the distributed cache.

Creating an ASP.NET Core Project

Create a new Web API.

dotnet new webapi -n HybridCacheDemo

Install the Redis package.

dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis

Configure Redis.

{
  "ConnectionStrings": {
    "Redis": "localhost:6379"
  }
}

Configuring HybridCache

Register HybridCache and Redis.

using Microsoft.Extensions.Caching.StackExchangeRedis;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration =
        builder.Configuration.GetConnectionString("Redis");
});

builder.Services.AddHybridCache();

var app = builder.Build();

app.Run();

The application now supports HybridCache backed by Redis.

Implementing a Repository

Assume a repository fetches product information.

public class ProductRepository
{
    public async Task<Product> GetByIdAsync(int id)
    {
        await Task.Delay(500);

        return new Product
        {
            Id = id,
            Name = "Laptop",
            Price = 950
        };
    }
}

The delay simulates an expensive database operation.

Using HybridCache

Inject HybridCache into your service.

public class ProductService
{
    private readonly HybridCache _cache;
    private readonly ProductRepository _repository;

    public ProductService(
        HybridCache cache,
        ProductRepository repository)
    {
        _cache = cache;
        _repository = repository;
    }

    public async Task<Product> GetProductAsync(int id)
    {
        return await _cache.GetOrCreateAsync(
            $"product:{id}",
            async token =>
            {
                return await _repository.GetByIdAsync(id);
            },
            expiration: TimeSpan.FromMinutes(10));
    }
}

Why This Approach?

Instead of writing:

  • Check memory cache

  • Check Redis

  • Query database

  • Save to both caches

HybridCache performs these steps through a single API, reducing repetitive caching code and making cache management easier.

Using Redis Directly

The equivalent Redis implementation is more manual.

public class ProductService
{
    private readonly IDistributedCache _cache;
    private readonly ProductRepository _repository;

    public ProductService(
        IDistributedCache cache,
        ProductRepository repository)
    {
        _cache = cache;
        _repository = repository;
    }

    public async Task<Product> GetProductAsync(int id)
    {
        string key = $"product:{id}";

        var cached =
            await _cache.GetStringAsync(key);

        if (!string.IsNullOrEmpty(cached))
        {
            return JsonSerializer.Deserialize<Product>(cached)!;
        }

        var product =
            await _repository.GetByIdAsync(id);

        await _cache.SetStringAsync(
            key,
            JsonSerializer.Serialize(product));

        return product;
    }
}

This approach provides full control but requires more boilerplate code.

End-to-End Request Flow

A typical request follows these steps:

  1. Client requests product information.

  2. HybridCache checks the in-memory cache.

  3. If not found, it checks Redis.

  4. If still unavailable, the database is queried.

  5. The response is stored in cache.

  6. Future requests return cached data.

This pattern minimizes unnecessary database access while maintaining consistency across multiple application instances.

Benchmark Methodology

The research brief did not include benchmark results or a testing environment, so this section describes how to perform meaningful benchmarks instead of presenting unsupported numbers.

Test Environment

Keep the environment consistent:

  • Same hardware

  • Same .NET SDK

  • Same ASP.NET Core version

  • Same Redis version

  • Same dataset

Test Scenarios

Measure:

  • Cold cache performance

  • Warm cache performance

  • High concurrency

  • Mixed read/write workloads

  • Large object caching

  • Small object caching

Metrics to Capture

Collect:

  • Average response time

  • P95 latency

  • P99 latency

  • Throughput (requests/sec)

  • CPU usage

  • Memory consumption

  • Redis network traffic

  • Cache hit ratio

Suggested Tools

Useful tools include:

  • BenchmarkDotNet

  • k6

  • Apache JMeter

  • dotnet-counters

  • dotnet-trace

Because workload characteristics vary across applications, benchmark results should always be collected using production-like traffic patterns rather than synthetic assumptions.

When Should You Use Each?

ScenarioRecommended Choice
Single application serverHybridCache
Multiple application serversHybridCache with Redis
Large distributed systemsRedis
Frequently accessed reference dataHybridCache
Session storageRedis
High-performance APIsHybridCache with Redis

Best Practices

  • Cache frequently accessed data rather than every query.

  • Use meaningful cache keys with consistent naming.

  • Choose expiration times based on business requirements.

  • Avoid caching rapidly changing data unnecessarily.

  • Monitor cache hit ratios in production.

  • Invalidate cache after data updates.

  • Keep cached objects reasonably small.

  • Use Redis for shared application state across multiple instances.

Common Mistakes

MistakeImpact
Caching everythingWasted memory
Very long expiration timesStale data
Very short expiration timesFrequent cache misses
Ignoring cache invalidationIncorrect responses
Large serialized objectsIncreased memory usage
Using only memory cache in a scaled environmentInconsistent data between servers

Troubleshooting

Cache Always Misses

Verify:

  • Cache key names are consistent.

  • Expiration has not elapsed.

  • Redis is connected.

  • Objects are successfully serialized.

Redis Connection Errors

Check:

  • Redis server availability.

  • Connection string.

  • Firewall settings.

  • Network connectivity.

Memory Usage Keeps Growing

Review:

  • Cache expiration policies.

  • Object sizes.

  • Number of cached entries.

  • Memory limits.

FAQs

Does HybridCache replace Redis?

No. HybridCache can use Redis as its distributed cache while simplifying cache access through a unified API.

Can HybridCache work without Redis?

Yes. It can operate with in-memory caching only, though distributed scenarios benefit from configuring Redis.

Should every database query be cached?

No. Cache data that is read frequently and changes infrequently. Highly dynamic data may not benefit from caching.

Is HybridCache suitable for microservices?

Yes. When combined with a distributed cache such as Redis, HybridCache works well in microservice architectures where multiple service instances need consistent cached data.

Which benchmark is most important?

There is no universal benchmark. Measure latency, throughput, resource usage, and cache hit ratio using workloads that closely resemble your production environment.

Conclusion

HybridCache simplifies caching in ASP.NET Core by providing a unified API that can combine fast in-memory caching with distributed caching through Redis. Compared to using Redis directly, it reduces boilerplate code while preserving the benefits of a shared cache for multi-instance deployments.

Rather than relying on generic performance claims, evaluate HybridCache and Redis using reproducible benchmarks that reflect your application's workload. Measuring latency, throughput, memory usage, and cache efficiency in a production-like environment will provide the data needed to choose the right caching strategy for your applications.