Share via

Creating a large JSON with Utf8JsonWriter is very slow in a native AOT library

Don Z 20 Reputation points
2026-06-20T10:40:28.79+00:00

Hello,

In a personal project I'm creating a fairly large JSON document, 150MB, using Utf8JsonWriter in C#. It is reasonably fast when compiled to managed, NET 10, code - it finishes in 6 seconds. However, when published to native AOT, the same process takes 21 seconds, so ~3.5 times slower. I would have expected it to be the other way around, and the native version to be significantly faster.

Is there a reason why Utf8JsonWriter is performing worse in native AOT build, as compared to managed NET10? Thank you.

Developer technologies | .NET | .NET Runtime

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 84,086 Reputation points
    2026-06-20T12:55:36.34+00:00

    Be sure you are not using reflection to get the values to write. AOT does not support dynamic code, so if using reflection, you should use the precompiled options.

    Was this answer helpful?

    1 person found this answer helpful.

  2. Tom Tran (WICLOUD CORPORATION) 5,050 Reputation points Microsoft External Staff Moderator
    2026-06-22T06:49:20.3933333+00:00

    Hi @Don Z ,

    From what I found, I couldn’t find a confirmed Utf8JsonWriter-specific issue in Native AOT.

    Native AOT can improve startup time, app size, and memory usage, but it does not always make long-running code faster. For this kind of workload, the managed JIT may still perform better because it can optimize hot code while the application is running. Native AOT code is fixed at publish time. Microsoft documents the AOT speed/size trade-off here: Optimize AOT deployments.

    I also found this article showing similar benchmark behavior: Native AOT can win when startup matters, but managed code can match or beat it after startup.

    Disclaimer: This is a non-Microsoft article. I found it useful for comparison, but please review any ads or downloads on the site carefully before installing anything.

    For your case, I would first try publishing the AOT version with speed optimization and compare again:

    <PropertyGroup>
      <PublishAot>true</PublishAot>
      <OptimizationPreference>Speed</OptimizationPreference>
    </PropertyGroup>
    

    If the gap is still large, I would compare the GC settings next. Writing a large JSON document can create a lot of allocation and buffer pressure, so it is worth checking whether both builds are using comparable GC behavior. For example, you can test with Server GC enabled:

    <PropertyGroup>
      <ServerGarbageCollection>true</ServerGarbageCollection>
    </PropertyGroup>
    

    If the AOT build is still around 3.5x slower after those checks, a small reproducible benchmark would be the best next step to narrow this down.

    Hope this helps. If the information I provided was helpful to you, I would greatly appreciate it if you could follow the instructions here

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.