Skip to main content

Overview

Caching in the Ramsha Framework provides a unified, modular, and provider-agnostic way to store and retrieve cached data across your application.

Ramsha caching is built on top of Microsoft.Extensions.Caching.Hybrid and exposes a simple abstraction that works consistently across all Ramsha engine modes.

Ramsha caching is designed to:

  • Be modular and optional
  • Decouple application logic from caching infrastructure
  • Support both in-memory and distributed caching transparently

At the center of the caching system is the IRamshaCache abstraction.


Default Caching Behavior​

When you install and enable only the Ramsha.Caching package:

  • Cache entries are stored in memory only
  • No external infrastructure is required
  • Ideal for:
    • Development environments
    • Single-instance applications
    • Lightweight services

This default behavior works out of the box with zero additional configuration.


Hybrid Cache Concept​

Ramsha uses Hybrid Cache, a modern caching abstraction that combines multiple cache layers into a single API.

Hybrid Cache supports:

  • Local in-memory cache (L1) for fast access
  • Optional distributed cache (L2) for shared storage

The cache resolution flow is:

  1. Check in-memory cache
  2. If not found, check distributed cache (if configured)
  3. If still not found, execute a factory to generate the value
  4. Store the result back into the cache layers

Ramsha configures Hybrid Cache internally while keeping application code independent of where cached data is stored.


Cache Stampede Protection​

Hybrid Cache automatically prevents cache stampedes.

When multiple requests attempt to access the same cache key at the same time:

  • Only one factory execution is allowed
  • Other callers wait for the result
  • Once completed, all callers receive the cached value

This behavior is available even when using in-memory caching only.


Cache Keys and Tags​

Cache Keys​

Cache keys must uniquely identify cached data.

Best practices:

  • Use stable and predictable key formats
  • Include identifiers (e.g. product:42)
  • Avoid very large keys

Key length limits are configurable through RamshaCachingOptions.


Cache Tags​

Ramsha caching supports tag-based invalidation.

Tags allow you to:

  • Group related cache entries
  • Invalidate multiple entries at once
  • Simplify cache cleanup logic

This is especially useful for domain-based cache invalidation.


Enabling Caching​

Enable caching by depending on the CachingModule:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRamsha(ramsha =>
{
ramsha.AddCaching(); // or ramsha.AddModule<CachingModule>
});

var app = builder.Build();
app.UseRamsha();
app.Run();

IRamshaCache Interface​

Applications and modules interact with caching through IRamshaCache.

This ensures:

  • No dependency on specific caching providers
  • Easy testing and replacement
  • Clean separation between logic and infrastructure

Common Cache Operations​

Get or Create​

app.MapGet("products", async (IRamshaCache cache) =>
{
return await cache.GetOrCreateAsync(
"products:all",
async ct => await LoadProductsAsync(),
new RamshaCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(10),
LocalCacheExpiration = TimeSpan.FromMinutes(2)
});
});

This method:

  • Reads from cache if available
  • Executes the factory only if needed
  • Writes results back to cache layers

Set Cache Entry​

Sometime you want only to set data to the cache:

await _cache.SetAsync(
"products:all",
products,
new RamshaCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(10)
});

Remove Cache Entry​

await _cache.RemoveAsync("products:all");

Remove by Tag​

await _cache.RemoveByTagAsync("products");

Configuration​

Caching behavior is configured using RamshaCachingOptions, typically during the Prepare phase of a module.

These options control:

  • Cache key limits
  • Payload size limits
  • Default expiration values
  • Local vs distributed cache expiration

Continue with:​