loading engine version

Forty kilobytes.
A real database.

asmdb is a transactional database engine written from scratch in x86-64 assembly. NASM emits the executable directly — no linker, no C runtime, no libraries. It is fast because it does far less: one fixed-shape row, one hash-indexed table, no parser, no planner.

The asmdb mark: a database cylinder at the centre of a circuit die

11,959,261

rows per second, inserted in RAM.
One workstation core, not a hosted tier.

43,749 B

the entire engine, PE64.
52,221 B as ELF64.

0

third-party dependencies.
No linker. No C runtime.

3,145,728

rows in the largest table.
256 bytes each, fixed.

~104 ms

to open a one-million-row
database. 5 MB resident.

The engine

A database is a table. That is the whole model.

One file holds one table. That same file is simultaneously the unit of durability, of locking, of transactions, of backup and of change capture. There is no catalogue to learn and nothing to configure — which is why it fits in forty kilobytes.

One row · 256 bytes · fixed at build time
idu64 — primary key, unique, ≥ 1 O(1) lookup through a hash index
valuei64 — the numeric column the only column RANGE can filter on
tag39 bytes — one token, no spaces longer input is refused, never truncated
content175 bytes — free text UTF-8 preserved byte for byte
created · updatedi64 — unix epoch milliseconds set by the engine, not the caller
$ asmdb notes
asmdb> INSERT 1001 5 project asmdb is written in assembly
[ OK ] 1 row inserted
asmdb> BEGIN
[ OK ] transaction started
asmdb> UPDATE 1001 9 project revised note
[ OK ] 1 row updated
asmdb> COMMIT
[ OK ] transaction committed
asmdb> VERIFY
[ OK ] verify: 1 row(s) checked, no problem found
Real output. FORMAT TSV switches the same commands to a machine-readable stream.

durability

Committed means committed

Every transaction goes through a write-ahead log: the changes are staged and flushed, a commit marker and its CRC-32 are flushed, a change frame is appended and flushed, and only then is the data file touched. A crash resumes from the log. Whole-table operations are announced in the header before they start, so an interrupted TRUNCATE finishes on the next open instead of leaving half a table.

capture

A durable log of every change

Each committed transaction appends one frame to an append-only change log — a total order, a dense sequence, and enough identity to refuse a log that belongs to a different database. Anything downstream can follow the database exactly, and CDCTRIM reclaims what has been acknowledged.

concurrency

One writer, unlimited readers

Reader sessions take no lock at all and run beside the writer. Each command is bracketed by the commit sequence, so a reader never observes a half-applied transaction. Writes do not scale within one instance — that is a real limit, and it is the reason the unit of scale here is the instance.

honesty

What it will not do

No SQL, no joins, no query planner, no secondary indexes — a FIND scans the whole slot region. No authentication, no encryption and no audit log inside the engine; that is the platform's job, and it is written down rather than implied.

Model Context Protocol

A front door built for agents, not bolted on.

Every instance speaks MCP over HTTP with the same tools as the local stdio server. Point a Model Context Protocol client at the endpoint and an agent has durable, transactional memory — with real timestamps, real transactions and a change log, instead of a vector blob it cannot audit.

db_insert

store a row by key or numeric id

db_get

read one row, whole and untruncated

db_update

overwrite, bumping updated

db_delete

remove one row by key

db_find

substring search, paginated

db_list

page through every row

db_count

how many rows are live

Identifiers and values cross the wire as decimal strings — a u64 key and an i64 value do not survive a JavaScript number, and silently rounding someone's primary key is not a trade-off worth making.

// claude_desktop_config.json — or any MCP client
{
  "mcpServers": {
    "asmdb": {
      "url": "https://<gateway-host>/db/7k2m9x4qp1va8ne03wjr5tzy/mcp",
      "headers": {
        "Authorization": "Bearer <your token>"
      }
    }
  }
}
The endpoint is returned at creation; the token is shown once and should go straight into a secret manager.
# or run it locally against a file, no cloud at all
npx asmdb-mcp --db ./memory
The same tools, the same engine, over stdio.

Web applications

The browser never gets the database token.

The instance access token is a bearer token with full authority over that database: read, write, delete and TRUNCATE. A web application calls asmdb from its server. The browser talks to your backend, never to the database directly, and the private database environment is not reachable from the public internet.

browser your backend https://<gateway-host>/db/7k2m9x4qp1va8ne03wjr5tzy/v1/rows Authorization: Bearer INSTANCE_TOKEN
// app/api/notes/route.ts — server-side only
const endpoint = process.env.ASMDB_ENDPOINT!;
// returned as https://<gateway-host>/db/7k2m9x4qp1va8ne03wjr5tzy
const token = process.env.ASMDB_INSTANCE_TOKEN!;

type Row = { id: string; value: string; tag: string; content: string; created: string; updated: string };

async function asmdb(path: string, init: RequestInit = {}) {
  return fetch(`${endpoint}${path}`, {
    ...init,
    headers: {
      authorization: ["Bearer", token].join(" "),
      "content-type": "application/json",
      ...init.headers
    }
  });
}

export async function GET() {
  const res = await asmdb("/v1/rows?limit=100&offset=0");
  const data = await res.json() as { rows: Row[]; count: number; hasMore: boolean; nextOffset: number };
  return Response.json(data);
}

export async function POST(request: Request) {
  const body = await request.json() as { id: string; value: string; tag: string; content: string };
  const res = await asmdb("/v1/rows", {
    method: "POST",
    body: JSON.stringify(body)
  });
  return Response.json(await res.json() as { row: Row }, { status: res.status });
}
The endpoint is returned at creation. The token is shown once, then belongs in server configuration.

strings

Numeric fields cross the wire as decimal strings. id is u64 and value is i64; neither should be parsed as a JavaScript number.

limits

tag is 39 bytes and content is 175 bytes. Longer input is refused, not truncated, so forms should validate before posting.

paging

Listings default to limit=100, cap at 1000 and page with offset. FIND and RANGE are full scans, not keystroke-by-keystroke search endpoints.

shape

One database is one fixed-shape table. There is no CREATE TABLE, no joins and no schema migration step.

Backends do not have to be JavaScript. Python, C# and C clients ship in the repository under clients/.

Three ways in

CLI, HTTP, or your language of choice.

# REST — every field is a string, on purpose
curl -X POST https://<gateway-host>/db/7k2m9x4qp1va8ne03wjr5tzy/v1/rows \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"id":"1001","value":"5",
       "tag":"project","content":"hello"}'

curl https://<gateway-host>/db/7k2m9x4qp1va8ne03wjr5tzy/v1/rows?limit=100 \
  -H "Authorization: Bearer $TOKEN"
Bounded by default — limit caps at 1000.
# Python — the client speaks the engine's own protocol
from asmdb import Client

db = Client(url, token)
db.insert("1001", value="5", tag="project",
          content="asmdb in assembly")

for row in db.find("assembly", limit=50):
    print(row.id, row.content)
Python, C# and C clients ship in the repository.

Tiers

Every tier is the same engine.

Tiers buy latency and headroom — never features. Durability guarantees and the change log are identical on every tier, because they are properties of the engine, not of a price list; the row ceiling follows the memory each tier is given. The last two are on the roadmap and cannot be bought yet. Prices are USD per month; the cost basis is published in the repository.

Free

$0USD / month

  • 0.25 vCPU / 0.5 GiB
  • Sleeps when idle
  • Max 3 databases per account
  • Up to 393,216 rows
  • Identical CLI, REST and MCP

Standard

$15USD / month

  • 0.5 vCPU / 1 GiB
  • Sleeps when idle
  • Max 20 databases per account
  • Up to 1,572,864 rows
  • Identical CLI, REST and MCP

Premium

$49USD / month

  • 1 vCPU / 2 GiB
  • Always warm, no cold start
  • Max 10 databases per account
  • Up to 3,145,728 rows
  • Identical CLI, REST and MCP

Premium+ not yet built

$89USD / month

  • 2 vCPU / 4 GiB
  • Up to 6,291,456 rows
  • Container isolation, read replica
  • Recovery point objective ≤ 5 s
  • Usage plus reserved capacity

Enterprise not yet built

Contact usannual contract + usage

  • Firecracker micro-VM, dedicated nodes
  • Warm standby
  • Data residency
  • Single sign-on
  • Audit export

Free uses 0.25 vCPU / 0.5 GiB because Container Apps Consumption has no smaller 1:2 CPU-to-memory pair. The row ceiling follows the memory: the engine's slot table is resident memory, not a file mapping, so each tier gets the largest table its memory can hold. Premium keeps a replica resident; the price buys no cold start, not a different engine.

What the throughput figure above is not: it is one workstation core with the data in RAM. A hosted tier gives you a fraction of a core — a quarter on free, a half on standard, one on premium — so expect throughput in that proportion, less the REST and gateway hops. The engine is identical; the machine is not. Tiers that sleep also pay a cold start on the first request after idling. Every number on this page is measured, and the one that matters for your workload is the one you measure yourself: the CLI ships a BENCH command that writes real rows into your own database.

Planned platform capabilities at general availability

The engine remains identical on every tier; these are service capabilities planned for GA.

CapabilityFreeStandardPremium
Microsoft Fabric Workload
Automated backups

Binaries

Download the engine bytes being served.

The Windows and Linux binaries are assembled from the same source tree with nasm -f bin. There is no linker and no C runtime; the PE64 build is emitted on Linux by writing different bytes, not by cross-compiling through a toolchain.

Standalone executable files. Nothing to install, no dependencies.

Linux downloads need chmod +x before running.

Security posture is documented in SECURITY.md, including the single RWX image at a fixed address.

Loading manifest…

Provision

Create or open one database at a time.

Creation, access, monitoring and CLI commands are separated so the selected database is always explicit. The instance token is shown once at creation; this tab can hold it for the session, or you can rotate it if it is lost.

Console access

Sign in with Microsoft Entra ID.

Provisioning and the browser CLI are restricted to members of the ASMDB_ADMIN security group. There are no local users, passwords or public sign-up path.

Not signed in.

The public site remains available. Sign in to create databases and open the CLI.