🐍 Typhon 🐍

GitHub

Overview: An Embedded ACID Database Engine With ECS Architecture

Typhon is an embedded database engine that takes the architectural patterns that make game engines fast β€” Entity-Component-System, data-oriented design, cache-line awareness β€” and applies them to build an ACID database from first principles. It targets 1–2 microsecond transaction commits in C#/.NET.

The thesis: game engines and databases are solving the same fundamental problem (managing structured data with performance constraints) but evolved completely different solutions. Typhon combines both β€” ECS storage with MVCC transactions, SIMD-optimized data access with WAL durability.

Status: Early alpha β€” the engine is functional with working MVCC, WAL, crash recovery, B+Tree indexes, and query engine. Not yet available for external use.

Core Features

Component-Based Architecture

Data is organized into typed, blittable components grouped by archetypes β€” the ECS model, applied to a database. Components must be unmanaged structs with explicit layout, enabling zero-copy reads and SIMD-friendly memory access.

[Component("Game.PlayerPosition", 1)]
[StructLayout(LayoutKind.Sequential)]
public struct PlayerPosition
{
    [Field] public float X;
    [Field] public float Y;
    [Field] public float Z;
}

[Archetype(100)]
class PlayerArch : Archetype<PlayerArch>
{
    public static readonly Comp<PlayerPosition> Position = Register<PlayerPosition>();
}

MVCC Transaction System

All operations go through a three-tier API: DatabaseEngine (setup) β†’ UnitOfWork (durability boundary) β†’ Transaction (MVCC operations).

Deadlock-Free by Construction

Typhon makes deadlocks structurally impossible through a three-pillar design:

  1. MVCC eliminates inter-transaction locks β€” readers see snapshots, writers create revisions, no data-level locks
  2. Optimistic Lock Coupling β€” B+Tree traversal without holding latches (version-counter validation instead)
  3. No cross-table latch holding β€” operations on different component tables are independent

No deadlock detection, no timeouts, no victim selection β€” deadlocks cannot form. The cost is optimistic retries on conflict, which is a local cost vs the global cost of cycle detection.

Three Storage Modes

Choose the right trade-off per component:

High-Performance Storage Engine

Indexing

B+Tree indexes with SIMD-accelerated search, automatically maintained on component fields:

[Component("Game.Enemy", 1, StorageMode = StorageMode.SingleVersion)]
[StructLayout(LayoutKind.Sequential)]
public struct Enemy
{
    [Field] [Index(AllowMultiple = true)]
    public int ZoneId;

    [Field]
    public int Health;

    [Index(AllowMultiple = true, OnParentDelete = CascadeAction.Delete)]
    public EntityLink<PlayerArch> Owner;
}

B+Tree nodes are 256 bytes (four cache lines), with Vector256.LessThan for parallel key comparison. Measured: 267 ns per lookup, 3.7M ops/sec.

Compile-Time Safety via Roslyn Analyzers

A custom analyzer suite (TYPHON001–007) enforces domain-specific safety rules as compiler errors:

Use Cases

Typhon is designed for workloads that need both real-time performance and transactional safety:

Technical Foundation

Built entirely in C# on .NET 10, using:

Why?

Initially I wanted to β€œmake a database engine for MMOs, something fast, reliable and scalable” (in that order).

The deeper insight came later: game engines (ECS) and databases solve the same fundamental problem β€” managing structured data under performance constraints β€” but evolved completely different solutions. ECS optimized for throughput on bulk operations. Databases optimized for flexibility and isolation. Typhon argues you can have both.

Fast

In the realm of the microsecond. A full CRUD lifecycle (spawn, read, update, destroy, commit with MVCC) measures at 1.2 Β΅s. The bottleneck is memory access patterns, not the language.

More suitable

Adopting ECS principals makes the data model natural for game developers β€” entities gain/lose components at runtime, no ALTER TABLE, no migration scripts. Components are blittable structs with zero-copy access.

Reliable, meaning Durable (or not…)

Atomic, transaction-based and durable operations. Through a design decision, the user can choose durability per component (Versioned/SingleVersion/Transient) and per transaction (Deferred/GroupCommit/Immediate override).

History

This project went through many things: