Performance is the main concern when thinking about the success of any website. We have thousands of website available which perform similar tasks but not all are popular. Among these thousands of website, some are popular which has highly optimized data, security and well performing.  We always prefer to use those websites which are frequently accessible in minimum time.

Let’s take one example, we have multiple search engines available like Google, Bing, Baidu, and many more. But you all know, we prefer GOOGLE and BING, because these are accessible within 3-4 seconds with search results. Let suppose if these take more than 10 seconds to search the result then do you think, we go with these. I don’t think so. We generally don’t want to wait for the results. We always want the results in minimum time without wasting much time. So, as per the above discussion, we can say performance is the main concern of any website. If your website is not performing well then the minimum user will interact with your website.

Today, we will learn a few points which we can be implemented while developing the website in Asp.NET Core to improve the performance.

Asp.Net Core is free, open source and cross-platform web development framework which is created by Microsoft. It is not upgraded version on Asp.Net but it is completely rewritten from scratch which comes with a single programming model of Asp.Net MVC and Asp.Net Web API.

Here, I am not going to discuss the features of Asp.NET Core. You can follow some of the most popular articles which help you to understand the Asp.NET Core. Let's start the tips for performance improvement of Asp.Net Core application.

  1. 10 New Features of Asp.NET Core 2.0
  2. First application in Asp.Net Core MVC 2.0
  3. Publish Asp.NET Core 2.0 Application on IIS 
  4. CRUD operations in Asp.NET Core Web API with Entity Framework Core 
  5. Code First approach in Asp.NET Core MVC with EF Core Migration   
  6. Authentication and Authorization in Asp.NET Core MVC using Cookie   
  7. Asp.NET Core Web API with Oracle database and Dapper   
  8. Razor Pages in Asp.NET Core 2.0   
  9. CRUD operations in Asp.NET CORE 2.0 Razor Pages with Dapper and Repository Pattern 
  10. .NET Framework vs .Net Core vs .Net Standard   


1. Always use Asp.NET Core latest version

As the first version of Asp.Net Core was released in 2016 with Visual Studio 2015 and now we have Asp.Net Core 2.2 version available. If you compare the performance improvement from the beginning version to current version, you will find that the application developed in Asp.Net Core 2.2 (current latest version) is running very fast as compared to the previous version. Microsoft always brings with some performance improvement in the next version as compared to the previous version.

So, while creating the application using Asp.Net Core, always prefer to use the latest version of Asp.Net Core. With the latest version, you will definitely find the performance improvement. Next version of Asp.Net Core is 3.0 which is under development and hope it will be released very soon with Visual Studio 2019.


2. Avoid Synchronous call in any level

While developing the Asp.Net Core application, just try to avoid to create blocking calls. Blocking call means which blocks the next execution until it will not be completed. Blocking call or Synchronous call can be anything, either you are fetching the data from API or performing some operations internally. You should always execute the call in an asynchronous manner.


3. Always use Asynchronous programming (Async-Await)

Asynchronous programming model was introduced in C# 5.0 and became very popular. Asp.Net Core uses the same Asynchronous Programming paradigm to make an application more reliable, faster and responsiveness.

You should use end to end Asynchronous Programming while writing the code. Let’s take one example, we have one Asp.Net Core MVC application with database implementation. As we know, it could many separations and it all depends on user project architecture but take some simple example where we have Controller > Repository Layer etc. Let see, how you will write the sample code at the controller level.

public async Task<IActionResult> GetPosts()
        var posts = await postRepository.GetPosts();
        if (posts == null)
            return NotFound();

        return Ok(posts);
    catch (Exception)
        return BadRequest();


This is how we will implement the asynchronous programming at the repository level.

public async Task<List<PostViewModel>> GetPosts()
    if (db != null)
         return await (from p in db.Post
                       from c in db.Category
                       where p.CategoryId == c.Id
                       select new PostViewModel
                            PostId = p.PostId,
                            Title = p.Title,
                            Description = p.Description,
                            CategoryId = p.CategoryId,
                            CategoryName = c.Name,
                            CreatedDate = p.CreatedDate
      return null;


4. Avoid Task.Wait or Tast.Result with Asynchronous Programming

While working with Asynchronous Programming, we recommended you to avoid to use Task.Wait and Task.Result and try to use await because of the following reason.

  1. These block the thread until the task completed and wait for completion of the task. Task.Wait block the thread synchronously until the task completion.
  2. Task.Wait and Task.Result both wrap any type of exception in AggregateException and create the complexity while doing exception handling. If you use the await instead of Task.Wait and Task.Result then you don’t have to worry about exception handling.
  3. Sometimes, these both block the current thread and create DEADLOCKS situation.
  4. Task.Wait and Task.Result only can be used if parallel task execution is going on. We recommend that don’t use it with Async programming.

Let's understand a good and bad example of Task.Wait as follows.

// Good Performance
Task task = DoWork(); 
await task; 

// Bad Performance
Task task = DoWork(); 

Let's understand a good and bad example of Task.Result as follows.

// Good Performance on UI
Task<string> task = GetEmployeeName(); 
txtEmployeeName.Text = await task; 

// Bad Performance on UI
Task<string> task = GetEmployeeName(); 
txtEmployeeName.Text = task.Result; 

Know more about Best Practices for Asynchronous Programming.


5. Perform I/O Operations Asynchronously

While performing I/O operations, you should perform it asynchronously without affecting the other processes. I/O operations mean, doing some execution with a file like uploading or retrieving files. It could be anything like image uploading, file uploading or anything else. If you try to accomplish it in a synchronous manner then it blocks the main thread and stops the other background execution till the I/O does not complete. So, as per the performance point of view, you should always use the Asynchronous execution for I/O operations.

We have lots of Async methods available for I/O operations like ReadAsync, WriteAsync, FlushAysnc etc. Here is one simple example, how we can create a copy of one file asynchronously.

public async void CreateCopyOfFile()
    string dir = @"c:\Mukesh\files\";

    using (StreamReader objStreamReader= File.OpenText(dir + "test.txt"))
        using (StreamWriter objStreamWriter= File.CreateText(dir+ "copy_test.txt"))
            await CopyFileToTarget(objStreamReader, objStreamWriter);

public async Task CopyFileToTarget(StreamReader objStreamReader, StreamWriter objStreamWriter) 
    int num; 
    char[] buffer = new char[0x1000]; 

    while ((num= await objStreamReader.ReadAsync(buffer, 0, buffer.Length)) != 0) 
        await objStreamWriter.WriteAsync(buffer, 0, num);


6. Always Use Cache

We can increase the performance of the application if we can reduce the number of the request to the server every time. It does not mean that you will not make the call to the server, it only means that you will not make the call to server EVERYTIME. First time, you will make the call to the server and get the response and this response store somewhere for future perspective for some time (There will be some expiry) and next time when you will make the call for the same response then first you will check that if you have already got data in the first request and stored somewhere and if it is yes then you will use the stored data rather than making the call to the server.

Keeping the data in that location from where we can get it frequently without making the call to the server is a good practice. Here, we can use the Cache. Caching the content helps us to reduce server calls again and again and it helps us to increase the performance of the application. We can do the cache at any point of a location like on client-side caching, server-side caching or client/server side caching.

We have different kinds of caching available in Asp.Net Core like we can do the caching In-Memory or we can use Response caching or we can use Distributed Caching. More about Caching in Asp.Net Core

public async Task<IActionResult> GetCacheData()
    var cacheEntry = await
        _cache.GetOrCreateAsync(CacheKeys.Entry, entry =>
        entry.SlidingExpiration = TimeSpan.FromSeconds(120);
        return Task.FromResult(DateTime.Now);

    return View("Cache", cacheEntry);


7. Optimize Data Access

We can also improve the performance of the application to optimize the data access logic. As we all know, most of the application totally dependent on the database and every time we have to fetch the data from a database and need to show on UI. If it is time-consuming than application will take much time to load. Here we have a few techniques which can be implemented while doing the code which can improve the performance much better.

  1. Reduce the number of HTTP calls, means you should always try to reduce the number of network round trips.
  2. Try to get all the data in one go. Means rather than making multiple calls to the server, just make one or two calls which can bring all required data.
  3. Frequently set the cache on data which is not being changed.
  4. Don’t try to get the data in advance which is not required, it will increase the load on the response and your application will load slower.


8. Optimize Custom Code

Apart from optimizing the data access logic, we can also optimize the business logic or middleware custom code. Optimizing or refactoring these codes help us to improve the performance of the applications. Here we have some points on which we should give the focus.

  1. Custom Logging, Authentication or some custom handler code which execute on every request should be optimized.
  2. Don’t perform custom long-running custom execution in the business logic layer or middleware, it basically blocks the request to go to the server and application takes much time to get the data. You should have optimized code for this, either at the client side or database side.
  3. Always check that a long-running task should be performed asynchronously without affecting other processes.
  4. You can take real-time client-server communication example as SignalR which works asynchronously.


9. Entity Framework Core Query Optimization

As we all know, EF Core is an ORM for .Net developers which helps us to play with database object without writing much code as usual. It helps us to use a database using Models. Data access logic code can play a vital role in performances. If your code is not optimized than your application will not perform well.

But if you write your data access logic in optimize ways in EF Core then definitely it improves the performance of the application. Here we have some of the techniques which will increase the performance.

  1. Us No Tracking while getting the data which is the only read-only purpose. It improves performance.
  2. Try to filter the data at the database side, don’t fetch the whole data using query and then filter at your end. You can use some function available in EF Core like Where, Select etc. which help you to filter the data at the database side.
  3. Retrieve the only required number of records which is necessary using the help of Take and Skip function. You can take one example of paging where you can implement Take and Skip while clicking on the page number.

Let's take one example and try to understand how we can optimize the EF Core query using Select and AsNoTracking.  

public async Task<PaginatedList<Post>> GetPagedPendingPosts(int pageIndex, int pageSize, List<Category> allowedCategories)
    var allowedCatIds = allowedCategories.Select(x => x.Id);
    var query = _context.Post
        .Include(x => x.Topic.Category)
        .Include(x => x.User)
        .Where(x => x.Pending == true && allowedCatIds.Contains(x.Topic.Category.Id))
        .OrderBy(x => x.DateCreated);

    return await PaginatedList<Post>.CreateAsync(query.AsNoTracking(), pageIndex, pageSize);


10. Some Other Tips

Here we have some other performance improvement stuff which can be implemented in Asp.Net Core application.

  1. Write logic in such a way for the process which is optimized and tested and which minimize the exception to be a part of the flow. Less number of chances to execute the exception code means high performed application.
  2. Always try to use simple ADO.NET code or highly performed ORM like Dapper for database operations. It is because if database operations will take much time to execute the query then it will decrease the performance of the application. As we all know, in the development phase, implementing the ADO.NET code and managing it, will take more time as compare to ORM implementation. But this is also true if you use simple ADO.NET than your application will be faster than as comparing if you use any other ORM.
  3. If response size is large than obvious it will take much time to load it. So, always reduce the response size using compression techniques and then load the data. You can implement the compression logic in middleware. We have some of the compression providers like Gzip, Brotli etc.
public void ConfigureServices(IServiceCollection services)

    services.Configure<GzipCompressionProviderOptions>(options =>
        options.Level = CompressionLevel.Fastest;


Bonus Tips (Client Side)

We would like to share some of the performance tips for client-side code. If you are creating a website using the Asp.Net Core MVC then I believe, you should always follow these tips to make your website well performing.

  • Bundling and Minification: Using these bundling and minification we can optimize the content before loading on UI. As per the performance point of view, always try to load all your client-side assets like JS/CSS in one go. It reduces the number of network hits. You can first minify your files using minification and then bundle those in one file which can be load faster and reduce the number of an HTTP request for resources.
  • Load JavaScript at Last: You should always try to load your JavaScript files at last. We have many benefits like first of all your website gets render in minimum time and when your JavaScript will execute then your DOM elements will be available. Using this, you can make your application faster.
  • Shrink Images:  Always avoid to load images in maximum size. Before loading, you can shrink the images using compression techniques.
  • Use CDN: If you have your custom CSS or JavaScript files then it’s OK to load it. But if you are using some third party libraries which has CDN version available then always try to use the CDN file path rather than downloaded library file path from your end. It is because CDN has different servers available on a different zone, if you are using a website in one zone then you will get the CDN file from your zone server when you hit the website, which is very fast.



So, today we have learned how to improve the performance of an Asp.Net Core application.

I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends. Thanks