ASP.NET has become developers’ foremost choice in developing high-traffic web applications. Because of its scalable nature, the ASP.NET application tier can seamlessly handle thousands of concurrent users with millions of requests per day. Such high-traffic ASP.NET applications are deployed in a load-balanced web farm with a load balancer, routing user requests to multiple web servers.
While the ASP.NET application tier performs exceptionally well even during high transactional loads, the application faces some critical scalability bottlenecks in other areas. These bottlenecks can slow down your ASP.NET application, and it may even halt when your business activity is at its peak.
The Problem: Four Performance Bottlenecks
These four ASP.NET performance bottlenecks are described below:
Database Bottleneck
In a load-balanced web farm, when the transaction load increases, you can easily add more web servers to scale linearly. But you cannot add more database servers to the database tier (SQL Server, Oracle, others) in the same fashion. So, the database starts to slow down and may even crash at one point. This breakdown is the most critical performance bottleneck that your application faces.
ASP.NET Session State Storage Bottleneck
ASP.NET Session State needs to be stored somewhere, and its storage becomes a bottleneck like the application database. There are three storage options provided by Microsoft, namely InProc, State Server, and SQL Server. All three have performance bottlenecks.
InProc forces you to use a single worker process per web server, which does not work in a multi-processor or a multicore environment, where having multiple worker processes is preferred.
And, in a load-balanced web farm, a sticky session bit is required on the load balancer for always sending user requests to the web server, creating the session, even if this web server is overloaded while others are idle.
Also, SQL Server is not an ideal store for ASP.NET Session State because it stores them as BLOBs, and SQL Server doesn’t perform well with it.
NCache Details ASP.NET Session Caching ASP.NET Session Caching Docs
ASP.NET View State Bottleneck
ASP.NET View State is a client-side state management feature constructed on the web server to keep the data of controls such as buttons and drop-downs. This data is sent to the browser only to return when a postback occurs. And an ASP.NET View State string can easily be 100’s of KBs in size, multiplied by millions of requests you receive each day.
This not only slows down the response time of your ASP.NET application but also consumes a lot of extra bandwidth that can significantly increase your operational cost.
Needless Page Execution
Many times, ASP.NET page output does not change across multiple requests because the underlying data didn’t change. But the page still executes to produce the same output as last time. This extra page execution consumes a lot of system resources including memory and CPU and also makes database calls.
The Solution: In-Memory Distributed Cache
The most appropriate solution to all these problems is to incorporate an In-Memory Distributed Cache in your ASP.NET and ASP.Net Core application. NCache is a popular open-source distributed cache for .NET. Let’s quickly discuss how to fix our four performance bottlenecks with NCache.
NCache Details ASP.NET Core Session Storage Strategies ASP.NET View State Caching Properties and Overview
Application Data Caching
NCache allows you to cache your application data (both read-only reference data and frequently changing transactional data) to reduce those expensive database trips. Instead of going to the database, NCache routes 85-90% of your requests to the cache. This rule out the chances of any database contention.
Unlike a database, NCache never becomes a bottleneck because it is a distributed cache and scales linearly. NCache builds a cluster of cache servers and allows you to add more servers to the cluster as your transaction load increases. Following is a sample code that fetches the data from the database and stores it in the cache cluster (If it is not already present in the cache).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Customer Load(string customerId) { // Key format: Customer:PK:1000 string key = "Customers:CustomerID:" + customerId; Customer cust = (Customer) _cache[key]; if (cust == null) { // Item not in cache so load from db LoadCustomerFromDb(cust); // Add item to cache for future reference _cache.Insert(key, cust); } return cust; } |
Session State Storage Configuration
NCache also lets you store your ASP.NET Sessions in the cache. This is a much faster in-memory store than your other storage options. To provide reliability, NCache replicates your sessions on multiple servers. So, if a server crashes, there will be no loss of session data.The nice thing about ASP.NET Session State storage in NCache is that there is no programming effort, and you can plug it in seamlessly through a web.config change. Below is an example.
1 2 3 4 5 6 7 8 9 |
<configuration> ... <sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="NCacheSessionProvider" timeout="20"> <providers> <add name="NCacheSessionProvider" |
View State Configuration
NCache lets you cache your ASP.NET View State on the web server end by sending only an identifier key to the browser. While returning in a postback, NCache fetches the View results by intercepting the identifier key through its HTTP Handler. This View State is then sent to your ASP.NET page.
The net result is a much faster ASP.NET application with a much smaller bandwidth footprint. Below is a config change example of how to use NCache for caching ASP.NET View State:
ASP.NET Output Cache
To prevent the needless execution of ASP.NET pages when their output doesn’t change, ASP.NET provides an Output Cache framework for single server and single worker process configurations. NCache, on the other hand, extends it for multi-server and multiple-worker processes configurations.
Through NCache, you can also expect your pages to expire when their related data is modified in the database. Below is an example.
Conclusion
In short, NCache an in-memory distributed cache with linear scalability, simple view state configuration and seamless configuration with your application is the best solution for all these performance bottlenecks. These features optimize the performance of your .Net application and make it faster, more reliable, and highly available.