BlitzCache 2.0.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package BlitzCache --version 2.0.2
                    
NuGet\Install-Package BlitzCache -Version 2.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BlitzCache" Version="2.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BlitzCache" Version="2.0.2" />
                    
Directory.Packages.props
<PackageReference Include="BlitzCache" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BlitzCache --version 2.0.2
                    
#r "nuget: BlitzCache, 2.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BlitzCache@2.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BlitzCache&version=2.0.2
                    
Install as a Cake Addin
#tool nuget:?package=BlitzCache&version=2.0.2
                    
Install as a Cake Tool

⚡ BlitzCache

NuGet NuGet Downloads Tests codecov License: MIT .NET Standard

🚀 Enterprise-grade caching that's ridiculously simple to use

One line of code prevents duplicate execution of expensive operations. BlitzCache is production-ready, ultra-fast (0.0001ms operations), and completely thread-safe. No configuration required.

✨ Why BlitzCache?

The Problem: Multiple concurrent calls = Multiple expensive operations

// Without BlitzCache: Expensive operations run multiple times
Task.Run(() => ExpensiveApiCall()); // Executes
Task.Run(() => ExpensiveApiCall()); // Executes again! 💸
Task.Run(() => ExpensiveApiCall()); // And again! 💸💸

The Solution: One line of code changes everything

// With BlitzCache: One execution, all callers get the result
Task.Run(() => cache.BlitzGet("api-call", ExpensiveApiCall)); // Executes once
Task.Run(() => cache.BlitzGet("api-call", ExpensiveApiCall)); // Waits for result ⏳
Task.Run(() => cache.BlitzGet("api-call", ExpensiveApiCall)); // Waits for result ⏳
// All concurrent calls receive the SAME result when the first one completes!

🛡️ The Thundering Herd Protection

// Scenario: 100 users hit your API at the exact same moment
for (int i = 0; i < 100; i++)
{
    Task.Run(async () => {
        // Without BlitzCache: 100 SQL queries hit your database simultaneously 💥
        // With BlitzCache: Only 1 SQL query executes, 99 others wait and get the result ⚡
        var userData = await cache.BlitzGet($"user_{userId}", 
            () => database.GetSlowUserData(userId), 
            300000);
    });
}

📊 Automatic Statistics

[12:51:32 INF] ***[Customers-Microservice] BlitzCache Statistics***
Hits: 22
Misses: 24
Hit Ratio: 47.83 %
Entries: 2
Evictions: 20
Active Semaphores: 0
Total Operations: 46
Top Slowest Queries:
        LoadBlitzSafe_UsageFromView_819735987 - Worse: 18266ms | Best: 93ms | Avg: 2014 | Occurrences: 10
        LoadBlitzSafe_MarketingView_819735987 - Worse: 8608ms | Best: 198ms | Avg: 4403 | Occurrences: 2
        LoadBlitzSafe_BillingView_-2041290683 - Worse: 655ms | Best: 107ms | Avg: 228 | Occurrences: 7
        CalculateAllDatesFromMarketing - Worse: 408ms | Best: 34ms | Avg: 201 | Occurrences: 3

Perfect for protecting:

  • 🗄️ SQL Server - Prevents slow query pile-ups that can crash databases
  • 🌐 External APIs - Avoids rate limiting and reduces costs
  • 📁 File System - Prevents I/O bottlenecks from concurrent reads
  • 🧮 Heavy Calculations - CPU-intensive operations run once, benefit everyone

🏆 Enterprise Features, Simple API

Zero duplicate execution - Guaranteed single execution per cache period
Ultra-fast performance - 0.0001ms per operation with intelligent memory management
Thread-safe by design - Handles any concurrency scenario automatically
Memory leak prevention - Advanced cleanup prevents memory bloat
Production tested - Comprehensive testing ensure reliability
Works with everything - Sync, async, any data type, any .NET app
Automatic logging - Built-in statistics monitoring with one line setup (v2.0.1+) ✅ Global statistics - As of v2.0.2, Statistics available and BlitzCacheLoggingService to log them automatically ✅ Top Slowest Queries - As of v2.0.2, BlitzCache tracks and exposes the top slowest queries, making it easy to identify performance bottlenecks in your application

📋 Table of Contents

📊 Real Impact

Scenario Without BlitzCache With BlitzCache Impact
1000 concurrent API calls 1000 executions 1 execution 99.9% faster
Database query bursts Multiple DB hits Single DB hit Massive savings
SQL server under load Server crashes 💥 Server protected 🛡️ System stability
Operation speed Varies 0.0001ms Lightning fast

Detailed benchmarks and analysis →

📦 Get Started in 30 Seconds

dotnet add package BlitzCache

📋 Requirements: Your project needs .NET Core 3.1+ or .NET 5-8+. No special SDK required for usage.

👥 For Contributors: Development requires .NET 8.0 SDK (see CONTRIBUTING.md)

Basic Usage

var cache = new BlitzCache();

// Any expensive operation becomes cached instantly
var data = await cache.BlitzGet("key", ExpensiveOperation, timeoutMs);

ASP.NET Core Integration

// Setup (one line in Program.cs)
services.AddBlitzCache();

// Optional: Add automatic logging of cache statistics (v2.0.2+)
services.AddBlitzCacheLogging(); // Logs cache performance hourly

// Usage anywhere
public WeatherService(IBlitzCache cache) => this.cache = cache;

public Task<Weather> GetWeather(string city) => cache.BlitzGet($"weather_{city}",  () => CallWeatherApi(city));

Compatibility: .NET Standard 2.1+ | .NET Core 3.1+ | .NET 5-8+

📚 Learning BlitzCache - Examples & Tutorials

Comprehensive Example Files

BlitzCache includes comprehensive example test files that serve as interactive tutorials and real-world usage guides:

🌱 BasicUsageExamples.cs

Perfect for getting started - covers essential patterns:

  • Basic synchronous caching - Simple function caching
  • Asynchronous operations - Async/await patterns
  • Cache key management - Working with different keys
  • Cache expiration - Understanding timeout behavior
  • Manual cache removal - Cache invalidation strategies
  • BlitzUpdate usage - Pre-populating cache
  • Different data types - Caching various objects
  • Cache statistics monitoring - Performance analytics and hit/miss tracking
  • Top slowest queries - Identify and monitor the slowest cache operations (v2.0.2+)
  • Dependency injection - ASP.NET Core integration
🚀 AdvancedUsageExamples.cs

For experienced users - sophisticated scenarios:

  • Dynamic cache timeout with Nuances - Result-based cache duration
  • Thread-safe concurrent access - Multi-threading patterns
  • Circuit breaker pattern - Resilient external service calls
  • Multi-level caching strategy - Complex caching hierarchies
  • Cache warming techniques - Pre-loading strategies
  • Conditional caching - Success/failure caching logic
  • Global vs Independent caches - Instance management
  • Performance monitoring - Metrics and diagnostics
  • Top slowest queries - Track and analyze slowest cache operations for optimization (v2.0.2+)

Running the Examples

# Run basic examples
dotnet test --filter "BasicUsageExamples"

# Run advanced examples  
dotnet test --filter "AdvancedUsageExamples"

# Run specific example
dotnet test --filter "Example1_BasicSyncCaching"

These example files are executable tests that demonstrate real-world usage patterns and serve as living documentation that stays up-to-date with the codebase.

🌟 Real-World Examples

Database Operations

public class UserRepository
{
    private readonly IBlitzCache _cache;
    
    public async Task<User> GetUserAsync(int userId)
    {
        return await _cache.BlitzGet($"user_{userId}", 
            async () => await database.Users.FindAsync(userId), 
            1200000); // Cache for 20 minutes
    }
    
    // Multiple concurrent calls to GetUserAsync(123) will result in only ONE database query
}

HTTP API Calls

public class ExchangeRateService
{
    public async Task<decimal> GetExchangeRateAsync(string fromCurrency, string toCurrency)
    {
        return await _cache.BlitzGet($"rate_{fromCurrency}_{toCurrency}",
            async () => {
                var response = await httpClient.GetAsync($"api/rates/{fromCurrency}/{toCurrency}");
                return await response.Content.ReadFromJsonAsync<decimal>();
            }, 
            600000); // Cache for 10 minutes
    }
}

File System Operations

public class ConfigurationService
{
    public async Task<AppConfig> LoadConfigAsync()
    {
        return await _cache.BlitzGet("app-config",
            async () => {
                var json = await File.ReadAllTextAsync("appsettings.json");
                return JsonSerializer.Deserialize<AppConfig>(json);
            },
            1800000); // Cache for 30 minutes
    }
}

Complex Calculations

public class ReportService
{
    public async Task<SalesReport> GenerateMonthlyReportAsync(int year, int month)
    {
        return await _cache.BlitzGet($"sales_report_{year}_{month}",
            async () => {
                // This expensive calculation will only run once
                var salesData = await CalculateComplexSalesMetricsAsync(year, month);
                var report = await GenerateChartsAndGraphsAsync(salesData);
                return report;
            },
            3600000); // Cache for 1 hour
    }
}

Class or Bounded Context Isolated

public class ReportService
{
    private static readonly BlitzCacheInstance  cache = new BlitzCacheInstance();

    public Task<SalesReport> GetProductsForCustomer(Guid customerId) => cache.BlitzGet($"products_{customerId}", () => LoadProducts(customerId)); // Cache for 1 hour
    }
}

🔧 Advanced Usage

Automatic Cache Key Generation

BlitzCache can automatically generate cache keys based on the calling method and file:

// Cache key will be: "GetUserData" + "UserService.cs"
public async Task<UserData> GetUserData()
{
    return await _cache.BlitzGet(async () => await FetchUserDataAsync());
}

Dynamic Cache Duration Based on Results

public async Task<ApiResponse> CallExternalApiAsync(string endpoint)
{
    return await _cache.BlitzGet($"api_{endpoint}", async (nuances) => {
        try 
        {
            var result = await httpClient.GetAsync(endpoint);
            if (result.IsSuccessStatusCode)
            {
                nuances.CacheRetention = 300000; // Success: cache for 5 minutes
                return await result.Content.ReadFromJsonAsync<ApiResponse>();
            }
            else
            {
                nuances.CacheRetention = 30000; // Error: cache for 30 seconds
                return new ApiResponse { Error = "API call failed" };
            }
        }
        catch (Exception)
        {
            nuances.CacheRetention = 5000; // Exception: cache for 5 seconds
            return new ApiResponse { Error = "Network error" };
        }
    });
}

Manual Cache Management

// Update cache manually
cache.BlitzUpdate("user_123", () => GetFreshUserData(), 120000);

// Remove from cache
cache.Remove("user_123");

// Async update
await cache.BlitzUpdate("weather_data", async () => await GetWeatherAsync(), 300000);

Cache Statistics and Monitoring

BlitzCache provides built-in performance statistics to help you monitor cache effectiveness and optimize your application.

As of v2.0.2, statistics are automatically enabled if you add your cache instance to BlitzCacheLoggingService.


// Access cache statistics
var stats = cache.Statistics;

Console.WriteLine($"Cache Hit Ratio: {stats.HitRatio:P1}"); // e.g., "75.5%"
Console.WriteLine($"Total Operations: {stats.TotalOperations}");
Console.WriteLine($"Cache Hits: {stats.HitCount}");
Console.WriteLine($"Cache Misses: {stats.MissCount}");
Console.WriteLine($"Current Entries: {stats.CurrentEntryCount}");
Console.WriteLine($"Evictions: {stats.EvictionCount}");
Console.WriteLine($"Active Semaphores: {stats.ActiveSemaphoreCount}");
// New in v2.0.2: Top slowest queries
if (stats.TopSlowestQueries != null && stats.TopSlowestQueries.Any())
{
    Console.WriteLine("Top Slowest Queries:");
    foreach (var q in stats.TopSlowestQueries)
        Console.WriteLine($"  {q}");
}
Real-World Monitoring Example
public class UserService
{
    private readonly IBlitzCache _cache;
    
    public UserService(IBlitzCache cache)
    {
        _cache = cache;
    }
    
    public async Task<UserProfile> GetUserProfileAsync(int userId)
    {
        // Cache the expensive database operation
        var profile = await _cache.BlitzGet($"user_profile_{userId}", 
            async () => await database.GetUserProfileAsync(userId), 
            300000); // 5 minutes
            
        // Log cache performance periodically
        var stats = _cache.Statistics;
        if (stats.TotalOperations % 100 == 0) // Every 100 operations
        {
            _logger.LogInformation("Cache performance: {HitRatio:P1} hit ratio, {CurrentEntries} entries", 
                stats.HitRatio, stats.CurrentEntryCount);
        }
        
        return profile;
    }
}
Statistics Reset for Time-Windowed Monitoring
// Reset statistics to monitor performance over specific periods
cache.Statistics.Reset();

// Perform operations...
DoSomeWork();

// Check performance for this period only
var periodStats = cache.Statistics;
Console.WriteLine($"Period hit ratio: {periodStats.HitRatio:P1}");

Available Statistics:

  • HitCount: Total cache hits since instance creation
  • MissCount: Total cache misses since instance creation
  • HitRatio: Hit percentage (0.0 to 1.0)
  • TotalOperations: Sum of hits and misses
  • CurrentEntryCount: Current number of cached entries
  • EvictionCount: Number of manual removals and expirations
  • ActiveSemaphoreCount: Current concurrency control structures
  • TopSlowestQueries: List of the slowest cache operations (v2.0.2+)
  • Reset(): Method to reset all counters to zero

📖 API Reference

Core Methods

BlitzGet<T>(string cacheKey, Func<T> function, long? milliseconds = null)

Executes function and caches result for synchronous operations.

BlitzGet<T>(string cacheKey, Func<Task<T>> function, long? milliseconds = null)

Executes async function and caches result for asynchronous operations.

BlitzGet<T>(Func<T> function, long? milliseconds = null)

Auto-generates cache key based on caller method and file path.

BlitzGet<T>(string cacheKey, Func<Nuances, T> function, long? milliseconds = null)

Allows dynamic cache duration configuration via the Nuances parameter.

Management Methods

BlitzUpdate<T>(string cacheKey, Func<T> function, long milliseconds)

Manually updates cache entry with new value.

Remove(string cacheKey)

Removes specific entry from cache.

Dispose()

Cleans up resources (implements IDisposable).

Parameters

  • cacheKey: Unique identifier for the cached value
  • function: The function to execute and cache
  • milliseconds: Cache duration in milliseconds (optional, uses default if not specified)
  • nuances: Object for dynamic cache configuration

🔄 Comparison with Alternatives

Feature BlitzCache MemoryCache Redis Custom Solutions
Zero Duplicate Execution ⚠️ Complex
Thread Safety ⚠️ Manual
Granular Locking ⚠️ Manual
Async Support ⚠️ Manual
Simple API ⚠️ Varies
No External Dependencies
Performance Overhead Very Low Low Medium Varies
Setup Complexity None Low High High

Why Choose BlitzCache?

  1. Prevents Thundering Herd: Unlike basic caches, BlitzCache prevents multiple concurrent executions
  2. Zero Configuration: Works out of the box with sensible defaults
  3. Performance Focused: Designed specifically for high-concurrency scenarios
  4. Developer Friendly: Simple, intuitive API that "just works"
  5. � Enterprise Grade: Advanced memory leak prevention with comprehensive testing
  6. ⚡ Ultra-Fast: 0.0001ms per operation with optimal memory management
  7. 🛡️ Robust Architecture: Advanced usage-based cleanup system
  8. 🔧 Production Ready: Intelligent smart lock management

🛠️ Troubleshooting

Common Issues

Q: Cache doesn't seem to work / function executes multiple times

  • Ensure you're using the same cache key for identical operations
  • Check that cache duration is appropriate for your use case
  • Verify you're not creating multiple BlitzCache instances unnecessarily

Q: Memory usage growing over time

  • BlitzCache automatically expires entries based on your specified durations
  • Consider shorter cache durations for frequently changing data
  • Use Remove() method for manual cleanup when needed

Q: Async methods hanging or deadlocking

  • Ensure you're using await properly with async BlitzGet methods
  • Avoid mixing sync and async patterns
  • Check for circular dependencies in your cached functions

Q: Performance not as expected

  • Verify your expensive operations are actually expensive enough to benefit from caching
  • Check cache hit ratios - very short cache durations may not provide benefits
  • Consider whether granular locking is needed for your use case

Getting Help

🎯 Production-Ready Caching Solution

BlitzCache delivers enterprise-grade performance and reliability:

  • Zero memory leaks - Advanced usage-based cleanup
  • 0.0001ms per operation - Ultra-high performance
  • Every feature is tested - Comprehensive reliability
  • Advanced architecture - Intelligent memory management
  • Thread-safe - Concurrent operation guarantees

Perfect for demanding production workloads! 🚀

🛠️ Migration Guide: 1.x → 2.x

If you are upgrading from BlitzCache 1.x to 2.x, please note the following breaking changes:

  • Async BlitzUpdate Signature: The BlitzUpdate<T> method for async operations now returns a Task instead of void. Update your code to await these calls:
    • Before (v1.x):
      void BlitzUpdate<T>(string cacheKey, Func<Task<T>> function, long milliseconds);
      
    • After (v2.x):
      Task BlitzUpdate<T>(string cacheKey, Func<Task<T>> function, long milliseconds);
      
  • API Cleanup: Obsolete and redundant APIs have been removed. Review the new interface for available methods.
  • Unified Concurrency Control: All concurrency is now managed with SemaphoreSlim. Remove any code referencing SmartLockDictionary or SmartLock classes.
  • Instance-Based Caching: BlitzCache is now instance-based instead of static. Update your code to create and manage BlitzCache instances as needed.

Migration Steps:

  1. Update your NuGet reference to BlitzCache 2.x.
  2. Refactor all async BlitzUpdate usages to return and await a Task.
  3. Update all projects using BlitzCache to be compatible with the new interface.
  4. Review and update any code referencing removed or changed APIs.
  5. Run your test suite to ensure all caching and concurrency scenarios work as expected.

For full details, see the Changelog.

🤝 Contributing

We welcome contributions! Here's how you can help:

Ways to Contribute

  • 🐛 Report bugs or issues
  • 💡 Suggest new features or improvements
  • 📖 Improve documentation
  • 🔧 Submit pull requests
  • ⭐ Star the repository
  • 📢 Share with other developers

Development Setup

git clone https://github.com/chanido/blitzcache.git
cd blitzcache
dotnet restore
dotnet build
dotnet test

Pull Request Guidelines

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Write tests for your changes
  4. Ensure all tests pass
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Code of Conduct

Please be respectful and constructive in all interactions. We're here to build something great together! 🚀

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Built with ❤️ by Chan
  • Thanks to all contributors
  • Inspired by the need for simple, high-performance caching solutions

⭐ If BlitzCache helped you, please consider giving it a star! ⭐

GitHub stars

Made with ⚡ by the BlitzCache team

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 21 8/11/2025
2.0.2 190 8/7/2025
2.0.1 356 8/4/2025
2.0.0 355 8/4/2025
1.0.2 11,631 11/28/2023
1.0.1 23,712 6/9/2020
1.0.0 562 6/6/2020

BlitzCache v2.0.2 - Automatic Statistics

NEW IN v2.0.2:
• Statistics enabled automatically or on demand if not using BlitzCacheLoggingService
• Predictable monitoring and logging for all usages of BlitzCache.Global
• Tracks and exposes the top slowest queries, making it easy to monitor and identify performance bottlenecks in your application.
• Fully backward compatible for all other APIs

THE SIMPLICITY ADVANTAGE:
• One line of code prevents duplicate execution of expensive operations
• Zero configuration required - works out of the box with sensible defaults
• Automatic Statistics for monitoring your application
• Ridiculously simple API that "just works" for any .NET application

THUNDERING HERD PROTECTION:
• Prevents SQL server crashes from concurrent query bursts
• Multiple concurrent calls = Single execution (others wait for result)
• Protects databases, APIs, and file systems from overload
• Perfect for high-traffic applications and microservices

ENTERPRISE PERFORMANCE:
• Ultra-fast 0.0001ms per operation with intelligent memory management
• Zero memory leaks with advanced usage-based cleanup system
• Thread-safe by design with granular concurrency control
• Comprehensive testing ensuring production reliability

🔧 ADVANCED FEATURES:
• Dynamic cache duration with result-based retention control
• Full async/await support with proper Task handling
• Automatic cache key generation or manual key management
• Built-in statistics, monitoring, and slow query tracking capabilities

Perfect for protecting your backend systems while keeping your code simple!