[HN Gopher] Why I'm Building a Database Engine in C#
___________________________________________________________________
Why I'm Building a Database Engine in C#
Author : vyrotek
Score : 53 points
Date : 2026-04-10 15:58 UTC (7 hours ago)
(HTM) web link (nockawa.github.io)
(TXT) w3m dump (nockawa.github.io)
| jaen wrote:
| C# is a great language with almost unlimited power and great
| ergonomics (as the article shows), but the .NET CLR (runtime) is
| a bit overcomplicated with a distinct "Java smell", and packaging
| and distribution is still meh.
|
| If they could make the developer experience similar to Go, it
| would rule the world...
| karmakaze wrote:
| I drank the Go kool-aid, then tried to do some high performance
| things the Go way: didn't work (channels are slow) and I got
| over it. Still think Go is great for web backends and the like
| with production grade stdlib.
|
| _Great post with details, not a I 'm vibe coding..._
| benterix wrote:
| > tried to do some high performance things the Go way: didn't
| work (channels are slow) and I got over it.
|
| What did you choose instead?
| Rohansi wrote:
| > If they could make the developer experience similar to Go, it
| would rule the world...
|
| You can already AOT compile .NET software to an executable to
| run on whichever platform you need, just like Go.
|
| Libraries need to be published into a package manager (NuGet)
| which is more friction than just importing from Git repos but
| it's not that bad.
| hnrodey wrote:
| AOT is not a panacea and comes with some restrictions/trade-
| offs that need understood before depending on it in
| production.
| ziml77 wrote:
| Losing dynamic PGO by using AOT compilation could be a
| detriment to performance in long-running applications,
| right?
| Rohansi wrote:
| You also have the option to do single file deployment where
| it self-extracts the runtime when you run it. It's not as
| nice but it works and maintains full compatibility.
| landl0rd wrote:
| I actually really like the CLR developer experience next to
| java ngl. I reach for C# in lieu of java (less J2EE
| SingletonBeanFactoryManagerInstance slop) but particularly F#
| is pretty nice to use. Haskell has bad tooling, OCaml is
| getting better thanks to JaneStreet (and if OxCaml gets wide
| adoption unboxed types are a big perf win) but if nothing else
| lack of a Rider-esque debugger is just a big time sink.
| tracker1 wrote:
| Also worth mentioning are VeloxDB and RavenDB, both written in
| C#. TBF, I haven't used any of them... but aware they exist.
|
| C# is pretty powerful and capable of lower level usage, such as
| in the examples given... not to mention a pretty nice interop
| with C-style libraries. It looks like the intent here might be a
| custom database engine for service integrations... not
| necessarily a full rdbms in and of itself.
| benterix wrote:
| > JIT warmup is real. The first call to any method pays the
| compilation cost. In a database engine, the first transaction
| after startup shouldn't be 100x slower than the steady state.
|
| Correct me if I'm wrong but isn't it what aot was supposed to
| solve?
| landl0rd wrote:
| AOT is a little fussy in real-world usage particularly for
| things like reflection. You can probably force it to work but
| it may make your code much uglier.
|
| Span<T> is more important for performance TBH JIT warmup isn't
| a huge issue for a long-running process
| CharlieDigital wrote:
| > ...but it may make your code much uglier
|
| Flip side is that if you use more source generation, it may
| end up making the code more terse/"prettier" where it matters
| and avoid the reflection hit.
|
| AI agents seem fairly good at generating source generators so
| there doesn't seem to be a reason to not use them.
| sebazzz wrote:
| With UnsafeAccessor you can often avoid reflection.
| orphea wrote:
| What's fussy about AOT and reflection?
| pjc50 wrote:
| Only a subset of reflection is actually AoT safe, and you
| can run into issues like "the method you wanted to call
| wasn't statically referenced anywhere, so there is no
| compiled implementation of it".
| zigzag312 wrote:
| That's due to trimming which can be also be enabled for
| self-contained deployments using JIT compilation.
| Trimming is mandatory for AOT though. But you can use
| annotations to prevent trimming of specific thing.
|
| AOT doesn't support generating new executable code at
| runtime (Reflection.Emit), like you can do in JIT mode.
| nycdotnet wrote:
| In the section "Hardware-accelerated WAL checksums" he explains
| how the JIT compiles away the hardware support stuff depending
| on the exact capabilities of the system its on. With AOT you
| don't get this - it's way more coarse like x64 vs ARM
| pjc50 wrote:
| Eh, I don't see that as a huge deal because the first thing the
| DB has to do is warm up the disk cache, at least for the
| indexes. Of course the first call is slow.
| DeathArrow wrote:
| I wonder why he didn't use AOT compiling if he's worried about
| JIT warmup.
| topspin wrote:
| It wasn't discussed, so we're left to speculate. If I had to
| guess, I imagine that the .NET JIT has actual benefits: the
| variety of architectures has gotten enormous and JIT is likely
| a performance win after warmup.
| littlecranky67 wrote:
| My guess is because .NET AoT is not yet optimized and mature
| enough as JIT. This is known and is on the agenda of Microsoft
| but it will take time to get there.
| nitwit005 wrote:
| I would be less worried about the GC pause, than the need to
| reserve some memory for garbage collection. Any reduction in
| available memory is going to tend to mean a hit to performance.
| alex7o wrote:
| That seems great, I have seen a few similar dbs written in java
| that say the same thing, that when written correctly you can get
| the perf very close to C, but at that point you are just writing
| C with a different syntax. You don't win on any in the security
| guarantees, so at that point can we just not build everything in
| wasm and then we can interface it from both dotnet and the jvm?
| zerr wrote:
| I'd say modern C++ is high level and ergonomic enough to stop
| considering any language with a GC.
| drfloyd51 wrote:
| Does C++ have build in memory management now?
| achillesheels wrote:
| You do you.
| kerblang wrote:
| Am amused that someone feels compelled to justify writing a db in
| C#. Such conscientiousness!
|
| I'm not sure authors of Cassandra, ElasticSearch, MongoDB (and
| more...?) ever had the slightest twinge of uncertainty about
| whether a managed memory env would cause far more problems than
| it fixed, even with less native tooling than in C#. Java bros
| DGAF
| cyberpunk wrote:
| Mongo's c++ isn't it?
| leosanchez wrote:
| Yes
| gwbas1c wrote:
| Regarding tradeoffs:
|
| I've been working with C# for most of my career, almost 25 years,
| since .Net 1.0. One of the _huge_ things that I love about Rust
| is the lack of a runtime framework. I don 't need to figure out
| how to bundle / ship / install a framework at runtime.
|
| (I also like Cargo better than Nuget, but that's a very
| subjective opinion.)
|
| Which leads to probably the biggest tradeoff:
|
| > Typhon is an embedded...
|
| It's probably hard, (or impossible) to use Typhon outside of the
| dotnet ecosystem. Granted, it's been years (since the 1.0 days)
| since I built a .dll that a native application could pull in,
| there are complications when you "impose" dotnet into an
| application that isn't dotnet. These don't happen when your
| library is 100% native, which you get with C/C++/Rust.
| pjc50 wrote:
| I think the developer is specifically targeting running in game
| engines in Unity, because that's already a C# capable
| environment.
|
| Personally I'm not worried about the micro optimization, I'm
| more a "why are you attempting to compete with sqlite" person.
| WorldMaker wrote:
| > One of the huge things that I love about Rust is the lack of
| a runtime framework. I don't need to figure out how to bundle /
| ship / install a framework at runtime.
|
| Rust has a runtime, it's just tiny and auto-bundled (for now).
| Modern .NET's support for self-contained bundling has gotten
| pretty good. AOT is getting better too, and AOT-ready code
| (switch Reflection for Source Generators as much as possible,
| for instance) can do some very heavy treeshaking of the
| runtime.
|
| Also, yeah native embedding has gotten somewhat easier in
| recent years depending on the style of API you want to present
| to native code. Furthermore both Godot and Unity (differently)
| embed .NET/C# as options in game development. I certainly
| expect Typhon is primarily targeting Godot and/or (eventually)
| Unity (when it finishes switching to coreclr to support more of
| these features) embedding (but maybe also Stride, a fully C#
| game engine).
___________________________________________________________________
(page generated 2026-04-10 23:02 UTC)