A .NET 10 educational demo project showcasing Hybrid Cache with Redis, demonstrating how to leverage both local in-memory cache and distributed cache (Redis) for optimal performance.
This project demonstrates a practical implementation of Microsoft.Extensions.Caching.Hybrid, which combines:
- Local Cache: Fast in-memory cache for frequently accessed data
- Distributed Cache (Redis): Shared cache across multiple instances
The demo uses PostgreSQL as the database and showcases different cache expiration strategies for various scenarios.
βββββββββββββββββββ
β API Layer β
β (Minimal APIs) β
ββββββββββ¬βββββββββ
β
ββββββββββΌββββββββββββββββββ
β CachedProductService β
β (Hybrid Cache Layer) β
ββββββββββ¬ββββββββββββββββββ
β
ββββββ΄βββββ
β β
βββββΌββββ ββββΌβββββββββββ
β Local β β Redis β
β Cache β β (Distributed)β
βββββββββ βββββββββββββββ
β
ββββββββββΌββββββββββ
β ProductService β
β (Database Layer)β
ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββ
β PostgreSQL β
βββββββββββββββββββ
- Hybrid Cache Implementation: Demonstrates local + distributed caching
- Different Expiration Times:
- Short-lived cache (10s local, 1min distributed) for both product list and individual product queries
- Demonstrates cache invalidation strategies for maintaining data consistency
- Cache Invalidation: Automatic cache invalidation on create/update/delete operations
- Aspire Integration: Uses .NET Aspire for orchestration and observability
- PostgreSQL Database: Real database with EF Core
- RESTful API: Clean minimal API endpoints
- .NET 10 SDK
- Docker Desktop (for PostgreSQL and Redis via Aspire)
-
Clone the repository
git clone <repository-url> cd HybridCachePlayground
-
Run the Aspire AppHost
dotnet run --project HybridCachePlayground.AppHost
This will:
- Start PostgreSQL database
- Start Redis cache
- Start the API application (3 replicas)
- Open Aspire Dashboard in your browser
-
Access the API
- API:
https://localhost:3000 - Aspire Dashboard: Automatically opens in browser
- OpenAPI/Swagger: Available in development mode
- API:
GET /api/productsReturns all products. Uses hybrid cache with:
- Local cache: 10 seconds
- Distributed cache: 1 minute
GET /api/products/{id}Returns a specific product. Uses hybrid cache with:
- Local cache: 10 seconds
- Distributed cache: 1 minute
POST /api/products
Content-Type: application/json
{
"name": "New Product",
"description": "Product description",
"price": 99.99,
"stock": 50
}Creates a new product and invalidates the products list cache.
PUT /api/products/{id}
Content-Type: application/json
{
"name": "Updated Product",
"description": "Updated description",
"price": 109.99,
"stock": 45
}Updates a product and invalidates related caches.
DELETE /api/products/{id}Deletes a product and invalidates related caches.
Both endpoints use the same cache expiration strategy:
- Local Cache: 10 seconds
- Distributed Cache: 1 minute
This configuration provides:
- Fast local access: Frequently requested data is served from in-memory cache for ultra-fast response times
- Shared cache across instances: Distributed cache (Redis) ensures cache hits even when requests hit different API instances
- Automatic cache invalidation: When products are created, updated, or deleted, related caches are automatically invalidated to maintain data consistency
When products are created, updated, or deleted:
- The specific product cache is invalidated
- The products list cache is invalidated
- This ensures data consistency across all instances
-
First Request (Cache Miss):
curl https://localhost:3000/api/products/1
- Check logs: You'll see "Fetching product 1 from database"
- Response time: ~100ms (simulated DB latency)
-
Second Request (Cache Hit):
curl https://localhost:3000/api/products/1
- Check logs: No database query
- Response time: <1ms (from local cache)
-
Request from Different Instance:
- Since we run 3 replicas, hit the same endpoint from a different instance
- First request from new instance: Cache miss (local), but may hit Redis
- Subsequent requests: Cache hit from local cache
Use the Aspire Dashboard to:
- Monitor cache hit/miss rates
- View distributed tracing
- Check Redis connection status
- Monitor database queries
- .NET 10 with C# 14
- Microsoft.Extensions.Caching.Hybrid - Hybrid caching
- StackExchange.Redis - Redis client
- Entity Framework Core 10 - ORM
- Npgsql.EntityFrameworkCore.PostgreSQL - PostgreSQL provider
- .NET Aspire - Cloud-native orchestration
- Minimal APIs - Lightweight API endpoints
- Hybrid Cache: Combining local and distributed cache for optimal performance
- Cache Expiration Strategies: Different TTLs based on data characteristics
- Cache Invalidation: Ensuring data consistency
- Multi-Instance Support: Distributed cache enables cache sharing across instances
- Performance Optimization: Reducing database load through intelligent caching
- When to use Hybrid Cache: Best for scenarios where you need both fast local access and shared cache across instances
- Expiration Strategy: Balance between freshness and performance - shorter local cache ensures quick updates while distributed cache reduces database load
- Cache Invalidation: Critical for maintaining data consistency - the demo shows how to invalidate both specific item caches and list caches
- Cache Tags: Using tags (e.g.,
["products"]) enables bulk invalidation if needed in the future - Monitoring: Use Aspire Dashboard to observe cache behavior, hit/miss rates, and distributed tracing
HybridCachePlayground/
βββ HybridCachePlayground/
β βββ Data/
β β βββ AppDbContext.cs # EF Core DbContext
β βββ DTOs/
β β βββ CreateProductRequest.cs
β β βββ UpdateProductRequest.cs
β βββ Models/
β β βββ Product.cs # Product entity
β βββ Services/
β β βββ ProductService.cs # Database service
β β βββ CachedProductService.cs # Hybrid cache wrapper
β βββ Program.cs # Application entry point
βββ HybridCachePlayground.AppHost/
β βββ AppHost.cs # Aspire orchestration
βββ README.md
This is an educational demo project. Feel free to fork and experiment with different cache strategies and scenarios!
This project is provided as-is for educational purposes.
Built with β€οΈ using .NET 10 and Aspire