This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can trysigning in orchanging directories.
Access to this page requires authorization. You can trychanging directories.
ByMohsin Nasir andsmandia
Note
This isn't the latest version of this article. For the current release, see the.NET 10 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see the.NET and .NET Core Support Policy. For the current release, see the.NET 9 version of this article.
A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.
A distributed cache has several advantages over other caching scenarios where cached data is stored on individual app servers.
When cached data is distributed, the data:
Distributed cache configuration is implementation specific. This article describes how to configure SQL Server, Redis, or Postgres distributed caches. Third party implementations are also available, such asNCache (NCache on GitHub), Cosmos DB, and Postgres. Regardless of which implementation is selected, the app interacts with the cache using theIDistributedCache interface.
View or download sample code (how to download)
Warning
This article uses a local database that doesn't require the user to be authenticated. Production apps should use the most secure authentication flow available. For more information on authentication for deployed test and production apps, seeSecure authentication flows.
Add a package reference for the distributed cache provider used:
TheIDistributedCache interface provides the following methods to manipulate items in the distributed cache implementation:
byte[] array if found in the cache.byte[] array) to the cache using a string key.Register an implementation ofIDistributedCache inProgram.cs. Framework-provided implementations described in this topic include:
We recommend production apps use the Distributed Redis Cache because it's the most performant. For more information seeRecommendations.
Redis is an open source in-memory data store, which is often used as a distributed cache. You can configure anAzure Cache for Redis for an Azure-hosted ASP.NET Core app, and use an Azure Cache for Redis for local development.
An app configures the cache implementation using aRedisCache instance, by callingAddStackExchangeRedisCache. Foroutput caching, useAddStackExchangeRedisOutputCache.
The following code enables the Azure Cache for Redis:
builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr"); options.InstanceName = "SampleInstance"; });The preceding code assumes the Primary connection string (StackExchange.Redis) was saved in configuration with the key nameMyRedisConStr.
For more information, seeAzure Cache for Redis.
Seethis GitHub issue for a discussion on alternative approaches to a local Redis cache.
The Distributed Memory Cache (AddDistributedMemoryCache) is a framework-provided implementation ofIDistributedCache that stores items in memory. The Distributed Memory Cache isn't an actual distributed cache. Cached items are stored by the app instance on the server where the app is running.
The Distributed Memory Cache is a useful implementation:
The sample app makes use of the Distributed Memory Cache when the app is run in the Development environment inProgram.cs:
builder.Services.AddDistributedMemoryCache();The Distributed SQL Server Cache implementation (AddDistributedSqlServerCache) allows the distributed cache to use a SQL Server database as its backing store. To create a SQL Server cached item table in a SQL Server instance, you can use thesql-cache tool. The tool creates a table with the name and schema that you specify.
Create a table in SQL Server by running thesql-cache create command. Provide the SQL Server instance (Data Source), database (Initial Catalog), schema (for example,dbo), and table name (for example,TestCache):
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCacheA message is logged to indicate that the tool was successful:
Table and index were created successfully.The table created by thesql-cache tool has the following schema:

Note
An app should manipulate cache values using an instance ofIDistributedCache, not aSqlServerCache.
The sample app implementsSqlServerCache in a non-Development environment inProgram.cs:
builder.Services.AddDistributedSqlServerCache(options =>{ options.ConnectionString = builder.Configuration.GetConnectionString( "DistCache_ConnectionString"); options.SchemaName = "dbo"; options.TableName = "TestCache";});Note
AConnectionString (and optionally,SchemaName andTableName) are typically stored outside of source control (for example, stored by theSecret Manager or inappsettings.json/appsettings.{Environment}.json files). The connection string may contain credentials that should be kept out of source control systems.
Azure Database for PostgreSQL can be used as a distributed cache backing store via theIDistributedCache interface. Azure Database for PostgreSQL is a fully managed, AI-ready Database-as-a-Service (DBaaS) offering built on the open-source PostgreSQL engine, designed to support mission-critical workloads with predictable performance, robust security, high availability, and seamless scalability.
After installing theMicrosoft.Extensions.Caching.Postgres NuGet package, configure your distributed cache as follows:
using Microsoft.Extensions.DependencyInjection;var builder = WebApplication.CreateBuilder(args);// Register Postgres distributed cachebuilder.Services.AddDistributedPostgresCache(options => { options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache"); options.SchemaName = builder.Configuration.GetValue<string>("PostgresCache:SchemaName", "public"); options.TableName = builder.Configuration.GetValue<string>("PostgresCache:TableName", "cache"); options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists", true); options.UseWAL = builder.Configuration.GetValue<bool>("PostgresCache:UseWAL", false); // Optional: Configure expiration settings var expirationInterval = builder.Configuration.GetValue<string>("PostgresCache:ExpiredItemsDeletionInterval"); if (!string.IsNullOrEmpty(expirationInterval) && TimeSpan.TryParse(expirationInterval, out var interval)) { options.ExpiredItemsDeletionInterval = interval; } var slidingExpiration = builder.Configuration.GetValue<string>("PostgresCache:DefaultSlidingExpiration"); if (!string.IsNullOrEmpty(slidingExpiration) && TimeSpan.TryParse(slidingExpiration, out var sliding)) { options.DefaultSlidingExpiration = sliding; }});var app = builder.Build();public class MyService { private readonly IDistributedCache _cache; public MyService(IDistributedCache cache) { _cache = cache; } public async Task<string> GetDataAsync(string key) { var cachedData = await _cache.GetStringAsync(key); if (cachedData == null) { // Fetch data from source var data = await FetchDataFromSource(); // Cache the data with options var options = new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(5) }; await _cache.SetStringAsync(key, data, options); return data; } return cachedData; }}NCache is an open source in-memory distributed cache developed natively in .NET. NCache works both locally and configured as a distributed cache cluster for an ASP.NET Core app running in Azure or on other hosting platforms.
To install and configure NCache on your local machine, seeGetting Started Guide for Windows & Linux.
To configure NCache:
Program.cs:builder.Services.AddNCacheDistributedCache(configuration =>{ configuration.CacheName = "democache"; configuration.EnableLogs = true; configuration.ExceptionsEnabled = true;});Azure Cosmos DB can be used in ASP.NET Core as a session state provider by using theIDistributedCache interface. Azure Cosmos DB is a fully managed NoSQL and relational database for modern app development that offers high availability, scalability, and low-latency access to data for mission-critical applications.
After installing theMicrosoft.Extensions.Caching.Cosmos NuGet package, configure an Azure Cosmos DB distributed cache as follows:
The easiest way to configure distributed cache is by reusing an existing Azure Cosmos DB client. In this case, theCosmosClient instance won't be disposed when the provider is disposed.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>{ cacheOptions.ContainerName = Configuration["CosmosCacheContainer"]; cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"]; cacheOptions.CosmosClient = existingCosmosClient; cacheOptions.CreateIfNotExists = true;});Alternatively, instantiate a new client. In this case, theCosmosClient instance will get disposed when the provider is disposed.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>{ cacheOptions.ContainerName = Configuration["CosmosCacheContainer"]; cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"]; cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]); cacheOptions.CreateIfNotExists = true;});To use theIDistributedCache interface, request an instance ofIDistributedCache in the app. The instance is provided bydependency injection (DI).
When the sample app starts,IDistributedCache is injected intoProgram.cs. The current time is cached usingIHostApplicationLifetime (for more information, seeGeneric Host: IHostApplicationLifetime):
app.Lifetime.ApplicationStarted.Register(() =>{ var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = System.Text.Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); app.Services.GetService<IDistributedCache>() .Set("cachedTimeUTC", encodedCurrentTimeUTC, options);});The sample app injectsIDistributedCache into theIndexModel for use by the Index page.
Each time the Index page is loaded, the cache is checked for the cached time inOnGetAsync. If the cached time hasn't expired, the time is displayed. If 20 seconds have elapsed since the last time the cached time was accessed (the last time this page was loaded), the page displaysCached Time Expired.
Immediately update the cached time to the current time by selecting theReset Cached Time button. The button triggers theOnPostResetCachedTime handler method.
public class IndexModel : PageModel{ private readonly IDistributedCache _cache; public IndexModel(IDistributedCache cache) { _cache = cache; } public string? CachedTimeUTC { get; set; } public string? ASP_Environment { get; set; } public async Task OnGetAsync() { CachedTimeUTC = "Cached Time Expired"; var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC"); if (encodedCachedTimeUTC != null) { CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC); } ASP_Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); if (String.IsNullOrEmpty(ASP_Environment)) { ASP_Environment = "Null, so Production"; } } public async Task<IActionResult> OnPostResetCachedTime() { var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options); return RedirectToPage(); }}There'sno need to use a Singleton or Scoped lifetime forIDistributedCache instances with the built-in implementations.
You can also create anIDistributedCache instance wherever you might need one instead of using DI, but creating an instance in code can make your code harder to test and violates theExplicit Dependencies Principle.
When deciding which implementation ofIDistributedCache is best for your app, consider the following:
Caching solutions usually rely on in-memory storage to provide fast retrieval of cached data, but memory is a limited resource and costly to expand. Only store commonly used data in a cache.
For most apps, a Redis cache provides higher throughput and lower latency than a SQL Server cache. However, benchmarking is recommended to determine the performance characteristics of caching strategies.
When SQL Server is used as a distributed cache backing store, use of the same database for the cache and the app's ordinary data storage and retrieval can negatively impact the performance of both. We recommend using a dedicated SQL Server instance for the distributed cache backing store.
A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.
A distributed cache has several advantages over other caching scenarios where cached data is stored on individual app servers.
When cached data is distributed, the data:
Distributed cache configuration is implementation specific. This article describes how to configure SQL Server, Redis, and Postgres distributed caches. Third party implementations are also available, such asNCache (NCache on GitHub). Regardless of which implementation is selected, the app interacts with the cache using theIDistributedCache interface.
View or download sample code (how to download)
Add a package reference for the distributed cache provider used:
For a Redis distributed cache,Microsoft.Extensions.Caching.StackExchangeRedis.
For SQL Server,Microsoft.Extensions.Caching.SqlServer.
For Postgres,Microsoft.Extensions.Caching.Postgres.
For the NCache distributed cache,NCache.Microsoft.Extensions.Caching.OpenSource.
Warning
This article uses a local database that doesn't require the user to be authenticated. Production apps should use the most secure authentication flow available. For more information on authentication for deployed test and production apps, seeSecure authentication flows.
TheIDistributedCache interface provides the following methods to manipulate items in the distributed cache implementation:
byte[] array if found in the cache.byte[] array) to the cache using a string key.Register an implementation ofIDistributedCache inProgram.cs. Framework-provided implementations described in this topic include:
We recommend production apps use the Distributed Redis Cache because it's the most performant. For more information seeRecommendations.
Redis is an open source in-memory data store, which is often used as a distributed cache. You can configure anAzure Redis Cache for an Azure-hosted ASP.NET Core app, and use an Azure Redis Cache for local development.
An app configures the cache implementation using aRedisCache instance (AddStackExchangeRedisCache).
The following code enables the Azure Cache for Redis:
builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr"); options.InstanceName = "SampleInstance"; });The preceding code assumes the Primary connection string (StackExchange.Redis) was saved in configuration with the key nameMyRedisConStr.
For more information, seeAzure Cache for Redis.
Seethis GitHub issue for a discussion on alternative approaches to a local Redis cache.
The Distributed Memory Cache (AddDistributedMemoryCache) is a framework-provided implementation ofIDistributedCache that stores items in memory. The Distributed Memory Cache isn't an actual distributed cache. Cached items are stored by the app instance on the server where the app is running.
The Distributed Memory Cache is a useful implementation:
The sample app makes use of the Distributed Memory Cache when the app is run in the Development environment inProgram.cs:
builder.Services.AddDistributedMemoryCache();The Distributed SQL Server Cache implementation (AddDistributedSqlServerCache) allows the distributed cache to use a SQL Server database as its backing store. To create a SQL Server cached item table in a SQL Server instance, you can use thesql-cache tool. The tool creates a table with the name and schema that you specify.
Create a table in SQL Server by running thesql-cache create command. Provide the SQL Server instance (Data Source), database (Initial Catalog), schema (for example,dbo), and table name (for example,TestCache):
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCacheA message is logged to indicate that the tool was successful:
Table and index were created successfully.The table created by thesql-cache tool has the following schema:

Note
An app should manipulate cache values using an instance ofIDistributedCache, not aSqlServerCache.
The sample app implementsSqlServerCache in a non-Development environment inProgram.cs:
builder.Services.AddDistributedSqlServerCache(options =>{ options.ConnectionString = builder.Configuration.GetConnectionString( "DistCache_ConnectionString"); options.SchemaName = "dbo"; options.TableName = "TestCache";});Note
AConnectionString (and optionally,SchemaName andTableName) are typically stored outside of source control (for example, stored by theSecret Manager or inappsettings.json/appsettings.{Environment}.json files). The connection string may contain credentials that should be kept out of source control systems.
Azure Database for PostgreSQL can be used as a distributed cache backing store via theIDistributedCache interface. Azure Database for PostgreSQL is a fully managed, AI-ready Database-as-a-Service (DBaaS) offering built on the open-source PostgreSQL engine, designed to support mission-critical workloads with predictable performance, robust security, high availability, and seamless scalability.
After installing theMicrosoft.Extensions.Caching.Postgres NuGet package, configure your distributed cache as follows:
using Microsoft.Extensions.DependencyInjection;var builder = WebApplication.CreateBuilder(args);// Register Postgres distributed cachebuilder.Services.AddDistributedPostgresCache(options => { options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache"); options.SchemaName = builder.Configuration.GetValue<string>("PostgresCache:SchemaName", "public"); options.TableName = builder.Configuration.GetValue<string>("PostgresCache:TableName", "cache"); options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists", true); options.UseWAL = builder.Configuration.GetValue<bool>("PostgresCache:UseWAL", false); // Optional: Configure expiration settings var expirationInterval = builder.Configuration.GetValue<string>("PostgresCache:ExpiredItemsDeletionInterval"); if (!string.IsNullOrEmpty(expirationInterval) && TimeSpan.TryParse(expirationInterval, out var interval)) { options.ExpiredItemsDeletionInterval = interval; } var slidingExpiration = builder.Configuration.GetValue<string>("PostgresCache:DefaultSlidingExpiration"); if (!string.IsNullOrEmpty(slidingExpiration) && TimeSpan.TryParse(slidingExpiration, out var sliding)) { options.DefaultSlidingExpiration = sliding; }});var app = builder.Build();public class MyService { private readonly IDistributedCache _cache; public MyService(IDistributedCache cache) { _cache = cache; } public async Task<string> GetDataAsync(string key) { var cachedData = await _cache.GetStringAsync(key); if (cachedData == null) { // Fetch data from source var data = await FetchDataFromSource(); // Cache the data with options var options = new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(5) }; await _cache.SetStringAsync(key, data, options); return data; } return cachedData; }}NCache is an open source in-memory distributed cache developed natively in .NET and .NET Core. NCache works both locally and configured as a distributed cache cluster for an ASP.NET Core app running in Azure or on other hosting platforms.
To install and configure NCache on your local machine, seeGetting Started Guide for Windows (.NET and .NET Core).
To configure NCache:
Program.cs:builder.Services.AddNCacheDistributedCache(configuration =>{ configuration.CacheName = "democache"; configuration.EnableLogs = true; configuration.ExceptionsEnabled = true;});To use theIDistributedCache interface, request an instance ofIDistributedCache in the app. The instance is provided bydependency injection (DI).
When the sample app starts,IDistributedCache is injected intoProgram.cs. The current time is cached usingIHostApplicationLifetime (for more information, seeGeneric Host: IHostApplicationLifetime):
app.Lifetime.ApplicationStarted.Register(() =>{ var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = System.Text.Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); app.Services.GetService<IDistributedCache>() .Set("cachedTimeUTC", encodedCurrentTimeUTC, options);});The sample app injectsIDistributedCache into theIndexModel for use by the Index page.
Each time the Index page is loaded, the cache is checked for the cached time inOnGetAsync. If the cached time hasn't expired, the time is displayed. If 20 seconds have elapsed since the last time the cached time was accessed (the last time this page was loaded), the page displaysCached Time Expired.
Immediately update the cached time to the current time by selecting theReset Cached Time button. The button triggers theOnPostResetCachedTime handler method.
public class IndexModel : PageModel{ private readonly IDistributedCache _cache; public IndexModel(IDistributedCache cache) { _cache = cache; } public string? CachedTimeUTC { get; set; } public string? ASP_Environment { get; set; } public async Task OnGetAsync() { CachedTimeUTC = "Cached Time Expired"; var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC"); if (encodedCachedTimeUTC != null) { CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC); } ASP_Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); if (String.IsNullOrEmpty(ASP_Environment)) { ASP_Environment = "Null, so Production"; } } public async Task<IActionResult> OnPostResetCachedTime() { var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options); return RedirectToPage(); }}There'sno need to use a Singleton or Scoped lifetime forIDistributedCache instances with the built-in implementations.
You can also create anIDistributedCache instance wherever you might need one instead of using DI, but creating an instance in code can make your code harder to test and violates theExplicit Dependencies Principle.
When deciding which implementation ofIDistributedCache is best for your app, consider the following:
Caching solutions usually rely on in-memory storage to provide fast retrieval of cached data, but memory is a limited resource and costly to expand. Only store commonly used data in a cache.
For most apps, a Redis cache provides higher throughput and lower latency than a SQL Server cache. However, benchmarking is recommended to determine the performance characteristics of caching strategies.
When SQL Server is used as a distributed cache backing store, use of the same database for the cache and the app's ordinary data storage and retrieval can negatively impact the performance of both. We recommend using a dedicated SQL Server instance for the distributed cache backing store.
A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.
A distributed cache has several advantages over other caching scenarios where cached data is stored on individual app servers.
When cached data is distributed, the data:
Distributed cache configuration is implementation specific. This article describes how to configure SQL Server, Redis, and Postgres distributed caches. Third party implementations are also available, such asNCache (NCache on GitHub). Regardless of which implementation is selected, the app interacts with the cache using theIDistributedCache interface.
View or download sample code (how to download)
To use a SQL Server distributed cache, add a package reference to theMicrosoft.Extensions.Caching.SqlServer package.
To use a Redis distributed cache, add a package reference to theMicrosoft.Extensions.Caching.StackExchangeRedis package.
To use a Postgres distributed cache, add a package reference to theMicrosoft.Extensions.Caching.Postgres package.
To use NCache distributed cache, add a package reference to theNCache.Microsoft.Extensions.Caching.OpenSource package.
TheIDistributedCache interface provides the following methods to manipulate items in the distributed cache implementation:
byte[] array if found in the cache.byte[] array) to the cache using a string key.Register an implementation ofIDistributedCache inStartup.ConfigureServices. Framework-provided implementations described in this topic include:
The Distributed Memory Cache (AddDistributedMemoryCache) is a framework-provided implementation ofIDistributedCache that stores items in memory. The Distributed Memory Cache isn't an actual distributed cache. Cached items are stored by the app instance on the server where the app is running.
The Distributed Memory Cache is a useful implementation:
The sample app makes use of the Distributed Memory Cache when the app is run in the Development environment inStartup.ConfigureServices:
services.AddDistributedMemoryCache();The Distributed SQL Server Cache implementation (AddDistributedSqlServerCache) allows the distributed cache to use a SQL Server database as its backing store. To create a SQL Server cached item table in a SQL Server instance, you can use thesql-cache tool. The tool creates a table with the name and schema that you specify.
Create a table in SQL Server by running thesql-cache create command. Provide the SQL Server instance (Data Source), database (Initial Catalog), schema (for example,dbo), and table name (for example,TestCache):
dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCacheA message is logged to indicate that the tool was successful:
Table and index were created successfully.The table created by thesql-cache tool has the following schema:

Note
An app should manipulate cache values using an instance ofIDistributedCache, not aSqlServerCache.
The sample app implementsSqlServerCache in a non-Development environment inStartup.ConfigureServices:
services.AddDistributedSqlServerCache(options =>{ options.ConnectionString = _config["DistCache_ConnectionString"]; options.SchemaName = "dbo"; options.TableName = "TestCache";});Note
AConnectionString (and optionally,SchemaName andTableName) are typically stored outside of source control (for example, stored by theSecret Manager or inappsettings.json/appsettings.{Environment}.json files). The connection string may contain credentials that should be kept out of source control systems.
Redis is an open source in-memory data store, which is often used as a distributed cache. You can configure anAzure Redis Cache for an Azure-hosted ASP.NET Core app, and use an Azure Redis Cache for local development.
An app configures the cache implementation using aRedisCache instance (AddStackExchangeRedisCache).
The following code enables the Azure Cache for Redis:
public void ConfigureServices(IServiceCollection services){ if (_hostContext.IsDevelopment()) { services.AddDistributedMemoryCache(); } else { services.AddStackExchangeRedisCache(options => { options.Configuration = _config["MyRedisConStr"]; options.InstanceName = "SampleInstance"; }); } services.AddRazorPages();}The preceding code assumes the Primary connection string (StackExchange.Redis) was saved in configuration with the key nameMyRedisConStr.
For more information, seeAzure Cache for Redis.
Seethis GitHub issue for a discussion on alternative approaches to a local Redis cache.
Azure Database for PostgreSQL can be used as a distributed cache backing store via theIDistributedCache interface. Azure Database for PostgreSQL is a fully managed, AI-ready Database-as-a-Service (DBaaS) offering built on the open-source PostgreSQL engine, designed to support mission-critical workloads with predictable performance, robust security, high availability, and seamless scalability.
After installing theMicrosoft.Extensions.Caching.Postgres NuGet package, configure your distributed cache as follows:
using Microsoft.Extensions.DependencyInjection;var builder = WebApplication.CreateBuilder(args);// Register Postgres distributed cachebuilder.Services.AddDistributedPostgresCache(options => { options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache"); options.SchemaName = builder.Configuration.GetValue<string>("PostgresCache:SchemaName", "public"); options.TableName = builder.Configuration.GetValue<string>("PostgresCache:TableName", "cache"); options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists", true); options.UseWAL = builder.Configuration.GetValue<bool>("PostgresCache:UseWAL", false); // Optional: Configure expiration settings var expirationInterval = builder.Configuration.GetValue<string>("PostgresCache:ExpiredItemsDeletionInterval"); if (!string.IsNullOrEmpty(expirationInterval) && TimeSpan.TryParse(expirationInterval, out var interval)) { options.ExpiredItemsDeletionInterval = interval; } var slidingExpiration = builder.Configuration.GetValue<string>("PostgresCache:DefaultSlidingExpiration"); if (!string.IsNullOrEmpty(slidingExpiration) && TimeSpan.TryParse(slidingExpiration, out var sliding)) { options.DefaultSlidingExpiration = sliding; }});var app = builder.Build();public class MyService { private readonly IDistributedCache _cache; public MyService(IDistributedCache cache) { _cache = cache; } public async Task<string> GetDataAsync(string key) { var cachedData = await _cache.GetStringAsync(key); if (cachedData == null) { // Fetch data from source var data = await FetchDataFromSource(); // Cache the data with options var options = new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(5) }; await _cache.SetStringAsync(key, data, options); return data; } return cachedData; }}NCache is an open source in-memory distributed cache developed natively in .NET and .NET Core. NCache works both locally and configured as a distributed cache cluster for an ASP.NET Core app running in Azure or on other hosting platforms.
To install and configure NCache on your local machine, seeGetting Started Guide for Windows (.NET and .NET Core).
To configure NCache:
InstallNCache open source NuGet.
Configure the cache cluster inclient.ncconf.
Add the following code toStartup.ConfigureServices:
services.AddNCacheDistributedCache(configuration => { configuration.CacheName = "demoClusteredCache"; configuration.EnableLogs = true; configuration.ExceptionsEnabled = true;});To use theIDistributedCache interface, request an instance ofIDistributedCache from any constructor in the app. The instance is provided bydependency injection (DI).
When the sample app starts,IDistributedCache is injected intoStartup.Configure. The current time is cached usingIHostApplicationLifetime (for more information, seeGeneric Host: IHostApplicationLifetime):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, IDistributedCache cache){ lifetime.ApplicationStarted.Register(() => { var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options); });The sample app injectsIDistributedCache into theIndexModel for use by the Index page.
Each time the Index page is loaded, the cache is checked for the cached time inOnGetAsync. If the cached time hasn't expired, the time is displayed. If 20 seconds have elapsed since the last time the cached time was accessed (the last time this page was loaded), the page displaysCached Time Expired.
Immediately update the cached time to the current time by selecting theReset Cached Time button. The button triggers theOnPostResetCachedTime handler method.
public class IndexModel : PageModel{ private readonly IDistributedCache _cache; public IndexModel(IDistributedCache cache) { _cache = cache; } public string CachedTimeUTC { get; set; } public async Task OnGetAsync() { CachedTimeUTC = "Cached Time Expired"; var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC"); if (encodedCachedTimeUTC != null) { CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC); } } public async Task<IActionResult> OnPostResetCachedTime() { var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC); var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options); return RedirectToPage(); }}Note
There's no need to use a Singleton or Scoped lifetime forIDistributedCache instances (at least for the built-in implementations).
You can also create anIDistributedCache instance wherever you might need one instead of using DI, but creating an instance in code can make your code harder to test and violates theExplicit Dependencies Principle.
When deciding which implementation ofIDistributedCache is best for your app, consider the following:
Caching solutions usually rely on in-memory storage to provide fast retrieval of cached data, but memory is a limited resource and costly to expand. Only store commonly used data in a cache.
Generally, a Redis cache provides higher throughput and lower latency than a SQL Server cache. However, benchmarking is usually required to determine the performance characteristics of caching strategies.
When SQL Server is used as a distributed cache backing store, use of the same database for the cache and the app's ordinary data storage and retrieval can negatively impact the performance of both. We recommend using a dedicated SQL Server instance for the distributed cache backing store.
Was this page helpful?
Need help with this topic?
Want to try using Ask Learn to clarify or guide you through this topic?
Was this page helpful?
Want to try using Ask Learn to clarify or guide you through this topic?