Adding Tiered Compilation in .Net Core 2.1

One of the many great features of .Net Core is its performance, which it certainly excels at.

A few weeks back I seen a new performance feature, well preview feature in .Net Core 2.1 – called “Tiered compilation”.

What is it

Well you could say at its core in enables applications to not only start faster but also run faster. It has a lot to do with the JIT(Just In Time) compilation process – first let me explain a little about JIT.


Leaving aside AOT compilation for now, The .Net CLR typically uses the JIT compiler to compile the MSIL against the CLR using CIL metadata to machine native code for the target machines architecture.

It performs this process either on startup with full assembly compilation when its loaded or on demand at runtime when a particular method is called – what happens here is basically that when a method is called first time it gets JIT compiled then on subsequent calls the calling code effectively just references the native/Jitted version of the method in memory.

Typically in JIT each method would be JIT compiled once either using aggressive optimization on startup sacrificing startup time but benefitting from steady state runtime performance, or simple optimization at the start sacrificing steady state performance throughout runtime.  There was typically only a single choice.

Back to tiered compilation

With tiered compilation you can JIT compile the same method more than once to  produce a more optimized version depending on its usage, it is hot swapped at runtime automatically for you making the decision for you.

On startup it performs a basic compilation(tier 0) but if the method gets used frequently the method is recompiled on  the background thread to produce a more optimized version(tier 1) for you to improve the runtime performance. This is sometime termed called adaptive optimization.

This in effect produces both fast startup and fast steady state performance.

Another benefit of tiered compilations is faster steady state with applications that use precompiled images shipped with the framework code of .net core, with tiered compilation it can produce more  optimized versions of the code at runtime.


In order to try it out for yourself, there are a few options

1. Assumes you have access to or are building the source code, then it is a trivial change to your csproj file by simply adding the MSBuild property :

like below

2. If the app was previously built and you have no access to the source code but you have access to the appsettings file simply add

to the configProperties.

For example:


  • You can check out official Microsoft article here: Tiered Compilation
  • Check out the GitHub thread indicating performance comparisons of Tiered vs non-tiered apps : GitHub

Happy coding!

My Reverie

MyReverie is a new simple side project I am working on. The idea is to build a goal tracking solution and be able to set target dates and milestone markers against those goals to track progress.

I will routinely push new updates to the GitHub repo : MyReverie

I have a rough idea of some of the features to add which I will list under the Projects Tab.

This is also a way to experiment and learn new technologies as I go, some technologies I will be looking to incorporate are Asp.Net Core, Swagger, Docker,  xUnit.Net and EF Core as well as patterns and approaches such as Microservices and DDD among others.

Let’s see how it goes!

ASP.NET Core Web API with Docker

This post simply demonstrates creating a simple service called ‘AdditionMicroservice’ that adds two numbers provided as query string parameters.

I will add this code to my GitHub account under Getting started with Microservices repo


Docker for Windows

1) Create a new ASP.NET Core Web Application project


Select the Web API Template


Check the Enable Docker Support checkbox

Select Windows as the OS


Open Values Controller file under Controllers


Remove all other methods except first Get method and change to below as below


The change  launchUrl’s from api/value to api/addition in launchsettngs.json file:


Run the app and append to the URL both the x and y parameters along with their set values to view the result: