Skip to content
managedcodePublic

About

The AI-native database. One database for AI agents. Documents, typed tables, graphs, vectors/search, blobs, queues, events and time series in one replicated .NET cluster. Everything links to everything else, and agents reach all of it through SQL, a built-in MCP server and a typed .NET SDK.

Topics

Resources

Stars

1 star

Watchers

2 watching

Forks

Repository files navigation

KeyLoad, the AI-native database for AI agents

KeyLoad

The AI-native database. One database for AI agents.
Your agent's context, relationships and next action. Together.
SQL · Native MCP · .NET SDK

Build and Tests Elastic License 2.0 .NET 10 Development preview

Website · Quick start · Capabilities · Docs · Status


Why an AI-native database?

At Managed Code, we've spent years building agents. Different projects. Same story: the agent always needs more than the database we started with.

You start with vectors. Great, the agent can find similar things. But it also needs real records. Add SQL. Then hybrid search. Still missing relationships? Add a graph. Now it needs to remember what happened: events. Read a PDF? Files. Do something later? Queues. Track what changes over time? Time series.

Every requirement makes sense. Put them together, and suddenly you're running a stack of databases just to build one agent. Different clients, permissions, backups and sync jobs. A lot of plumbing before the interesting work even starts.

Agents shouldn't need a dozen databases.

We came to a simple conclusion: we need an AI-native database that keeps the agent's context, relationships and work together. With MCP built in, so the agent can actually use it.

Meet KeyLoad. One database for AI agents.

One agent connected to one database, with documents, tables, graphs, vectors, files, queues, events and time series around the same core

Documents, typed tables, graphs, vectors/search, blobs, queues, events and time series belong to the same database. They connect through canonical entity references, so a row can be part of a graph, an event can point to a document, and a queued task can carry the context it needs.

SQL is the familiar shared language. The built-in MCP server and typed .NET SDK reach the same authorized operations. The full product is still being built; the status below shows what's accepted and what remains.

The idea Why it matters
Keep context together Search, relationships, files and history connect to the same entities
Keep work next to the data A document, event, graph edge and queued task in one partition commit together
Give agents a native way in MCP discovery finds the relevant tools; SQL and the SDK use the same operations
Keep permissions in the database Persisted keys and row/field policies apply across every caller

Why we think this is the future

A support agent doesn't ask for a vector database. It needs the ticket, the customer, similar cases, the attached file and a way to schedule the next action. Those things belong together.

That's what we're building: one place for context, one place for the work that follows. Same-partition writes already commit atomically. Leased receives, blob uploads and cross-partition work are separate steps today. Try the preview or bring us your agent workload.

What you can build

You want to… KeyLoad gives you
Give an agent long-term memory and retrieval (RAG) Documents, files and embeddings in one place, with vector, full-text and hybrid search
Build a knowledge graph Relationships between any entities, including typed rows, and graph traversal
Run reliable agent workflows Queues with scheduling, leases, retries and dead letters, stored next to the data they change
Make event-driven apps Ordered event history, durable subscriptions, change feeds and projections
Analyze time series Timestamped samples, range reads, aggregates, time windows and retention
Store files for agents Chunked uploads and partial reads of large blobs

Project status

Development preview. Production qualification is still open.

flowchart LR
    Build["Implement<br/>in progress"] --> Check["Qualify<br/>in progress"] --> Release["Release<br/>gated"]
    classDef active fill:#f7eef3,stroke:#97718d,color:#171717
    classDef gated fill:#f2f2f2,stroke:#777,color:#171717
    class Build,Check active
    class Release gated
Loading

Accepted = criteria passed for a recorded source. In source = implemented, with qualification open. Later changes require fresh checks.

Current focus: removing the self-written cluster code so that Orleans alone runs the cluster (ADR-136).

.NET profiling with dotnet-diagnostics-mcp guides measured bottleneck repairs.

Workstream What it does and why State Remaining work
Records & indexes CRUD and revision checks keep records consistent ✓ Accepted Recovery and fault gates
Backup & restore Recover a saved local database ✓ Local scope Cluster restore drills
Atomic batches Commit related writes together; retry without duplicates ✓ Accepted Cross-partition composition
Graphs Store relationships and traverse agent knowledge ✓ Accepted Cross-partition graphs
Time series Samples, ranges and aggregates track history ✓ Accepted Chunk and scale checks
Search Exact vectors, hybrid ranking and Explain retrieve context ✓ Accepted ANN, rebuilds and freshness
SQL & tables Selected T-SQL SELECT, canonical EXEC and closed model INSERT lower to shared typed plans ◐ In source Full SQL, foreign keys and client protocol
Queues & events Leases, history and queue ↔ graph flows drive agent work ◐ In source Failure, security and recovery checks
SDK & MCP SDK, tool discovery, CLI and admin connect callers ◐ In source Gateway and official MCP cluster checks
Authorization ASP.NET Core authentication and persisted row/field policies protect context ◐ In source Adversarial and revocation checks
Orleans cluster Orleans runs the cluster and copies data to the configured number of replicas ◐ In source Remove self-written cluster code; fault and restart checks
RAM & SIMD Bounded caches and CPU vectorization target lower memory/latency ◐ In progress Comparable Linux measurements
Production Qualified database and operator guidance ○ Gated Full SIMD-enabled unit, recovery, cluster, coverage, performance, endurance and power-loss gates

Full product functional coverage remains unqualified. Load tests and benchmarks contribute no coverage. Public performance figures require original GitHub measurements; process-kill tests do not prove power-loss durability.

Complete Linux cluster, recovery, fault and coverage qualification remains open; see the current status.

Status · SQL conformance · Coverage · Benchmark methodology · Published benchmarks

One database, connected models

Capability matrix

Model Operations in source Atomic write scope
Documents CRUD, revision checks, indexed and live queries Put, patch, delete
Typed tables Schemas, primary keys, unique constraints and indexed reads Row mutations
Graphs Edges and bounded traversal Add/remove edges
Vectors & search Exact vector, full-text and hybrid retrieval Store vectors with documents
Queues & topics Scheduling, leases, ACK, retries, dead letters and peek Enqueue/publish
Events Append, replay and durable subscriptions Append with expected revision
Time series Ranges, aggregates, windows and retention Append samples
Files & blobs Chunked uploads and byte-range reads Separate upload/publication
Change feeds Resumable feeds and projections Record document changes

Atomic batches share one partition. T-SQL SELECT reads supported documents, typed rows and model views; EXEC reaches the shared operation catalog. MCP discovers those operations on demand. SQL syntax · API and tool catalog.

Models that work together

Flow What one request does
Queue to knowledge graph (QueueToGraph) Reads ready messages, resolves linked entities and writes knowledge-graph relationships
Graph to queued actions (GraphToQueueMutation) Follows relationships and can enqueue actions for linked entities
flowchart LR
    Q[["Queue: inbox"]] -->|"QueueToGraph"| E["Linked entities<br/>documents and rows"]
    E --> G(("Knowledge graph"))
    G -->|"GraphToQueueMutation"| A[["Queue: actions"]]
Loading

The current composition API uses .NET CommitAsync, SQL EXEC keyload_documents_commit @arguments or the official MCP server.

Boundary Current contract
Atomicity The same atomic partition and transaction domain (PartitionRef); the batch succeeds or rolls back together
Queue reads Composition does not lease or ACK messages
Files Blobs remain part of the same database, with separate upload and publication operations
Preview limits Full declarative SQL, the native SQL-client protocol and cross-partition composition are still in development; production guarantees remain under qualification

Details: composition guide · transaction contract.

How it works

flowchart LR
    Callers["SDK · MCP · SQL · HTTP"] --> Request["One Orleans grain<br/>per connection"]
    Request --> Partition["Partition grains"]
    Partition --> N1[("Node 1<br/>ZoneTree")]
    Partition --> N2[("Node 2<br/>ZoneTree")]
    Partition --> N3[("Node 3<br/>ZoneTree")]
Loading

Each actual connection reuses one Orleans grain and admits bounded parallel operations and commands. Every operation has its own signed identity, fresh persisted authorization, cancellation and stream cleanup; completed requests are not retained. Disconnect or idle expiry closes admission, joins the original work and requests native deactivation.

Orleans does all of the clustering: membership, discovery, placement, activation migration, communication between silos and scaling. Every silo has its own ZoneTree that owns its files; database grains reach it on their own node or on other nodes through Orleans calls, and a write is copied to the configured number of replicas and acknowledged only after every configured copy persists it. Receipts report the actual persisted copy count separately from durability. Storage files never move with grain activations. Background work (queues, ANN, time series) runs in Orleans stateless workers that buffer events and flush them on a timer. See ADR-136 and the architecture map.

Why .NET, Orleans and ZoneTree

Foundation Why we use it
.NET 10 C# end to end, pooled buffers, Span<T> and native SIMD intrinsics; speedups need measurements
Orleans The whole cluster: membership, routing, placement, migration, communication, data copies through grain calls and generated binary serialization
ZoneTree Embedded ordered storage and a write-ahead log for every model; data stays on its node
ZoneTree.FullTextSearch Native full-text indexing on the same storage foundation
Aspire Owns Docker cluster startup, readiness and cleanup

Orleans runs the cluster; ZoneTree keeps each node's data in place.

Quick start

You need: the .NET SDK version pinned in global.json, and Docker.

1. Build the solution

dotnet restore KeyLoad.slnx
dotnet build KeyLoad.slnx --no-restore --configuration Release -warnaserror

2. Start KeyLoad through Aspire

aspire start --apphost build/KeyLoad.AppHost/KeyLoad.AppHost.csproj --no-build --non-interactive

For ordinary local development Aspire runs dotnet publish /t:PublishContainer and owns all server containers and the native Orleans membership emulator. No manually started registry or server containers are required. An explicitly configured KeyLoad__ContainerImages__Server still selects the pinned image; qualification and benchmark profiles retain their separate image/provenance requirements.

3. Choose the number of silos and copies

The default is three silos and three copies. For five Orleans silos with three copies of the data:

KeyLoad__SiloCount=5 KeyLoad__ReplicaCount=3 aspire start --apphost build/KeyLoad.AppHost/KeyLoad.AppHost.csproj --no-build --non-interactive

SiloCount is the number of Orleans silos. ReplicaCount is the number of copies of the data and must be between one and SiloCount. A write requires every configured copy: one of one, both of two, all three of three, or all five of five. A missing required copy blocks successful writes; available owners can still serve earlier committed data after native Orleans membership settles.

Both values are read at startup; there is no live resizing or data movement. Node data and private development credentials remain in data/cluster/. HTTP ports start at 5101; keep the data directory between restarts. Stop owned resources with aspire stop --non-interactive.

4. Look around

dotnet run --project src/KeyLoad.Cli --configuration Release --no-build -- status http://localhost:5101 data/cluster/local-profile.json

Your local admin API key is the AdminKey value in data/cluster/local-profile.json. Export it as KEYLOAD_API_KEY for the examples below.

Use it

From .NET

The client SDK gives you typed database operations. This creates a collection, writes an order and reads it back:

using KeyLoad;
using KeyLoad.Client;

var apiKey = Environment.GetEnvironmentVariable("KEYLOAD_API_KEY")
    ?? throw new InvalidOperationException("Set KEYLOAD_API_KEY.");
using var http = new HttpClient { BaseAddress = new Uri("http://localhost:5101") };
var client = new KeyLoadClient(http, apiKey);

// tenant, database, transaction domain, partition key
var partition = new PartitionRef("acme", "shop", "orders", "customer-42");

var collection = await client.ConfigureResourceAsync(Guid.NewGuid(), new("acme", "shop",
    new ResourceDefinition("orders", ResourceKind.Collection, "orders")));
collection.ThrowIfFail();

var commandId = Guid.NewGuid(); // Reuse this ID if you retry the same write.
var result = await client.CommitAsync(new CommandRequest(commandId, partition,
[
    new PutDocument("orders", "order-1", "{\"status\":\"new\"}", ExpectedRevision: 0)
]));
result.ThrowIfFail();

var order = await client.GetAsync(new EntityRef(partition, "orders", "order-1"));
order.ThrowIfFail();

With SQL

Use the selected T-SQL syntax for supported reads and canonical operations through Microsoft ScriptDOM. Successful parsing does not grant execution of an unsupported AST family:

using System.Text.Json;

var rows = await client.ExecuteSqlAsync(new SqlOperationRequest(partition,
    "SELECT TOP (20) * FROM orders WHERE status = @status",
    new() { ["status"] = JsonSerializer.SerializeToElement("new") },
    AllowFullScan: true));
rows.ThrowIfFail();
Console.WriteLine(rows.Value);

Source-integrated selected-language examples (current Linux operation qualification remains open):

SELECT * FROM orders WHERE number BETWEEN 1 AND 9 ORDER BY id
SELECT * FROM QUEUE_MESSAGES('jobs')
SELECT e.eventType FROM EVENTS('events', 'stream-a', 3) AS e
EXEC keyload_documents_commit @arguments

Model views (QUEUE_MESSAGES, EVENTS) and unindexed filters require AllowFullScan: true, and model views don't support cursors. Closed same-partition INNER JOIN and queue/graph INSERT profiles are in source. Complete T-SQL execution, foreign keys and native-client qualification remain open. The bounded PostgreSQL wire/Npgsql session is a separate transport contract; it does not promise PostgreSQL grammar or SQL Server TDS compatibility. The query guide lists the supported syntax, and the compatibility inventory tracks the rest.

From an AI agent (MCP)

Every node serves MCP at /mcp. Its compact catalog offers gateway_tools_search, gateway_tools_route and gateway_tool_invoke; tools are discovered on demand. Connect with an API key, for example in Claude Code's .mcp.json:

{
  "mcpServers": {
    "keyload": {
      "type": "http",
      "url": "http://localhost:5101/mcp",
      "headers": { "Authorization": "Bearer ${KEYLOAD_API_KEY}" }
    }
  }
}
Step Agent workflow
Learn Read keyload://guides/agent-quickstart or request the no-argument keyload_agent_quickstart prompt
Discover Call gateway_tools_search with { "query": "keyload_query_capabilities", "maxResults": 1 }
Inspect Use the returned exact schema and effect hints
Invoke Call gateway_tool_invoke with { "toolId": "keyload_query_capabilities", "arguments": {} }

Every invocation checks current persisted permissions. Retry uncertain writes with the same command identity and payload. Details: API guide · discovery and qualification contract.

FAQ

Question Answer
Is this a vector database? Vectors share a database with documents, graphs, queues and files. Exact search is available; ANN is in progress.
Can it hold agent memory? Yes: linked documents, embeddings, files, graphs and history are the main use case.
Does it replace a stack of databases? That's the goal for agent workloads. Check the preview limits before moving data.
How do agents connect? MCP at /mcp, with an API key and on-demand tool discovery.
What about Python or TypeScript? Use MCP or /v1/ HTTP. The typed SDK is .NET.
Can I use it commercially? Elastic License 2.0 permits application use. Offering a substantial set of KeyLoad features as a hosted or managed service requires ManagedCode authorization. KeyLoad is source available.
Production ready? Not yet: endurance, fault and power-loss qualification remain open.

Repository map

Source map and development commands

Feature code uses Features/<SliceName>/<Responsibility>/ across the solution.

Path What's inside
src/KeyLoad.Server The database server: HTTP API, MCP server and admin console
src/KeyLoad.Client The .NET SDK
src/KeyLoad.Cli Command-line tool for operators and workers
build/KeyLoad.AppHost Aspire host for the local cluster and every test suite
src/KeyLoad.Abstractions Shared public contracts
src/KeyLoad.Core, Query, Clustering, Replication, Storage.ZoneTree, Diagnostics Database engine, SQL, Orleans grains, replica calls, storage and phase telemetry
tests/ Unit, crash-recovery, three-node and website tests (TUnit)
benchmarks/ Comparisons with other databases, plus microbenchmarks
site/ Source for keyload.cloud
docs/ Architecture, feature specifications and design decisions

Contributing

Start with the architecture map, the feature specs and repository rules. After building, run a functional suite (unit, recovery, cluster, analyzers or site):

node scripts/Features/TestInfrastructure/run-tests.mjs --KeyLoadTests:Suite=unit
dotnet format KeyLoad.slnx --verify-no-changes --no-restore

Native TUnit fixtures own Aspire startup and cleanup; the cluster suite uses real .NET and official MCP clients against the Aspire-owned Docker cluster (three silos by default). Benchmark builds, checks and measurements run exclusively in GitHub's Benchmarks workflow.

License

KeyLoad is licensed under the Elastic License 2.0. Use it in your own applications; contact ManagedCode for authorization to offer it as a hosted or managed database service to third parties. Dependency licenses remain with their respective owners.

Credits

KeyLoad is built by Managed Code. We get to build it because other people built great tools first. Thank you to their authors and contributors.

A special thanks to ZoneTree and ZoneTree.FullTextSearch for the storage and text-index foundation, Orleans for the cluster runtime, and the MCP C# SDK team for the native agent connection.

Project How KeyLoad uses it
.NET and ASP.NET Core Server, client SDK and HTTP hosting
Orleans Distributed request execution, cluster routing and binary serialization
ZoneTree Persistent ordered storage for every database model
ZoneTree.FullTextSearch Full-text search index
MCP C# SDK Built-in MCP server and real MCP clients in tests
ManagedCode.Communication Typed operation results and ASP.NET Core/Orleans integration
ManagedCode.Storage File-system storage and backup transfer support
ManagedCode.TimeSeries Time-series aggregation
ManagedCode.Orleans.Graph Grain call relationship policies
ManagedCode.Orleans.Identity Native Orleans request identity context
ManagedCode.MCPGateway Agent authentication and on-demand tool discovery
ManagedCode.MarkdownLd.Kb Knowledge-graph search over tool metadata
Cartograph Segmented backup archives and catalogs
OpenTelemetry .NET Logs, metrics and traces
Development & presentation Contribution
Aspire · TUnit Docker orchestration and real operation tests
Roslyn · BenchmarkDotNet Repository analyzers and microbenchmarks
Three.js Website cluster illustration

The comparison suite uses free community editions and real native clients:

Workload family Comparison projects Client projects
Records & SQL PostgreSQL, MongoDB, Redis Npgsql, MongoDB .NET Driver, StackExchange.Redis
Vectors & text pgvector, Qdrant, OpenSearch —
Queues & events RabbitMQ, KurrentDB RabbitMQ .NET Client, KurrentDB .NET Client
Graphs & connected models Neo4j, SurrealDB, HelixDB —
Time series TimescaleDB —

Active scale: 100,000 and 1,000,000 records, at native 1 or 3 nodes where supported. New adapters remain under qualification. The vector comparison contract defines accuracy, latency, index cost and memory checks; only qualified original GitHub results become public figures.


Developed by Managed Code

About

The AI-native database. One database for AI agents. Documents, typed tables, graphs, vectors/search, blobs, queues, events and time series in one replicated .NET cluster. Everything links to everything else, and agents reach all of it through SQL, a built-in MCP server and a typed .NET SDK.

Topics

Resources

Stars

1 star

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages