Cookie Consent by Free Privacy Policy Generator Scaling ASP.NET Core Web APIs with NCache

Scaling ASP.NET Core Web APIs with NCache

As modern software ecosystems evolve, scalability and performance have become fundamental goals for application design. Back in the day, Service-Oriented Architecture (SOA) laid the foundation for building distributed systems. Today, ASP.NET Core Web APIs have extended that vision, offering lightweight, cross-platform, and high-performance services for the cloud era.

But here's the thing: just adding more servers won't automatically make your application faster. The real slowdown often happens when your application talks to the database. Think about it - every time you need data, your application has to wait for the database to find and send that information. This is especially bad when many people are using your application at the same time.

A proven solution to this challenge is distributed caching. That's where NCache comes in. NCache is an enterprise-grade, distributed in-memory caching solution built specifically for .NET applications. It enhances scalability and responsiveness by reducing database round trips, keeping frequently accessed data in memory, and distributing cache across multiple servers for high availability.

This article demonstrates how to integrate NCache into your ASP.NET Core Web API to achieve low-latency, fault-tolerant, and cloud-scalable performance.

Key Takeaways

  • Linear Scalability: Unlike local in-memory caching, NCache provides a distributed architecture that allows ASP.NET Core APIs to scale horizontally without losing data consistency.
  • Database Acceleration: By reducing redundant round-trips to the database, NCache significantly lowers I/O latency and prevents CPU spikes during high-traffic periods.
  • Modern .NET 10 Implementation: Utilize C# 10+ features like Primary Constructors and File-Scoped Namespaces to keep integration code clean, readable, and maintainable.
  • Data Reliability: Features like High Availability (replication) and Write-Behind Caching ensure that your application remains fault-tolerant and responsive even under heavy loads.
  • Automated Consistency: Use SQL Cache Dependency to automatically invalidate stale data when the underlying database changes, ensuring the cache always reflects the latest information.
Architecture diagram showing an NCache cluster reducing database traffic
NCache architecture: Linear scalability across .NET, Java, Node.js, and Python.
 

Removing Database Bottlenecks with NCache Distributed Caching

Traditional in-memory caching is confined to a single server - it works for small applications but quickly becomes a bottleneck when scaling out. NCache, on the other hand, provides:

  • Distributed architecture - keeps cache data synchronized across all servers.
  • Reduced database load - minimizes repetitive queries, which prevents CPU spikes during high-traffic.
  • Faster API responses - serve data from memory instead of storage.
  • High availability - ensures continuity if any cache node fails.
  • Cloud-native scalability - integrates seamlessly with containerized deployments.
Feature Local In-Memory Caching NCache Distributed Caching
Scalability Limited to a single server node Linear scalability across multi-node clusters
Data Consistency Inconsistent across multiple servers Real-time synchronization across all nodes
Availability Cache Data is lost if the server restarts High availability with data replication
Data Capacity Limited by single-server RAM Aggregated RAM of the entire cluster
Advanced Features Basic Key/Value storage SQL-like queries, Pub/Sub, and DB Dependency

In essence, NCache acts as your data acceleration layer, ensuring APIs respond faster and scale seamlessly.

Now that we understand why NCache is valuable for improving API performance, let's see how to put it into action. The following section walks through integrating NCache into an ASP.NET Core Web API step by step.

 

Integrating NCache into Your ASP.NET Core Web API

Assuming you already have a running ASP.NET Core Web API project created via the standard template (using dotnet new Web API or Visual Studio). For project setup details, see the Microsoft ASP.NET Core Web API documentation.

We'll now extend it by integrating NCache to handle data caching efficiently.

  • Step 1: Install NCache SDK

    Add the NCache SDK to your project using the .NET CLI or NuGet Package Manager:

    dotnet add package Alachisoft.NCache.SDK

    This package includes APIs required to connect and interact with your distributed cache cluster.

  • Step 2: Connect to an Existing NCache Cluster

    Ensure that:

    • NCache (Enterprise or Open Source) is installed.
    • A cache cluster (for example, demoCache) is configured and running.
    • Your API server can communicate with the cache cluster nodes.
  • Step 3: Register NCache in the Application Startup

    In the Program.cs file (or Startup.cs in older projects), register NCache as a singleton service so that the same cache connection is shared across the application.

    var builder = WebApplication.CreateBuilder(args);
    
    // Services Configuration
    builder.Services.AddControllers();
    
    // Register NCache as a singleton
    builder.Services.AddSingleton<ICache>(_ =>
    {
        const string cacheName = "demoCache";
        try
        {
            // CacheManager.GetCache establishes the physical socket connection to the cluster
            var cache = CacheManager.GetCache(cacheName);
            Console.WriteLine("[NCache] Cache connection established successfully.");
            return cache;
        }
        catch (Exception ex)
        {
            // Logging the specific failure (e.g., server down or cache name mismatch)
            Console.WriteLine($"[NCache] Connection Error: {ex.Message}");
            throw;
        }
    });
    
    var app = builder.Build();
    
    // Immediate Connection
    // We resolve the ICache service here to trigger the GetCache() logic immediately rather than waiting for the first HTTP request to arrive.
    try
    {
        _ = app.Services.GetRequiredService<ICache>();
    }
    catch
    {
        Console.WriteLine("[NCache] Failed to initialize cache on startup.");
    }
  • Step 4: Use NCache in Your API Controllers

    By utilizing the ICache interface, your controller implements the Cache-Aside pattern, which allows the Web API to serve data from memory and significantly reduce database I/O latency.

    The default Web API template already includes a Controllers folder and model classes (such as WeatherForecast or custom entities).

    You can update existing controllers or create new ones to use NCache for caching frequently accessed data.

    namespace AspNetCoreWebApi.Controllers; // File-scoped namespace
    
    [ApiController]
    [Route("api/[controller]")]
    
    // Primary Constructor: 'cache' is automatically available to all methods in the class
    public class ProductsController(ICache cache) : ControllerBase
    {
        [HttpGet("{id}")]
        public IActionResult GetProduct(string id)
        {
            // Try to fetch from memory (The "Cache-Aside" pattern)
            var product = cache.Get<Product>(id);
           
            return product is not null
                ? Ok(new { Message = $"[NCache] Product retrieved: {product.Name}", Data = product })
                : NotFound($"[NCache] Product with ID '{id}' not found in cache.");
        }
    
        [HttpPost]
        public IActionResult AddProduct([FromBody] Product product)
        {
            // Null-conditional check on the ID property
            if (string.IsNullOrEmpty(product?.Id))
                return BadRequest("[NCache] Invalid product data.");
    
            var cacheItem = new CacheItem(product)
            {
                // Create item with Absolute Expiration policy
                // .NET 10 Target-typed new 'new(...)' reduces redundancy
                Expiration = new(ExpirationType.Absolute, TimeSpan.FromMinutes(10))
            };
    
            cache.Insert(product.Id, cacheItem);
            return Ok($"[NCache] Product '{product.Name}' added to cache with key: {product.Id}");
        }
    
        [HttpDelete("{id}")]
        public IActionResult RemoveProduct(string id)
        {
            if (!cache.Contains(id))
            {
                return NotFound($"[NCache] No product found in cache with ID '{id}'.");
            }
    
            cache.Remove(id);
            return Ok($"[NCache] Product with ID '{id}' removed from cache.");
        }
    }
  • Step 5: Run and Test Your API with Swagger

    Build and run the application. Once running, Swagger automatically opens in your browser at: https://localhost:<port>/swagger.

    From here, test these endpoints directly:

    • Add a Product: Adds an item to cache
      POST /api/products/add

      {
      "Id": "P101",
      "Name": "Laptop",
      "Price": 1200
      }
      
    • Retrieve the Product: Retrieve item from cache
      GET /api/products/get/{id}

    • Remove the Product: Delete item from cache
      DELETE /api/products/remove/{id}

You'll see all actions logged in the console and reflected in the NCache Management Center under your demoCache cluster.

 

Advanced NCache Features

Once the basic caching layer is functional, you can extend your implementation using NCache's advanced features to improve cache consistency, performance, and data synchronization. The following examples demonstrate how these capabilities can be integrated into your ASP.NET Core Web API.

 

Data Expiration (Automatic Cleanup)

NCache supports both absolute and sliding expirations to automatically remove stale data from the cache. This mechanism ensures that frequently accessed items remain valid while outdated entries are removed from the cache, maintaining cache accuracy and optimal memory usage.

// Define a cache item with 5-minute absolute expiration
var cacheItem = new CacheItem(product)
    {
        // Using static 'From' methods which are further optimized in .NET 10
        Expiration = new(ExpirationType.Absolute, TimeSpan.FromMinutes(10))
    };
// Insert item with expiration policy
cache.Insert(product.Id, cacheItem);
 

Database Dependency (Maintaining Data Consistency)

For scenarios where cached data is directly linked to a database record, NCache provides database dependency support. When the underlying record in the database changes, the corresponding cache item is automatically invalidated, ensuring cache consistency without manual intervention.

public class ProductService(ICache cache, IOptions<DbSettings> settings) 
{
    public void RegisterProduct(Product p) =>
    cache.Insert( 
        $"Product:{p.Id}",	
        p, 
        new SqlCacheDependency(settings.Value.Conn, "SELECT ProductID, ProductName FROM dbo.Products")
        );
}
 

Write-Behind Caching (Asynchronous Write Operations)

In high-throughput systems, synchronous database writes can create performance bottlenecks. NCache's write-behind caching queues update operations and performs them asynchronously in the background. This approach improves response times while maintaining data durability.

// Queue cache updates to be written asynchronously to the database
cache.Insert(
    $"Product:{p.Id}",
    p, 
    new CacheItemVersion(), 
    null, 
    WriteMode.WriteBehind
);
 

Conclusion

Scalable service architectures rely not only on distributed design but also on fast and efficient data access. While ASP.NET Core Web APIs ensure scalability at the application level, NCache guarantees the same at the data layer.

By integrating NCache, you can:

  • Reduce database load and improve response times
  • Easily manage high concurrent traffic
  • Automatically maintain data freshness and consistency

Distributed caching isn't just a performance optimization - but also for enabling cloud-based scalability and enterprise-level resilience.

What to Do Next?

Frequently Asked Questions (FAQ)

NCache uses SQL Cache Dependency to monitor database changes. If a record is updated in SQL Server, NCache automatically invalidates or updates the corresponding item in the cache, ensuring your Web API never serves stale data.

Absolute Expiration: The item expires at a fixed time (e.g., 10 minutes) regardless of access.
Sliding Expiration: The expiration clock resets every time the item is accessed.

Yes. NCache is cloud-native and integrates with Docker and Kubernetes (AKS, EKS), supporting dynamic scaling for ASP.NET Core services.

© Copyright Alachisoft 2002 - . All rights reserved. NCache is a registered trademark of Diyatech Corp.