Testing Caching Strategies in .NET Core

Masoud Banimahd
3 min readJan 28, 2025

--

In this article, we’re going to prepare a simple test in .NET and use k6 for load testing to evaluate different caching strategies, including In-Memory Cache, Hybrid Cache, and Fusion Cache. We’ll examine their performance and see how well they address common issues like cache stampede, system overload, and data consistency.

What is Cache Stampede?
Cache stampede occurs when a cached item expires, and multiple requests hit the system at once, all trying to recreate the same data. This can put too much pressure on your database or external services, especially in high-traffic applications, and lead to slower performance or system issues.

The Three Contenders

We’ll compare three different caching implementations:

  • Memory Cache: The built-in ASP.NET Core caching solution
  • Hybrid Cache: Microsoft’s new preview library combining in-memory and distributed caching
  • Fusion Cache: A specialized library with built-in stampede protection

Implementation Details

Let’s look at how each caching strategy is implemented:

You can find the code in this repository:
https://github.com/dev3mike/dotnet-cache-strategies

1. Memory Cache Implementation

var cachedValue = await memoryCache.GetOrCreateAsync("memory-cache", async (entry) =>
{
await Task.Delay(3000); // Simulated database delay
return "Data from the database";
}, new MemoryCacheEntryOptions() { SlidingExpiration = TimeSpan.FromSeconds(1) });

2. Hybrid Cache Implementation

var cachedValue = await hybridCache.GetOrCreateAsync("hybrid-cache", async (entry) =>
{
await Task.Delay(3000); // Simulated database delay
return "Data from the database";
}, new HybridCacheEntryOptions
{
LocalCacheExpiration = TimeSpan.FromSeconds(1),
});

3. Fusion Cache Implementation

var cachedValue = await fusionCache.GetOrSetAsync("fusion-cache", async (entry) =>
{
await Task.Delay(3000); // Simulated database delay
return "Data from the database";
}, TimeSpan.FromSeconds(1));

Load Testing Setup

To compare these implementations, we created a comprehensive load testing scenario using k6:

  • Test Duration: 6 seconds total
  • Load Pattern:
  • 0–2s: Ramp up to 100 users
  • 2–4s: Ramp up to 1000 users
  • 4–6s: Ramp down to 0 users
  • Performance Thresholds: 95% of requests should complete under 2 seconds
  • Failure rate should be less than 10%

Performance Results

Memory Cache Performance

  • ✅ 100% success rate (1,272 requests)
  • ⚠️ Average request duration: 1.45s
  • ⚠️ Maximum request duration: 3.16s
  • ❌ Failed p95 threshold requirement (p(95)<2000)
  • 📊 Total iterations: 1,272

Hybrid Cache Performance

  • ✅ 100% success rate (1,763 requests)
  • ✅ Average request duration: 1.52s
  • ⚠️ Maximum request duration: 3.01s
  • ❌ Failed p95 threshold requirement (p(95)<2000)
  • 📊 Total iterations: 1,763

Fusion Cache Performance

  • ✅ 100% success rate (1,760 requests)
  • ⚠️ Average request duration: 1.59s
  • ⚠️ Maximum request duration: 3.14s
  • ❌ Failed p95 threshold requirement (p(95)<2000)
  • 📊 Total iterations: 1,760

Key Findings and Recommendations

  • Hybrid Cache: The Winner
  • Best overall performance with 1.52s average response time
  • Handled the highest number of requests (1,763)
  • Successfully managed high concurrency
  • Fusion Cache: The Specialist
  • Built-in stampede protection
  • Similar performance to Hybrid Cache
  • Good for most of the scenarios especially when stampede protection is critical
  • More complex implementation than Memory Cache
  • Memory Cache: The Basic Solution
  • Simple implementation
  • Moderate performance
  • Suitable for low-traffic applications
  • No built-in stampede protection

When to Use Each Strategy

1. Choose Hybrid Cache when:

  • You need the best overall performance
  • Your application handles high traffic
  • You want both in-memory and distributed caching capabilities
  • Performance is your top priority

2. Choose Fusion Cache when:

  • You need the best overall performance (similar to hybrid approach)
  • Your application handles high traffic
  • Cache stampede protection is critical
  • You need fine-grained control over caching behavior
  • You can tolerate slightly higher latency for better protection
  • You need built-in failure handling

3. Choose Memory Cache when:

  • You have a simple application with low traffic
  • You need a straightforward implementation
  • You don’t need distributed caching
  • Resource usage is a concern

Performance testing shows that Microsoft’s Hybrid Cache and Fusion Cache deliver nearly identical results, both achieving a 100% success rate and comparable average request durations (1.52s for Hybrid Cache and 1.59s for Fusion Cache).

However, since Hybrid Cache is still in its preview phase and not yet production-ready, Fusion Cache stands out as the best available solution for production environments.

But in general when implementing caching in your .NET applications, consider your specific needs around performance, scalability, and protection against cache stampede to choose the most appropriate solution.

Remember that these results are based on specific test scenarios, and your actual performance may vary depending on your use case, infrastructure, and load patterns. Always perform thorough testing in your specific environment before making a final decision.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Masoud Banimahd
Masoud Banimahd

Written by Masoud Banimahd

Experienced Full-stack Engineer | NodeJS & .NET Pro | Tech Enthusiast | Knowledge Seeker - Reach me : https://masoudb.com/

No responses yet

Write a response