
This article was written in 2021. Versions, tools and recommendations may have changed since then. Newer posts are collected under .NET.
While analyzing nearly 120 million requests, we noticed that one thing was dragging down our performance: parsing user agents for detecting bots and search engines.
For this task, we used the UA Parser library, which is quite widely used. Unfortunately, it is quite outdated, generates a lot of allocations and lowers our performance in its implementation.
1| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
2|-------------------- |-------------|-----------|-----------|---------|--------|-------|-----------|
3| 'UA Parser' | 3,238.59 us | 27.435 us | 25.663 us | 7.8125 | - | - | 168225 B |Since the alternatives are not really better, we decided to build our own parser: mycsharp/HttpUserAgentParser
During implementation, we paid special attention to the fact that this component could be part of a hot path of the application and therefore invested a lot in optimized performance. And our implementation lives up to this expectation in comparison!
1| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
2|-------------------- |-------------|-----------|-----------|---------|--------|-------|-----------|
3| 'UA Parser' | 3,238.59 us | 27.435 us | 25.663 us | 7.8125 | - | - | 168225 B |
4| UserAgentService | 391.11 us | 5.126 us | 4.795 us | 35.1563 | 3.4180 | - | 589664 B |
5| HttpUserAgentParser | 67.07 us | 0.740 us | 0.693 us | - | - | - | 848 B |As can be seen, we generate minimal allocations, but as the only implementation no GenX load at all!
Besides the implementation itself, we also created a caching component that checks respective browser agent strings for equality and thus very widely used agents only need to be parsed once.
We also provide a Dependency Injection registration for ASP.NET Core directly.
Related articles

- 16 min read
Production Rate Limiting in ASP.NET Core
Most ASP.NET Core rate-limiting examples stop after registering a fixed window. That is enough to demonstrate the middleware, but it is not …

- 11 min read
The Big Decimal Bugfix with .NET 11
For more than two decades, (decimal)1.23 returned 1.23m. It looked correct, it passed every test and it was a polite lie.

- 10 min read
Distroless, Chiseled or Alpine: Choosing a .NET Base Image
Distroless, Chiseled and Alpine are often compared as three equivalent Linux distributions. They are not. Alpine is a distribution built …
Let's Work Together
Looking for an experienced Platform Architect or Engineer for your next project? Whether it's cloud migration, platform modernization or building new solutions from scratch - I'm here to help you succeed.
