Codenil

Mastering Distributed Caching in .NET with Azure PostgreSQL

Published: 2026-05-04 12:36:19 | Category: Cloud Computing

This guide walks through building a .NET 10 console application that demonstrates high-performance distributed caching using Azure Database for PostgreSQL and the HybridCache package. You'll learn how to set up a host-based application with dependency injection, logging, and configuration, simulate expensive data calls, securely manage secrets, store cache values in a PostgreSQL database, and benchmark performance improvements. The patterns shown are production-ready and applicable to real-world microservices and high-throughput systems.

How do you set up a .NET console project with the generic host for caching?

Start by creating a new console project: mkdir dcache-demo && cd dcache-demo && dotnet new console. Then add the hosting package with dotnet add package Microsoft.Extensions.Hosting. This brings in the generic host, which provides dependency injection, configuration, logging, and hosted services. Now replace Program.cs with host-based scaffolding using Host.CreateDefaultBuilder(args). Inside the builder, configure application settings via ConfigureAppConfiguration, register services in ConfigureServices, and set up logging in ConfigureLogging. Finally, call builder.Build().RunAsync(). This foundation allows you to easily add caching components like HybridCache and connect to PostgreSQL later. The setup works identically on Windows and Linux.

Mastering Distributed Caching in .NET with Azure PostgreSQL
Source: devblogs.microsoft.com

What are the benefits of using the HybridCache package in .NET?

HybridCache, available in .NET 10, automatically combines an in-memory cache (e.g., IMemoryCache) with a persistent distributed cache (e.g., Redis or PostgreSQL). This dual-layer approach offers the speed of local memory for frequently accessed data while providing the reliability and capacity of a shared distributed store. Key benefits include reduced latency for hot cache items, automatic cache coherency between local and distributed layers, and simpler code because you only need to interact with one cache abstraction. It also supports features like cache stamps and eviction notifications. In our demo, we use HybridCache to store simulated expensive data calls in both memory and Azure PostgreSQL, resulting in dramatic performance improvements that scale with your application.

How do you securely manage connection strings and secrets in a caching application?

Secure management of secrets is critical when connecting to Azure services. Use the .NET Secret Manager during development: dotnet user-secrets init then set values like dotnet user-secrets set "ConnectionStrings:PostgresCache" "Server=...". At runtime, the generic host automatically loads secrets from the user secrets store. For production, utilize Azure Key Vault by adding Azure.Identity and Azure.Extensions.AspNetCore.Configuration.Secrets packages. Configure AddAzureKeyVault in ConfigureAppConfiguration. This ensures that sensitive data like connection strings, access keys, or passwords are never in source code. The appsettings.json file can hold non-sensitive placeholders, while real values come from secure sources. This pattern follows best practices for zero-trust environments.

How can you simulate expensive data calls to test cache performance?

Simulating expensive calls is done with a DelayAsync method that introduces a configurable sleep (e.g., 500–2000 ms) to mimic slow external APIs, database queries, or microservice calls. In a hosted service, you can call this method inside a loop that fetches data—first without caching, then with caching. For example, a GetDataAsync function checks the cache first. If a cache hit occurs, it returns immediately; if not, it calls DelayAsync (simulating the work) and then stores the result in the cache. By measuring elapsed time with Stopwatch, you can compare the uncached vs. cached execution times. This clearly demonstrates the latency reduction that caching provides, making it easy to quantify the improvement in your demo.

Mastering Distributed Caching in .NET with Azure PostgreSQL
Source: devblogs.microsoft.com

What steps are needed to integrate Azure Database for PostgreSQL as a distributed cache backend?

First, provision an Azure Database for PostgreSQL Flexible Server. In your .NET project, install packages: Npgsql and Microsoft.Extensions.Caching.Hybrid. Additionally, you may need Microsoft.Extensions.Caching.StackExchangeRedis if using Redis; but here we focus on PostgreSQL. To use PostgreSQL as a distributed cache, you implement a custom IDistributedCache that stores key-value pairs in a table. Alternatively, leverage a community library like EntityFrameworkCore.Cache or PgCache. Register the cache service in ConfigureServices using services.AddStackExchangeMemoryCache() combined with services.AddHybridCache() and the custom PostgreSQL store. Configure the connection string from secure secrets. Finally, in your application code, inject HybridCache and use its GetOrCreateAsync method to automatically manage the two cache tiers.

How does the application benchmark cache performance and highlight improvements?

Benchmarking is built into the demo using a Stopwatch to measure request duration. After setting up the cache (as described in question 1), you create a background service that repeatedly fetches the same data. On the first request, there is an expensive simulated delay (e.g., 1000 ms). Once cached, subsequent requests complete almost instantly (sub-millisecond). The code logs both the raw data and the time taken. For clarity, results can be output to the console in a table showing request number, source (cache vs. fresh), and elapsed time. This empirical evidence proves how dramatically caching reduces latency. The demo can also display the cache hit ratio over multiple requests, reinforcing the value of HybridCache's dual-layer strategy.

What production-ready patterns does this demo demonstrate for caching in .NET?

The demo illustrates several patterns you can directly carry into production: 1) Use of the .NET generic host for clean separation of concerns (DI, configuration, logging). 2) Secure secret management via user-secrets and Azure Key Vault. 3) Structured logging with ILogger for monitoring. 4) Simulating unreliable external dependencies to test resilience. 5) Implementing a distributed cache with HybridCache that seamlessly blends local memory and PostgreSQL. 6) Benchmarking and observability to verify caching benefits. 7) Separation of cache initialization logic from business code. These patterns help build scalable, high-performance microservices that can handle millions of requests while maintaining low latency. By following this guide, you create a reference architecture that is both testable and deployable to Azure.