<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel xmlns:media="http://search.yahoo.com/mrss/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <title>ABP.IO Stories</title>
    <link>https://abp.io/community/articles</link>
    <description>A hub for ABP Framework, .NET, and software development. Access articles, tutorials, news, and contribute to the ABP community.</description>
    <lastBuildDate>Thu, 22 Oct 2026 17:24:28 Z</lastBuildDate>
    <generator>Community - ABP.IO</generator>
    <image>
      <url>https://abp.io/assets/favicon.ico/favicon-32x32.png</url>
      <title>ABP.IO Stories</title>
      <link>https://abp.io/community/articles</link>
    </image>
    <a10:link rel="self" type="application/rss+xml" title="self" href="https://abp.io/community/rss?member=leon.kosak" />
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/performance-optimization-of-.netbased-and-also-abpbased-application-pmdwhwxc</guid>
      <link>https://abp.io/community/posts/performance-optimization-of-.netbased-and-also-abpbased-application-pmdwhwxc</link>
      <a10:author>
        <a10:name>leon.kosak</a10:name>
        <a10:uri>https://abp.io/community/members/leon.kosak</a10:uri>
      </a10:author>
      <category>performance</category>
      <category>optimization</category>
      <title>Performance Optimization of .NET-based (and also abp-based) application</title>
      <description>Guide how to develop a performant and scalable abp-based application with minimal tech stack and on all layers (database, application backend, web application frontend, network).</description>
      <pubDate>Mon, 11 Dec 2023 10:36:27 Z</pubDate>
      <a10:updated>2026-10-22T16:26:01Z</a10:updated>
      <content:encoded><![CDATA[<h1>Performance Optimization of .NET-based application</h1>
<h2>Introduction</h2>
<p>In this article, we will look at how to improve performance of .NET-based application and therefore also abp framework-based application.</p>
<h2>Performance Optimization</h2>
<p>Application overall performance is determined by several factors such as:</p>
<ul>
<li>Execution times of database queries</li>
<li>Execution times of application backend code</li>
<li>Amount of data that has to be sent to the application frontend and/or inside (micro)services</li>
<li>Overall speed and occupancy of hardware, which provides the runtime for an application</li>
<li>Network connectivity speed and responsiveness (latency) on end devices (in case of web application or application which consumes REST or other type of API)</li>
</ul>
<p>In abp framework, all .NET code performance techniques can be used combined with abp framework-specific features.</p>
<h2>Database</h2>
<p>Keep database version and potential extensions (plugins) updated as much as possible.</p>
<p>However, most performance gains can be achieved with the techniques described below.</p>
<p><strong>Also, keep in mind that the performance of production databases heavily depends on regular maintenance (e.g.: defragmentation of indexes, statistics update,...).</strong></p>
<p><strong>Additional performance gains on database-level can be achieved with multiple replicas of the same database (synchronous or asynchronous replication - decision should be made based on client's requirements). Read-only database requests can be redirected to non-primary instances. These topics are not covered in this part of the documentation, because of dependence on specific database technology and also are not for software developers (but for DB admins). DB admins can establish multiple replicas environment and all described database optimization techniques below should work without any changes (with additional application performance gains).</strong></p>
<h3>Caching</h3>
<p>To improve performance on the database layer (regardless of database type), it's recommended to use caching wherever possible and safe and as long as possible.</p>
<p>Leverage:</p>
<ul>
<li><a href="https://docs.abp.io/en/abp/latest/Entity-Cache">Entity Cache</a></li>
<li><a href="https://docs.abp.io/en/abp/latest/Redis-Cache">Redis Cache</a></li>
</ul>
<h3>Paging Approach</h3>
<p>If <strong>Cursor Pagination</strong> can be used, then it is the preferred way how to effectively sort and paginate data from database. <a href="https://khalidabuhakmeh.com/cursor-paging-with-entity-framework-core-and-aspnet-core">This article</a> shows execution times and it's based on EF Core implementation.</p>
<h3>Denormalization techniques and JSON (RDBMS)</h3>
<p>Using <a href="https://en.wikipedia.org/wiki/Denormalization">denormalization</a> techniques can (significantly) reduce querying execution times.
Querying such pieces of data from different parts of application should be read from the location where the query is the most efficient (performance-wise).</p>
<p><strong>Writing the same piece of data multiple times inside different SQL tables or even databases consumes more disk space and requires careful domain logic to insert and update the same data across all locations inside a database (databases) as a transactional unit of work.</strong></p>
<p>Use denormalization techniques in conjunction with JSON capabilities (No-SQL capabilities) of modern RDBMS, which can extend denormalization even further.</p>
<p>Further reading:</p>
<ul>
<li><a href="https://learn.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server">JSON data in Microsoft SQL Server</a></li>
<li><a href="https://www.postgresql.org/docs/current/functions-json.html">JSON in PostgreSQL</a></li>
<li><a href="https://www.npgsql.org/efcore/mapping/json.html">JSON Mapping in Npgsql (EF Core)</a></li>
</ul>
<h3>Database sharding</h3>
<p>The smaller the database, the less data is for querying and this also means lower execution times.</p>
<ul>
<li>In multitenant applications, it is recommended to use per-tenant database or multiple databases per tenant (logging db, data db,...).
Each tenant database can be hosted inside different hardware performance tier (cost-effectiveness).</li>
<li>In a microservice environment, it's recommended to use database-per-microservice or even database-per-tenant-per-microservice
It is possible to achieve described sharding in abp framework:<br>
<a href="https://docs.abp.io/en/abp/latest/Connection-Strings">Connection Strings</a><br>
<a href="https://docs.abp.io/en/abp/latest/Multi-Tenancy">Multitenancy</a><br>
<a href="https://docs.abp.io/en/abp/latest/Entity-Framework-Core-Migrations">Entity Framework Core Migrations</a> (Look <a href="https://docs.abp.io/en/abp/latest/Entity-Framework-Core-Migrations#using-multiple-databases">Using Multiple Databases</a> section for migrations)</li>
</ul>
<h3>Database partitioning (RDBMS)</h3>
<p>Most modern RDBMS offers horizontal (and also vertical) <a href="https://en.wikipedia.org/wiki/Partition_(database)">partitioning</a>.
When querying performance is not good enough because of large tables, it's recommended to create horizontal partitions.</p>
<ul>
<li><a href="https://learn.microsoft.com/en-us/sql/relational-databases/partitions/partitioned-tables-and-indexes">Partitions in Microsoft SQL Server</a></li>
<li><a href="https://www.postgresql.org/docs/current/ddl-partitioning.html">Partitions in PostgreSQL</a></li>
</ul>
<h3>Database indexing, partitioning, denormalization, and sharding techniques</h3>
<p><strong>Database indexing, partitioning, denormalization, and sharding can be used in conjunction.</strong></p>
<h3>Entity Framework Core</h3>
<p>There are some general recommendations for writing efficient queries using EF Core, which are <a href="https://learn.microsoft.com/en-us/ef/core/performance/efficient-querying">described here</a>.</p>
<p>When maximum performance is needed (complex queries, very frequent queries,...), using <a href="https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/compiled-queries-linq-to-entities">Compiled queries</a> and/or <a href="https://learn.microsoft.com/en-us/ef/core/querying/sql-queries">SQL queries</a> can improve performance.</p>
<p>Use ReadOnly Repositories and NoTracking (EF Core feature) for read DB requests (abp v8.0 onwards).</p>
<p>For complex queries when LINQ is not suitable you can use <a href="https://docs.abp.io/en/abp/latest/Dapper">Dapper</a> (but prefer EF Core SQL queries instead of Dapper, because of similar approaches - keep technology stack and libraries as small as possible).</p>
<h2>Application layer (backend)</h2>
<ul>
<li><p><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/best-practices">Microsoft ASP.NET Core Best Practices</a> covers most topics regarding performance.
Best Practices is part of <a href="https://learn.microsoft.com/en-us/aspnet/core/performance/overview">Microsoft ASP.NET Core Performance</a> documentation.</p>
</li>
<li><p>Usege of <a href="https://docs.abp.io/en/abp/latest/Dependency-Injection#cached-service-providers">Cached Service Providers</a> (ICachedServiceProvider or ITransientCachedServiceProvider) to optimize dependency injection.</p>
</li>
<li><p>Using <a href="https://medium.com/@frederikbanke/improving-scalability-in-c-using-async-and-await-f97af1466922">asynchronous code</a> (<strong>async/await</strong>) wherever possible and not mixing synchronous and asynchronous code</p>
</li>
<li><p>For computationally intensive tasks, which can leverage parallel code use <a href="https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl">Task Parallel Library</a> (TPL) from Microsoft (available from .NET Framework 4.0 onwards).</p>
</li>
<li><p><a href="https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/performance/">Reduce memory allocations</a> wherever possible.</p>
</li>
<li><p><a href="https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder">Discover StringBuilder</a> performance benefits.
<a href="https://www.meziantou.net/stringbuilder-performance-pitfalls.htm">This article</a> shows performance benefits using StringBuilder.</p>
</li>
<li><p>Build deployment packages in <strong>Release</strong> mode (and with additional optimization possibilities (AoT,...)).</p>
</li>
<li><p>Updated to the latest stable version of .NET (and also abp framework) with latest runtime optimizations. Updating .NET is usually not a difficult task.</p>
</li>
</ul>
<h2>Frontend</h2>
<h3>ASP.NET Core MVC (Razor Pages)</h3>
<h4>Faster page loading</h4>
<ul>
<li>Using <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Bundling-Minification">Bundling &amp; Minifications</a> feature of abp framework wherever possible</li>
<li>Using <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Static-JavaScript-Proxies">Static JavaScript Client Proxies</a></li>
<li>Avoid longer loading times with blank pages with minimal server-side rendering and transfer loading on javascript level (ajax) with loading spinners for specific GUI elements which require more time to get data from backend</li>
</ul>
<h4>Faster Javascript execution</h4>
<p>Prefer <strong>NOT using jQuery</strong> (or jQuery-based libraries) in favor of pure modern Javascript code (<a href="https://en.wikipedia.org/wiki/ECMAScript_version_history">ECMAScript version</a>) if possible (based on application complexity, development time,...).</p>
<p>Based on potential client's browser limitations (older browsers), check with <a href="https://caniuse.com/">Can I Use</a> for javascript features availability.</p>
<p><em>abp framework (Commercial) with Razor Pages frontend option integrates jQuery by default, however, custom application code may not need jQuery.</em></p>
<hr />
<p>DevExpress also offers non-jQuery version of DevExtreme javascript suite for years now with <a href="https://community.devexpress.com/blogs/donw/archive/2017/11/09/devextreme-with-and-without-jquery-v17-2.aspx">noticeable performance gains</a>.</p>
<p>Keep in mind, that NuGet wrappers (for ASP.NET Core) for <a href="https://docs.devexpress.com/AspNetCore/401026/devextreme-based-controls/get-started/configure-a-visual-studio-project">DevExpress requires jQuery</a> under the hood. Avoid using NuGet wrappers in favor of plain javascript/typescript files included in .cshtml.</p>
<h2>Network</h2>
<p>This section applies to communication between frontend (MVC, Angular,...) and backend and also backend to databases and/or external API services.</p>
<ul>
<li>Reduce the number of calls via the network as much as possible (e.g. usage of API methods that return an array of entities,...)</li>
<li>Use modern compression algorithms (<a href="https://en.wikipedia.org/wiki/Brotli">Brotli</a>,...) wherever possible</li>
<li>Make calls in parallel if possible (usage of <a href="https://en.wikipedia.org/wiki/HTTP/2">HTTP/2</a> or newer protocol for frontend-backed communication and parallel calls from application backend to external services)</li>
<li>Prefer lighter data formats (e.g. JSON over XML, <a href="https://en.wikipedia.org/wiki/Protocol_Buffers">Protobuf</a> over JSON) for fewer data size transfers and/or faster serialization/deserialization</li>
<li>Prefer vector-based data formats for graphics elements instead of raster graphics wherever possible</li>
</ul>
<p><strong>Network engineers can establish specific caching on network-level to further speed-up application (reduce the number of requests that come to the application backend - API). However, this type of optimization should be applied carefully, because application can start behave unpredictable (wrong responses) even the backend code is written correct.</strong></p>
<h2>Optimizing for Production</h2>
<p>abp framework documentation about <a href="https://docs.abp.io/en/abp/latest/Deployment/Optimizing-Production">Optimizing Your Application for Production Environments</a></p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a0f6a9f-f3c6-7bf4-ea26-a48d8f724427" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a0f6a9f-f3c6-7bf4-ea26-a48d8f724427" medium="image" />
    </item>
  </channel>
</rss>