.NET Aspire Redis®* output caching integration

Includes: Hosting integration and Client integration

Learn how to use the .NET Aspire Redis output caching integration. The Aspire.StackExchange.Redis.OutputCaching client integration is used to register an ASP.NET Core Output Caching provider backed by a Redis server with the docker.io/library/redis container image.

Learn how to use the .NET Aspire Redis output caching integration. The Aspire.StackExchange.Redis.OutputCaching client integration is used to register an ASP.NET Core Output Caching provider backed by a Garnet server with the ghcr.io/microsoft/garnet container image.

Learn how to use the .NET Aspire Redis output caching integration. The Aspire.StackExchange.Redis.OutputCaching client integration is used to register an ASP.NET Core Output Caching provider backed by a Valkey server with the docker.io/valkey/valkey container image.

Hosting integration

The Redis hosting integration models a Redis resource as the RedisResource type. To access this type and APIs that allow you to add it to your app model, install the 📦 Aspire.Hosting.Redis NuGet package in the app host project.

dotnet add package Aspire.Hosting.Redis

For more information, see dotnet add package or Manage package dependencies in .NET applications.

Add Redis resource

In your app host project, call AddRedis on the builder instance to add a Redis resource:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

When .NET Aspire adds a container image to the app host, as shown in the preceding example with the docker.io/Redis/Redis image, it creates a new Redis instance on your local machine. A reference to your Redis resource (the cache variable) is added to the ExampleProject.

The WithReference method configures a connection in the ExampleProject named "cache". For more information, see Container resource lifecycle.

Tip

If you'd rather connect to an existing Redis instance, call AddConnectionString instead. For more information, see Reference existing resources.

Add Redis resource with Redis Insights

To add the Redis Insights to the Redis resource, call the WithRedisInsights method:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache")
                   .WithRedisInsights();

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

Redis Insights is a free graphical interface for analyzing Redis data across all operating systems and Redis deployments with the help of our AI assistant, Redis Copilot. .NET Aspire adds another container image docker.io/redis/redisinsight to the app host that runs the commander app.

Tip

To configure the host port for the RedisInsightResource call WithHostPort and provide the desired port number.

Add Redis resource with Redis Commander

To add the Redis Commander to the Redis resource, call the WithRedisCommander method:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache")
                   .WithRedisCommander();

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

Redis Commander is a Node.js web application used to view, edit, and manage a Redis Database. .NET Aspire adds another container image docker.io/rediscommander/redis-commander to the app host that runs the commander app.

Tip

To configure the host port for the RedisCommanderResource call WithHostPort and provide the desired port number.

Add Redis resource with data volume

To add a data volume to the Redis resource, call the WithDataVolume method on the Redis resource:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache")
                   .WithDataVolume(isReadOnly: false);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

The data volume is used to persist the Redis data outside the lifecycle of its container. The data volume is mounted at the /data path in the Redis container and when a name parameter isn't provided, the name is generated at random. For more information on data volumes and details on why they're preferred over bind mounts, see Docker docs: Volumes.

Add Redis resource with data bind mount

To add a data bind mount to the Redis resource, call the WithDataBindMount method:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache")
                   .WithDataBindMount(
                       source: @"C:\Redis\Data",
                       isReadOnly: false);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

Tip

Data bind mounts have limited functionality compared to volumes, which offer better performance, portability, and security, making them more suitable for production environments. However, bind mounts allow direct access and modification of files on the host system, ideal for development and testing where real-time changes are needed.

Data bind mounts rely on the host machine's filesystem to persist the Redis data across container restarts. The data bind mount is mounted at the C:\Redis\Data on Windows (or /Redis/Data on Unix) path on the host machine in the Redis container. For more information on data bind mounts, see Docker docs: Bind mounts.

Add Redis resource with persistence

To add persistence to the Redis resource, call the WithPersistence method with either the data volume or data bind mount:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache")
                   .WithDataVolume()
                   .WithPersistence(
                       interval: TimeSpan.FromMinutes(5),
                       keysChangedThreshold: 100);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

The preceding code adds persistence to the Redis resource by taking snapshots of the Redis data at a specified interval and threshold. The interval is time between snapshot exports and the keysChangedThreshold is the number of key change operations required to trigger a snapshot. For more information on persistence, see Redis docs: Persistence.

The Garnet hosting integration models a Garnet resource as the GarnetResource type. To access this type and APIs that allow you to add it to your app model, install the 📦 Aspire.Hosting.Garnet NuGet package in the app host project.

dotnet add package Aspire.Hosting.Garnet

For more information, see dotnet add package or Manage package dependencies in .NET applications.

Add Garnet resource

In your app host project, call AddGarnet on the builder instance to add a Garnet resource:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddGarnet("cache");

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

When .NET Aspire adds a container image to the app host, as shown in the preceding example with the ghcr.io/microsoft/garnet image, it creates a new Garnet instance on your local machine. A reference to your Garnet resource (the cache variable) is added to the ExampleProject.

The WithReference method configures a connection in the ExampleProject named "cache". For more information, see Container resource lifecycle.

Tip

If you'd rather connect to an existing Garnet instance, call AddConnectionString instead. For more information, see Reference existing resources.

Add Garnet resource with data volume

To add a data volume to the Garnet resource, call the AddGarnet method on the Garnet resource:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddGarnet("cache")
                   .WithDataVolume(isReadOnly: false);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

The data volume is used to persist the Garnet data outside the lifecycle of its container. The data volume is mounted at the /data path in the Garnet container and when a name parameter isn't provided, the name is generated at random. For more information on data volumes and details on why they're preferred over bind mounts, see Docker docs: Volumes.

Add Garnet resource with data bind mount

To add a data bind mount to the Garnet resource, call the WithDataBindMount method:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddGarnet("cache")
                   .WithDataBindMount(
                       source: @"C:\Garnet\Data",
                       isReadOnly: false);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

Tip

Data bind mounts have limited functionality compared to volumes, which offer better performance, portability, and security, making them more suitable for production environments. However, bind mounts allow direct access and modification of files on the host system, ideal for development and testing where real-time changes are needed.

Data bind mounts rely on the host machine's filesystem to persist the Garnet data across container restarts. The data bind mount is mounted at the C:\Garnet\Data on Windows (or /Garnet/Data on Unix) path on the host machine in the Garnet container. For more information on data bind mounts, see Docker docs: Bind mounts.

Add Garnet resource with persistence

To add persistence to the Garnet resource, call the WithPersistence method with either the data volume or data bind mount:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddGarnet("cache")
                   .WithDataVolume()
                   .WithPersistence(
                       interval: TimeSpan.FromMinutes(5),
                       keysChangedThreshold: 100);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

The preceding code adds persistence to the Redis resource by taking snapshots of the Garnet data at a specified interval and threshold. The interval is time between snapshot exports and the keysChangedThreshold is the number of key change operations required to trigger a snapshot. For more information on persistence, see Redis docs: Persistence.

The Valkey hosting integration models a Valkey resource as the ValkeyResource type. To access this type and APIs that allow you to add it to your app model, install the 📦 Aspire.Hosting.Valkey NuGet package in the app host project.

dotnet add package Aspire.Hosting.Valkey

For more information, see dotnet add package or Manage package dependencies in .NET applications.

Add Valkey resource

In your app host project, call AddValkey on the builder instance to add a Valkey resource:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddValkey("cache");

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

When .NET Aspire adds a container image to the app host, as shown in the preceding example with the docker.io/valkey/valkey image, it creates a new Valkey instance on your local machine. A reference to your Valkey resource (the cache variable) is added to the ExampleProject.

The WithReference method configures a connection in the ExampleProject named "cache". For more information, see Container resource lifecycle.

Tip

If you'd rather connect to an existing Valkey instance, call AddConnectionString instead. For more information, see Reference existing resources.

Add Valkey resource with data volume

To add a data volume to the Valkey resource, call the AddValkey method on the Valkey resource:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddValkey("cache")
                   .WithDataVolume(isReadOnly: false);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

The data volume is used to persist the Valkey data outside the lifecycle of its container. The data volume is mounted at the /data path in the Valkey container and when a name parameter isn't provided, the name is generated at random. For more information on data volumes and details on why they're preferred over bind mounts, see Docker docs: Volumes.

Add Valkey resource with data bind mount

To add a data bind mount to the Valkey resource, call the WithDataBindMount method:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddValkey("cache")
                   .WithDataBindMount(
                       source: @"C:\Valkey\Data",
                       isReadOnly: false);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

Tip

Data bind mounts have limited functionality compared to volumes, which offer better performance, portability, and security, making them more suitable for production environments. However, bind mounts allow direct access and modification of files on the host system, ideal for development and testing where real-time changes are needed.

Data bind mounts rely on the host machine's filesystem to persist the Valkey data across container restarts. The data bind mount is mounted at the C:\Valkey\Data on Windows (or /Valkey/Data on Unix) path on the host machine in the Valkey container. For more information on data bind mounts, see Docker docs: Bind mounts.

Add Valkey resource with persistence

To add persistence to the Valkey resource, call the WithPersistence method with either the data volume or data bind mount:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddValkey("cache")
                   .WithDataVolume()
                   .WithPersistence(
                       interval: TimeSpan.FromMinutes(5),
                       keysChangedThreshold: 100);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(cache);

// After adding all resources, run the app...

The preceding code adds persistence to the Redis resource by taking snapshots of the Valkey data at a specified interval and threshold. The interval is time between snapshot exports and the keysChangedThreshold is the number of key change operations required to trigger a snapshot. For more information on persistence, see Redis docs: Persistence.

Hosting integration health checks

The Redis hosting integration automatically adds a health check for the appropriate resource type. The health check verifies that the server is running and that a connection can be established to it.

The hosting integration relies on the 📦 AspNetCore.HealthChecks.Redis NuGet package.

Client integration

To get started with the .NET Aspire Stack Exchange Redis output caching client integration, install the 📦 Aspire.StackExchange.Redis.OutputCaching NuGet package in the client-consuming project, that is, the project for the application that uses the output caching client.

dotnet add package Aspire.StackExchange.Redis.OutputCaching

Add output caching

In the Program.cs file of your client-consuming project, call the AddRedisOutputCache extension method on any IHostApplicationBuilder to register the required services for output caching.

builder.AddRedisOutputCache(connectionName: "cache");

Tip

The connectionName parameter must match the name used when adding the Redis resource in the app host project. For more information, see Add Redis resource.

Tip

The connectionName parameter must match the name used when adding the Garnet resource in the app host project. For more information, see Add Garnet resource.

Tip

The connectionName parameter must match the name used when adding the Valkey resource in the app host project. For more information, see Add Valkey resource.

Add the middleware to the request processing pipeline by calling UseOutputCache(IApplicationBuilder):

var app = builder.Build();

app.UseOutputCache();

For minimal API apps, configure an endpoint to do caching by calling CacheOutput, or by applying the OutputCacheAttribute, as shown in the following examples:

app.MapGet("/cached", () => "Hello world!")
   .CacheOutput();

app.MapGet(
    "/attribute",
    [OutputCache] () => "Hello world!");

For apps with controllers, apply the [OutputCache] attribute to the action method. For Razor Pages apps, apply the attribute to the Razor page class.

Configuration

The .NET Aspire Stack Exchange Redis output caching integration provides multiple options to configure the Redis connection based on the requirements and conventions of your project.

Use a connection string

When using a connection string from the ConnectionStrings configuration section, you can provide the name of the connection string when calling AddRedisOutputCache:

builder.AddRedisOutputCache(connectionName: "cache");

Then the connection string will be retrieved from the ConnectionStrings configuration section:

{
  "ConnectionStrings": {
    "cache": "localhost:6379"
  }
}

For more information on how to format this connection string, see the Stack Exchange Redis configuration docs.

Use configuration providers

The .NET Aspire Stack Exchange Redis integration supports Microsoft.Extensions.Configuration. It loads the StackExchangeRedisSettings from configuration by using the Aspire:StackExchange:Redis key. Example appsettings.json that configures some of the options:

{
  "Aspire": {
    "StackExchange": {
      "Redis": {
        "ConnectionString": "localhost:6379",
        "DisableHealthChecks": true,
        "DisableTracing": false
      }
    }
  }
}

For the complete Redis client integration JSON schema, see Aspire.StackExchange.Redis/ConfigurationSchema.json.

Use inline delegates

You can also pass the Action<StackExchangeRedisSettings> configurationSettings delegate to set up some or all the options inline, for example to disable health checks from code:

builder.AddRedisOutputCache(
    "cache",
    static settings => settings.DisableHealthChecks  = true);

You can also set up the ConfigurationOptions using the Action<ConfigurationOptions> configureOptions delegate parameter of the AddRedisOutputCache method. For example to set the connection timeout:

builder.AddRedisOutputCache(
    "cache",
    static settings => settings.ConnectTimeout = 3_000);

Health checks

By default, .NET Aspire integrations enable health checks for all services. For more information, see .NET Aspire integrations overview.

The .NET Aspire Stack Exchange Redis output caching integration handles the following:

  • Adds the StackExchange.Redis health check, tries to open the connection and throws when it fails.
  • Integrates with the /health HTTP endpoint, which specifies all registered health checks must pass for app to be considered ready to accept traffic.

Observability and telemetry

.NET Aspire integrations automatically set up Logging, Tracing, and Metrics configurations, which are sometimes known as the pillars of observability. For more information about integration observability and telemetry, see .NET Aspire integrations overview. Depending on the backing service, some integrations may only support some of these features. For example, some integrations support logging and tracing, but not metrics. Telemetry features can also be disabled using the techniques presented in the Configuration section.

Logging

The .NET Aspire Stack Exchange Redis output caching integration uses the following Log categories:

  • Aspire.StackExchange.Redis
  • Microsoft.AspNetCore.OutputCaching.StackExchangeRedis

Tracing

The .NET Aspire Stack Exchange Redis output caching integration will emit the following Tracing activities using OpenTelemetry:

  • OpenTelemetry.Instrumentation.StackExchangeRedis

Metrics

The .NET Aspire Stack Exchange Redis output caching integration currently doesn't support metrics by default due to limitations with the StackExchange.Redis library.

See also

*: Redis is a registered trademark of Redis Ltd. Any rights therein are reserved to Redis Ltd. Any use by Microsoft is for referential purposes only and does not indicate any sponsorship, endorsement or affiliation between Redis and Microsoft. Return to top?