Profiling .NET code with MiniProfiler

Related Articles

Sometimes your project does not succeed as you would expect. Bottlenecks occur, and it is difficult to understand where and why.

So, the best thing you need to do is do profile Your code and analyze the execution time to understand which parts are the most influential on the performance of your application.

In this article, we will learn how to use Miniprofiler for a code profile in the .NET 5 API project.

Establishment of the project

For this article, I have created a simple project. This project tells you the average temperature of a place by specifying the country prefix (for example: IT), and the zip code (for example: 10121, for Turin).

There is only one endpoint, /Weather, Which receives CountryCode and PostCode on input, and returns the temperature in Celsius.

To retrieve the data, the app calls two external ones free Services: Chippopotamus To get the current coordinates, and OpenMeteo To get the daily temperature using these coordinates.

Let’s see how to create a profile of the code to see the timings of each action.

Installing MiniProfiler

As usual, we need to install the Nuget package: since we are working on the .NET 5 API project, you can install the MiniProfiler.AspNetCore.Mvc Package, and you’re ready to go.

MiniProfiler provides Tons Of packages that you can use for your code profile: For example, you can create a profile Entity framework, Redis, PostgreSql, And more.

Nuget mini-profiles packages

Once you have installed it, we can add it to our project by updating the Startup status.

In the Configure In the method, you can simply add MiniProfiler to the ASP.NET pipeline:

Then, you will need to set it to ConfigureServices method:

public void ConfigureServices(IServiceCollection services)

    services.AddMiniProfiler(options =>
            options.RouteBasePath = "/profiler";
            options.ColorScheme = StackExchange.Profiling.ColorScheme.Dark;


As might be expected, the king of this method is AddMiniProfiler. This allows you to configure MiniProfiler by defining an object type MiniProfilerOptions. There are many things you can define, that you can see On GitHub.

For this example, I updated the color scheme for dark use, and set the root path of the page that displays the results. The default is Mini-profile resources, So that the results will be available in / mini-profiler-resources / results. With this setting, the result is available in / profiles / results.

Defining traces

It’s time to dump her and move on.

When you launch the app, a MiniProfiler The object is created and shared throughout the project. This object reveals a number of methods. The most used is Step: It allows you to configure some of the code for the profile, by scrolling to a using block.

using (MiniProfiler.Current.Step("Getting lat-lng info"))

    (latitude, longitude) = await _locationService.GetLatLng(countryCode, postalCode);

The section above defines a stage, Gives it a name (“gets lat-lng information”), and lists everything that happens within these lines of code.

You can also use Nested steps Simply by adding a parent stage:

using (MiniProfiler.Current.Step("Get temperature for specified location"))

    using (MiniProfiler.Current.Step("Getting lat-lng info"))
        (latitude, longitude) = await _locationService.GetLatLng(countryCode, postalCode);

    using (MiniProfiler.Current.Step("Getting temperature info"))
        temperature = await _weatherService.GetTemperature(latitude, longitude);

This way you can create a better trace structure and perform better surgeries. Of course, this method does not know what is going on inside GetLatLng method. If there is more stage, This too will be taken into account.

You can also use Embedded stages To track an action and return its value on the same line:

var response = await MiniProfiler.Current.Inline(() => httpClient.GetAsync(fullUrl), "Http call to OpenMeteo");

Inline Monitors the operation and returns the return value from the same method. Note that this works even for asynchronous methods! 🤩

Watching the result

Now that we have everything in place, we can launch our app.

To get better data, you Should Launch the app specifically.

First, Use the RELEASE configuration. You can change it in the project properties, in the title to build Subscription card:

Visual Studio tab for selecting the construction configuration

Then, you need to launch the application Without the debugger connected. You can just press Ctrl + F5, or go to debug Menu and click Start without debugging.

Visual Studio menu to run the application without bugs

Now, launch the application and call the endpoint. Once you get the result, you can navigate to the report page.

Remember the options.RouteBasePath = "/profiler" option? Is the one that indicates the path to this page.

If you turn to / profiles / results, You will see a page similar to this:

MiniProfiler results

In the left column, you can see the hierarchy of the messages we defined in the code. In the right column, you can see the timings for each action.

Assignment of each MiniProfiler call to the related result

I noticed that Show trivial Button in the lower right corner of the report? It shows the actions that took such a small amount of time that can be easily ignored. By clicking this button, you will see many things, like all the actions that the NET engine performs to handle your HTTP requests, like the action filters.

Trivial actions in MiniProfiler

Finally, e Additional columns The button shows, well … more columns! You will see the cumulative timing (action + all its children), and the timing from the beginning of the request.

Additional columns were displayed in MiniProfiler

The mystery of x-miniprofiler-ids

Now, there’s one thing I did not understand in MiniProfiler: the meaning of x-miniprofiler-ids.

This value is an array of identifiers that represent each time we profiled something using MiniProfiler during this session.

You can find this array in HTTP response headers:

x-miniprofiler-ids HTTP header

I have noticed that every time you make a call to this endpoint, it adds some values ​​to this array.

my question is: So what? What can we do with these certificates? Can we use them to filter data, or to see results in certain ways?

If you know how to use these IDs, please send a message in the comments section 👇

If you want to run this project and play with MiniProfiler, I shared this project on GitHub.

🔗 Database ProfilingWithMiniprofiler | GitHub

In this project, I used Zippopotam to retrieve latitude and longitude given location

🔗 Chippopotamus

After I took out the coordinates, I used Open Meteo to get the weather information for this location.

🔗 Open Meteo Documentation | OpenMeteo

Then, of course, I used MiniProfiler to create a profile in my code.

🔗 MiniProfiler Database | GitHub

I have already used MiniProfiler to analyze the performance of an app, and thanks to this library I have been able to improve the response time from 14 seconds (yes, seconds!) To less than 3. I explained all the steps in 2 articles.

🔗 How I Improved Endpoint Performance by 82% – Part 1 | Code4IT

🔗 How I Improved Endpoint Performance by 82% – Part 2 | Code4IT


In this article, we saw how we can create a profile of .NET applications using MiniProfiler.

This NuGet package works for almost any version of .NET, from the expensive .NET Framework to the latest version, .NET 6.

ProposalSet it up so you can turn it off easily. Maybe using some environmental variables. This will give you the option to turn it off when this tracking is no longer required and to speed up the application.

Have you ever used it? Are there alternative tools?

And most importantly, what the hell is that x-mini-profile ID Array ?? 😶

Happy coding!





Please enter your comment!
Please enter your name here

Popular Articles