This Article

Using .NET Cosmos DB SDK with Native AOT and System.Text.Json

Something went wrong.

TLDR, if you want to try it on Native AOT, go here.

If you’ve used Cosmos DB’s SDK for .NET (v3) you’ll know it’s.. well, old. Really old. In fact most of the code is from the private v2 of the SDK from way back when.

That’s not an issue for most applications, drag it in, and bend to its will.

The problem is that this will is:

and of course, the whole point of this post:

Really, it’s no problem. Except .NET 9 is all about Cloud-Native so, things like (in their own words) strong cloud-native fundamentals, runtime performance, and perhaps the most important thing, scaling to multiple instances. Things that the Cosmos DB SDK makes really hard, and becomes a bottleneck on your otherwise brilliant applications.


Because I’m clearly masochistic I thought I’d take a look at just how ingrained Newtonsoft.Json (the primary culprit) for all of this actually is. If Azure.Core can change to be supported natively, why can’t this?

I regret it.

It’s very, very ingrained. In packages that aren’t open.

You see if it was just the Cosmos DB SDK that we can see on Github, that wouldn’t really be an issue. The problem is that it isn’t.

See, this relies on 2 very specific things, that are very much Newtonsoft.Json based:

Long story short when you just have the code for Microsoft.Azure.Cosmos you literally cannot remove the dependency on Newtonsoft.Json. I’m guessing that’s why it still uses it and isn’t likely to change soon.


With all that said, there’s a tonne of crap in the Cosmos SDK that just isn’t required for typical usage in a world-facing application.

So as part of this journey I’ve removed them, specifically:

I haven’t removed things on the control plane, but they definitely won’t work.

In fact I removed a lot of stuff. Stuff that didn’t seem at all needed for what is actually needed which is basically 4 methods:

I wanted to write up what I actually did to get this working but honestly, it was a case of deleting, debugging, deleting, debugging, oh that’s actually used, change it to be STJ, deleting, debugging, etc. etc.

It was horrible, but the end result is something that works (albeit with 3000 warnings at build time) on Native AOT. Yay!

You can see the end result on my GitHub and compile it for yourself if you really want to try.

I don’t recommend it though, it does work, but I can’t offer any support for it at all.

If you do try using it and spot something off, feel free to raise an issue.


More long term, I’d love a truly slim version of the Cosmos DB SDK that supports just the methods you’ll need. Something like azcosmos that we have available in Go, but again without the Control Plane methods.

I can’t see any reason that the control plane stuff is even included in here in the first place. Creating containers and such shouldn’t really be the responsibility of the application at runtime, though I get that a management tool of sorts may want to use them, so make it a separate package?

Written by Rudi Visser

Fancy reading more?

We'll be writing more in the coming weeks. Check back later!