The AI-native database. One database for AI agents.
Your agent's context, relationships and next action. Together.
SQL · Native MCP · .NET SDK
Website · Quick start · Capabilities · Docs · Status
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.
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 |
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.
| 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 |
Development preview. Production qualification is still open.
| Plan tasks | Accepted | In progress |
|---|---|---|
| 105 | 20 | 85 |
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
Accepted = original task criteria passed for a recorded source. In source = implemented, with qualification open. Later changes require fresh checks.
KL-105 adds .NET profiling with dotnet-diagnostics-mcp, measured bottleneck repairs and matched verification; its acceptance remains open.
Оновлена normal-пара функціональних перевірок прийнята локально на frozen cohort afee6834: R600 ONE виконав 10 302 успішні операції (SDK 5315, MCP 4987) за 442,619 с; після нього R602 RF3 — 10 306 (SDK 5317, MCP 4989) за 1176,958 с. Обидва запуски мають 41 хвилю, вісім workload-користувачів, одного оператора та три ресурси на модель. Використано справжні SDK, official MCP SDK і вибрані T-SQL операції; source, DLL та image inputs збігаються. Прийняття спирається на terminal PASS, original TRX, joined shutdown і перевірки звільнення ресурсів. Це локальний development proof; ONE не має replica fault tolerance. Час виконання не є benchmark або performance claim. Три persisted time-series sets і node operational analytics не означають три користувацькі analytics stores.
The earlier resource-lifetime and analytics-root repair checkpoint passed its strict solution build, all 45 selected native whole-operation tests, all three selected process/native recovery tests, and the actual SDK/MCP RF3 authorization scenario through all-three-node same-root cold restart. These are local development proofs. Earlier scenarios and failures retain their original source scope; whole-product and Linux qualification remain open.
Поточний foundation-пакет виправляє ONE placement DI, межі resource inventory, графові effect bindings, replay-очікування та heartbeat під час довгого command preparation. R751 раніше зібрав Unit/Integration/Recovery з реальними залежностями без warnings/errors. Новіший R762 strict Unit + actual dependencies: 0 warnings / 0 errors за 116,46 с належить записаному diagnostic snapshot; у R759 product, Integration і Recovery зібралися, але весь command завершився двома Unit analyzer errors, які потім виправлено. Чотири тимчасові capture-зміни вже видалені; fresh final-source build, full solution та Linux qualification залишаються OPEN.
Оригінальний попередній R739: 154/216 PASS, 62 FAIL, 0 SKIP збережений. R756: 56/57 related Unit rows і 6/6 privacy/closed-cause rows пройшли; після виправлення одного composition setup R761: 12/12 PASS за 8,37 с у повному відповідному класі. R763: 21/21 related process-recovery PASS за 56,15 с на поточному записаному snapshot. R760 native connection control досі FAIL до business execution за 17,13 с: первинна відмова виникає в native graph transition check; точна причина в KeyLoad registration або owning dependency ще досліджується. Приватні exception messages/stacks не публікуються, тимчасового capture-коду в checkpoint немає. Ці focused результати не закривають full Unit/Recovery, public ONE/RF3/cold/files чи 105-task acceptance. Raw coverage 27,30% належить старому невдалому focused-прогону лише 7 production modules і не є поточним повним покриттям.
Окремий benchmark-пакет переходить до 22 shared sessions (11 баз × 1/3 вузли), починаючи із семи document-сценаріїв та вимірюваного початкового завантаження 1 млн записів без warmup/reseed. Новий пакет із 47 файлів видаляє obsolete standalone intensive/report/progress paths, зберігає справжні native algorithms/adapters та змістовні ledger/receipt/failure перевірки, і виправляє збереження original operation/retention/disposal failures. Ще 8 ComparisonTests-файлів виправляють три actual Linux compiler diagnostics у native capture disposal та responsibility split без підняття caps. Benchmark build/tests/measurements виконуються лише в Linux CI; повна model/client matrix та benchmark qualification залишаються OPEN.
The separate all-model cold-reopen pair also passed on 57cea624: one node in 104.61 seconds, then RF3 in 118.73 seconds. After all original nodes restarted through Aspire, both clients replayed the original SQL, mixed-model and blob-stage commands with complete receipt/value checks, then verified persisted grant revocation, repair and a healthy write. These tests keep the same physical roots and credentials. They use three cold-only identities and do not claim the normal gate's eight-user concurrency.
Поточний пакет зберігає ownership native команд, streams і result retention до оригінальних Prepare/cleanup/settlement бар’єрів; його повна strict SDK збірка пройшла, а runtime ще відкритий. Додано Aspire-сценарій фізично окремих файлів вузлів, захист живої папки від конкурентного відкриття, CI gate та 16 негативних profile-перевірок із healthy native model. Успішний одночасний доступ усіх silo до тих самих ZoneTree-файлів залишається OPEN: pinned ZoneTree і поточний exclusive owner не мають підтвердженого контракту цього режиму. Відмова через lock не закриває цей критерій; builder model не є виконаним Docker RF3 сценарієм.
R638 інтегрував у canonical source DROP TABLE/resource recreate, користувацькі AnalyticsStore, lifetime-bound зв’язки моделей і розширені normal/cold SDK/MCP/T-SQL сценарії. Їхня спільна збірка пройшла R697; виконання залишається OPEN; старі normal/cold PASS не кваліфікують нові тіла сценаріїв. Локальні normal-перевірки не завершують unified SQL, Linux fault/endurance/security/performance/release або production qualification. Початковий task acceptance незмінний: 105 tasks / 20 accepted / 85 in progress; діє foundation-first plan.
| 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 | RF3 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 RF3 checks |
| Authorization | ASP.NET Core authentication and persisted row/field policies protect context | ◐ In source | Adversarial and revocation checks |
| RF3 & Orleans | Three replicas, follower reads and partition movement | ◐ In source | Fault, restart and runtime 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, RF3, coverage, performance, endurance and power-loss gates |
KL‑029 now satisfies its original projection rebuild, checkpoint recovery and stale-revision criteria on Linux at 7e94024c: 58 Unit + 18 real process recovery + 9 Aspire RF3 cases passed, zero failed or skipped. The original acceptance audit binds source, native UIDs, TRX, DLL/PDB, images and joined processes. Current shared changes still require fresh complete qualification.
Full product functional coverage remains unqualified. The last measured 45-case native whole-operation Unit cohort passed and measured 11.16% production lines /7.79% branches. This focused selection does not establish full-product coverage or a trend against different selections. Load tests and benchmarks contribute no coverage. Public performance figures require original GitHub measurements; process-kill tests do not prove power-loss durability.
Implementation is progressing across SQL and the connected data models. Complete Linux cluster, recovery, fault and coverage qualification remains open; see the canonical implementation status.
Task tracker · SQL conformance · Coverage · Benchmark methodology · Published benchmarks
| 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.
| 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"]]
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.
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")]
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.
Connection execution under ADR-125 passed eight local native flows and five real SDK/official MCP Aspire Docker RF3 flows. Complete Linux fault, endurance and performance qualification remains open. This transport ownership does not deliver native SQL session compatibility. Partition grains route to node-local storage owners; moving a grain does not move its storage handles. Writes require a persisted majority of the three replicas. See the architecture map and grain lifetime contract.
| Foundation | Why we use it |
|---|---|
| .NET 10 | C# end to end, pooled buffers, Span<T> and native SIMD intrinsics; speedups need measurements |
| Orleans | Request isolation, membership, routing and generated binary serialization; experimental directory/repartitioning remain under qualification |
| 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 moves the routing; ZoneTree keeps the data in place.
You need: the .NET SDK version pinned in global.json, and Docker.
1. Build the solution
dotnet restore KeyLoad.slnxdotnet build KeyLoad.slnx --no-restore --configuration Release2. Build the server image
The cluster runs the server image pinned by its digest, so build it from source and push it to a local registry:
docker run -d --name keyload-registry -p 5050:5000 registry:3docker build -t localhost:5050/keyload/server:dev . && docker push localhost:5050/keyload/server:devexport KeyLoad__ContainerImages__Server="localhost:5050/keyload/server:dev@$(docker inspect --format '{{index .RepoDigests 0}}' localhost:5050/keyload/server:dev | cut -d@ -f2)"3. Start the three-node cluster
dotnet run --project src/KeyLoad.AppHost --configuration Release --no-buildAspire starts three nodes at http://localhost:5101, :5102 and :5103. Node data and your local development credentials are stored in data/cluster/, which git ignores. Keep that folder between restarts.
4. Look around
- Open the admin console.
- Or check the cluster from the CLI:
dotnet run --project src/KeyLoad.Cli --configuration Release --no-build -- status http://localhost:5101 data/cluster/local-profile.jsonYour local admin API key is the AdminKey value in data/cluster/local-profile.json. Export it as KEYLOAD_API_KEY for the examples below.
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();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 @argumentsModel 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.
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.
| 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. |
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 |
src/KeyLoad.AppHost |
Aspire host for the local cluster and every test suite |
src/KeyLoad.Abstractions |
Shared public contracts |
src/KeyLoad.Core, Query, Orleans, Replication, Security, Storage.* |
Database engine, SQL, cluster, replication, permissions and storage |
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 |
Start with the architecture map, the feature specs and repository rules. After building, run a functional suite (unit, recovery, rf3, analyzers or site):
node scripts/Features/TestInfrastructure/run-tests.mjs --KeyLoadTests:Suite=unitdotnet format KeyLoad.slnx --verify-no-changes --no-restoreNative TUnit fixtures own Aspire startup and cleanup; rf3 uses real .NET and official MCP clients against three Docker nodes. Benchmark builds, checks and measurements run exclusively in GitHub's Benchmarks workflow.
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.
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
