Ruvio.AspNetCore.OutputCaching 0.1.0

dotnet add package Ruvio.AspNetCore.OutputCaching --version 0.1.0
                    
NuGet\Install-Package Ruvio.AspNetCore.OutputCaching -Version 0.1.0
                    
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="Ruvio.AspNetCore.OutputCaching" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ruvio.AspNetCore.OutputCaching" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Ruvio.AspNetCore.OutputCaching" />
                    
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 Ruvio.AspNetCore.OutputCaching --version 0.1.0
                    
#r "nuget: Ruvio.AspNetCore.OutputCaching, 0.1.0"
                    
#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 Ruvio.AspNetCore.OutputCaching@0.1.0
                    
#: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=Ruvio.AspNetCore.OutputCaching&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Ruvio.AspNetCore.OutputCaching&version=0.1.0
                    
Install as a Cake Tool

Ruvio.AspNetCore.OutputCaching

ASP.NET Core 8 IOutputCacheStore backed by Ruvio. This is HTTP output caching, not IDistributedCache and not response replay for side-effecting requests. ASP.NET Core still owns the output-cache policies, serialization, HTTP variation and eligibility rules.

Setup

Reference this package and Ruvio.Client.AspNetCore, then:

using Microsoft.AspNetCore.OutputCaching;
using Ruvio.AspNetCore.OutputCaching;
using Ruvio.Client.AspNetCore;

builder.Services.AddRuvioClient("127.0.0.1", 6379);
builder.Services.AddRuvioOutputCache(o =>
{
    o.InstanceName = "catalog-production-v1";
    o.MaxValueBytes = 1024 * 1024;
});

var app = builder.Build();
app.UseRouting();
// If configured, authentication/authorization and CORS belong before output caching.
app.UseOutputCache();
app.MapGet("/catalog", () => new { version = 1 })
    .CacheOutput(policy => policy.Expire(TimeSpan.FromSeconds(30)).Tag("catalog"));

AddRuvioOutputCache calls AddOutputCache and replaces the registered IOutputCacheStore, including the framework's memory store. Call it after another provider registration when switching stores. Further AddOutputCache calls can configure normal framework policies. The borrowed IRuvioClient is resolved on the first storage operation, not when middleware is constructed. The provider does not own or dispose it.

To invalidate a tag, inject IOutputCacheStore:

await store.EvictByTagAsync("catalog", cancellationToken);

All application instances sharing output entries must use the same namespace, limits, HTTP host/scheme/path-base handling and cache policies. Configure trusted forwarded headers correctly behind a reverse proxy; do not remove host variation to conceal a proxy configuration problem.

Tag semantics and costs

  • Untagged publication: one binary SET PX. Untagged hit or any missing entry: one GET.
  • Tagged publication: one GET/PTTL pipeline, then native SET or PEXPIRE for tags whose lifetime is shorter than the entry, then one SET PX of the entry. A tag TTL is extended, never shortened. The steps are separate commands.
  • Tagged hit: one GET of the entry, then one MGET of its tag generations. A missing or changed generation means a cache miss.
  • Eviction: one DEL of the tag generation, independent of the number of entries. No key scan, reverse membership set, timer, local dictionary or background task. Old entry bytes remain until their original TTL; they are no longer served.
  • Recreating a tag generates a new random token. Expiry, eviction and re-creation cannot make entries from an older generation valid again.

The GET and tag validation are separate operations. A concurrent invalidation after validation can race with an already in-flight response, as with ordinary cache reads. Publishing stale application data after invalidation can also cache it again; this provider does not serialize database reads with cache writes. Framework request coalescing remains process-local, not a distributed lock.

Cluster tradeoff: one InstanceName occupies one hash slot so tagged publication and generation lifetime updates remain atomic. It does not spread one application's output cache across all shards. Different namespaces can land on different shards, but cannot share tag invalidation. Do not use this package as a claim of full-cluster throughput for one namespace.

Keys and tags are SHA-256 hashed; raw HTTP cache keys are not sent as server key names. Payloads remain binary, without Base64. Record overhead is 6 bytes plus 96 bytes per tag; tagged reads copy 32 bytes per tag into a bounded validation argument. Returning byte[] requires extracting the payload from its envelope. The framework also incurs its normal buffering and serialization costs.

Defaults: 1 MiB serialized value, 4096 UTF-8 bytes per input key/tag, at most 32 tags. Supported configured value range: 1 byte through 8 MiB, subject also to server protocol/script limits. Entry lifetimes are 1 ms through 365 days, rounded down to milliseconds. Empty values and null/empty tag arrays are supported. Coordinate OutputCacheOptions.MaximumBodySize with MaxValueBytes; the latter includes framework serialization overhead, not just HTTP body bytes.

No activity occurs unless the feature is registered and a caching policy invokes storage. Unselected endpoints do not resolve the Ruvio client or create records. The provider throws on transport errors, wrong types, malformed records and size violations; it does not silently reinterpret errors as misses or retry writes. ASP.NET Core controls how its middleware logs/handles store exceptions.

Use a dedicated namespace, not existing Redis output-cache entries. Tag scripts require this repository's deadline-preserving Lua rollback fix. Eviction or replica state loss can reduce cache hit rates. Replica rollback can also lose tag invalidations and bring back stale responses; this is not durable application state or an authorization boundary. Never enable caching of user-specific content without an appropriate trusted variation policy.

Development

RUVIO_TEST_ADDR=127.0.0.1:16382 dotnet test integrations/dotnet/Ruvio.AspNetCore.OutputCaching.Tests -c Release
dotnet pack integrations/dotnet/Ruvio.AspNetCore.OutputCaching -c Release -o dist

Live tests include two clients/shards, tag re-creation, concurrent eviction, the 32-tag/1-MiB boundary, and real ASP.NET Core output caching across two HTTP hosts. Without RUVIO_TEST_ADDR, live cases are explicitly skipped.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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. 
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
0.1.0 88 10/2/2026