Skip to main content

GoatDB Benchmarks

A Third Category of Database

Traditional databases fall into two camps. Remote databases (PostgreSQL, Redis) store data on a server — every read and every write crosses the network. A single-row lookup costs 1–5ms in the same datacenter, 10–50ms from a browser. Embedded databases (SQLite) eliminate the network by running in-process — reads drop to ~15μs — but they offer no sync, no collaboration, and no security primitives.

GoatDB is a third option: an embedded database with built-in peer-to-peer sync whose memory model mirrors how desktop apps handle files. When your app opens a repository, the full dataset loads into memory — like a word processor opening a document. After that one-time cost, reads complete in ~1μs with no network hop and no disk I/O. The app explicitly controls which repositories are in memory by opening and closing them, the same way users open and close files. Explicit user interactions — opening a project, switching a workspace, loading a document — map directly to db.open() and db.closeRepo() calls, so the startup cost is expected and bounded. Sync, conflict resolution, and cryptographic signing run entirely in the background. The network never appears in your hot path.

The table below places GoatDB alongside the databases it draws from. The benchmark sections that follow compare GoatDB head-to-head with SQLite — the only other embedded database that runs across server, browser, and edge.

GoatDBSQLiteRedisPostgreSQL
CategoryEmbedded, memory-first, syncingEmbedded, local-onlyRemote, in-memoryRemote, disk-based
Read latency~1μs (memory lookup)~15μs (FFI + B-tree)~50-200μs P50 (same datacenter)1–5ms (network + query)
Runs in browserYes (OPFS)Yes (WASM)NoNo
Built-in syncMulti-peer CRDTNonePub/sub (no CRDT)Logical replication
Offline supportFull read/writeFull read/writeNoneNone
Memory modelOpen repos load fully into RAM, like opening a file; app explicitly controls which repos are loadedDisk-backed, pages on demandEntire dataset in RAMDisk-backed, pages on demand
Data modelCommit graph with CRDT conflict resolutionB-tree + ACID transactionsKey-value / streamsRelational + ACID

Redis and PostgreSQL are not benchmarked here — they require a network hop per operation, making direct comparison misleading. Reference latency from published production data: Redis (oneuptime.com 2026, centminmod 2025), PostgreSQL (integrate.io 2026). Add 10–50ms from a browser or across regions.

Head-to-Head: GoatDB vs SQLite

Both databases in their recommended production configurations: GoatDB with cryptographic signing and relaxed durability (crash-safe via append-only log), SQLite with WAL mode and synchronous=NORMAL. Color coding: green = meaningfully faster, amber = meaningfully slower, grey = statistical tie (variance makes winner uncertain). Reproduce locally: deno task bench

Query Operations Explained

The query benchmarks test three distinct capabilities:

Filter queries are benchmarked in two configurations:

  • Cold — first-access cost: GoatDB creates a new query object and performs a full O(n) scan evaluating a JavaScript predicate per item; SQLite creates a new connection and runs an equivalent WHERE clause. This represents the worst case: no caching, no reuse.
  • Warm — repeated-access cost: GoatDB reuses the same live query instance (pooled by config hash) and returns its age-tracked frozen result array in O(1) when no data has changed; SQLite reuses a persistent connection with a prepared statement and a warm OS page cache. This represents steady-state performance after the first access.

The parenthetical shows dataset size and result count — e.g., "100k → 1k results" scans 100,000 items cold and returns 1,000 matches; warm, it returns the same 1,000 items directly from cache with no scan.

Filter + sort adds a custom sort comparator on top of predicate filtering (GoatDB) or ORDER BY (SQLite), measuring the combined cost. Same cold/warm split applies.

Live query updates measure reactive performance: a query is subscribed to a 100k-item dataset, then N items are modified across the predicate boundary, and the query results are refreshed. The measurement includes both write latency (N commits/UPDATEs) and query refresh time. In GoatDB, queries subscribe to changes and update incrementally via event propagation. In SQLite, the equivalent is N UPDATE statements followed by a full re-query — there is no subscription mechanism. In the browser, GoatDB queries yield cooperatively to keep the UI at 60fps, so wall-clock time includes scheduling overhead.

Server (Deno / Node.js)

OperationGoatDBSQLite
Create instance1.3ms73.7µs
Open database (empty)437.7µs333.6µs
Open database (100k items)643.7ms130.4µs
Create item35.6µs24.3µs
Read item1.3µs10.2µs
Update item6.3µs17.9µs
Bulk create 100 items2.8ms143.4µs
Bulk read 100 items162.1µs238.1µs
Write 100k items2615.1ms153.3ms
Read 100k items (cold)278.5ms69.9ms
Read 100k items (warm)5.3ms ±37%70.6ms ±91%
Filter query cold (100 items)30.6µs37.2µs
Filter query warm (100 items)0.4µs28.9µs
Filter query cold (100k → 1k results)114.8ms540.9µs
Filter query warm (100k → 1k results)0.3µs534.9µs
Filter query cold (100k → 10k results)124.1ms5.5ms
Filter query warm (100k → 10k results)0.8µs5.4ms
Filter + sort query cold (100 items)7.0µs ±286%17.7µs ±40%
Filter + sort query warm (100 items)0.6µs3.1µs
Live query update (100 items)195.7µs907.1µs
Live query update (1k items)1.2ms3.0ms
Live query update (10k items)9.5ms21.1ms
Count operation1.3µs6.5µs
Keys operation2.9µs11.9µs

Data: Deno. Node.js results are comparable for most operations (bulk writes diverge ~1.7×) — see Detailed Statistics for both.

Browser

GoatDB uses OPFS (Origin Private File System); SQLite uses WASM.

GoatDB writes return after committing to memory (OPFS persistence is batched in a background worker); SQLite WASM writes include synchronous OPFS persistence. This difference primarily affects single-item write latencies.

OperationGoatDBSQLite (WASM)
Create instance11.9ms10.8ms
Open database (empty)1.8ms2.9µs
Open database (100k items)655.2ms2.8ms
Create item45.0µs4.4ms
Read item2.0µs515.5µs
Update item6.5µs3.7ms
Bulk create 100 items4.9ms6.8ms
Bulk read 100 items181.7µs44.3ms
Read 100k items (cold)223.1ms378.8ms
Read 100k items (warm)4.9ms347.5ms
Filter query cold (100 items)33.1µs631.5µs
Filter query warm (100 items)1.1µs627.8µs
Filter query cold (100k → 1k results)602.6ms3.9ms
Filter query warm (100k → 1k results)<0.1µs3.8ms
Filter query cold (100k → 10k results)600.7ms35.6ms
Filter query warm (100k → 10k results)<0.1µs29.2ms
Filter + sort query cold (100 items)5.6µs498.0µs
Filter + sort query warm (100 items)<0.1µs469.5µs
Live query update (100 items)170.0µs454.2ms
Live query update (1k items)1.4ms4429.1ms
Live query update (10k items)42.4ms43846.9ms
Count operation1.5µs439.4µs
Keys operation5.5µs459.0µs

Omitted rows perform comparably across environments — see Detailed Statistics for full browser data.

Why Browser Results Differ

Three phenomena explain why the server and browser tables tell such different stories:

  1. GoatDB is environment-invariant. Data lives in the JS heap regardless of runtime. Browser reads (~1.5μs) are nearly identical to server reads (~0.8μs) — both are Map lookups. The runtime boundary barely registers.

  2. SQLite pays compounding browser overhead. Every browser SQLite operation crosses JS→WASM, then WASM→OPFS with synchronous I/O. On the server, SQLite uses native FFI + OS page cache. This is why read gaps jump from ~11× (server) to ~301× (browser), and live query gaps from 2.3× to 1,022×. Each individual SQLite UPDATE in the browser pays the full WASM+OPFS round-trip, so operations that issue many writes (live query updates) see the largest amplification. SQLite's :memory: mode bypasses all kernel filesystem interactions (sqlite.org/forum/forumpost/7eee1ce2e4f97f47); browser SQLite requires workarounds (Asyncify, SharedArrayBuffer+Atomics) that add 2–5× overhead (powersync.com/blog/sqlite-persistence-on-the-web).

  3. Cold read direction flip. Read 100k cold is GoatDB-slower on server (273ms vs 68ms) but GoatDB-faster in browser (223ms vs 367ms). On the server, SQLite's memory-mapped pages-on-demand wins for sequential scans. In the browser, each page fetch pays the WASM+OPFS boundary cost, making pages-on-demand a liability — while GoatDB's bulk-load-and-deserialize pays the OPFS cost once.

Interpreting the Results

The database is the application cache. After the initial open, item data lives in memory — reads are pure Map lookups with no FFI, no B-tree traversal, and no disk I/O.

  • Reads and metadata: GoatDB wins — ~1μs memory lookups (~11× on server, ~301× in browser). Count/keys 5–8× faster.
  • Cold filter queries: SQLite wins — B-tree indexing: 2–3× faster on server (small datasets), ~18× on large. Cold = first-access cost.
  • Warm filter queries: GoatDB wins — O(1) cached frozen array return. Cold-to-warm speedup: 100–1,000×. SQLite warm improvement is moderate (prepared statement + page cache).
  • Live query updates: GoatDB wins — incremental event propagation vs full re-query. Browser: cooperative yielding adds scheduling overhead (not directly comparable to SQLite's blocking queries).
  • Cold start: SQLite wins — pages-on-demand = near-zero open cost.

Expected outcome after running deno task bench:

  • GoatDB warm reads: 10–50× faster than cold (pure Map lookups)
  • GoatDB warm queries: ~100–1,000× faster than cold (O(1) cached array, no predicate scan)
  • SQLite warm reads: similar to cold (B-tree traversal + FFI cost is irreducible)
  • SQLite warm queries: moderate improvement over cold from prepared statement reuse and warm page cache

Cold vs. warm reads: Read 100k items (cold) measures first-access deserialization — GoatDB lazily parses each commit's JSON on the first valueForKey call, so 100k items means 100k JSON parses. Read 100k items (warm) runs one untimed full scan first to populate all caches, then times a second scan — this is GoatDB's steady-state: pure Map lookups at ~1μs each. Both databases receive identical treatment (one untimed warmup scan, then one timed scan), making the warm comparison the fairest measure of each database's in-process read throughput.

The open cost maps naturally to user-initiated actions — opening a project, switching a workspace, loading a document. Users already expect a brief load when they open something; what they don't expect is latency on every subsequent interaction. GoatDB pays the cost once at open time and then runs at memory speed, matching the mental model modern apps have trained users to expect.

RequirementBest fitWhy
Read-heavy, long-running processGoatDB~1μs reads after one-time startup load; pay the cold-start cost once
Real-time reactive queriesGoatDBIncremental query updates as data changes, no polling
Offline-first / multi-device syncGoatDBBuilt-in CRDT sync with automatic conflict resolution
Distributed AI agentsGoatDBRuns in-process on server, edge, and browser; reactive state; optional cryptographic signing
Bulk write ingestSQLiteB-tree + WAL optimized for batch inserts
Very large datasets (many repos open simultaneously)SQLite / PostgreSQLGoatDB loads each open repo fully into RAM; keep the in-memory set manageable by opening only the repos you need and closing the rest
Short-lived processes (serverless, CLI)SQLiteNear-zero startup cost; no warm-up required
Multi-tenant server with complex queriesPostgreSQLSQL, joins, stored procedures, row-level security
High-throughput caching layerRedis150K+ ops/s single instance, TTL eviction, pub/sub

Configuration Variants

The comparisons below isolate specific GoatDB configuration options. Only operations where configurations differ by more than 2× are shown.

Trusted Mode — Bypassing Signatures

GoatDB signs every commit with Ed25519 by default, enabling multi-peer and untrusted environments. For single-user or fully-trusted local scenarios you can opt out with trusted: true, which removes the signing overhead.

OperationGoatDBGoatDB (Trusted)
Create instance1.3ms846.3µs
Create item35.6µs15.8µs
Read item1.3µs0.8µs ±43%
Update item6.3µs2.5µs
Bulk create 100 items2.8ms848.3µs
Write 100k items2615.1ms679.2ms

Data: Deno. Only operations where trusted mode differs >1.3-1.5× — omitted rows are comparable. See Detailed Statistics for full data.

Trusted mode removes ~3× overhead on bulk writes. Reads are unaffected by signing in either mode.

Durable Mode Comparison (per-operation fsync)

GoatDB (Durable) adds per-operation fsync while keeping full cryptographic signing — isolating the cost of waiting for disk I/O. Only operations where at least one configuration differs meaningfully are shown.

Crash safety without fsync

GoatDB's append-only log remains crash-safe even without fsync — incomplete writes are discarded on restart. SQLite synchronous=OFF risks database corruption on crash. GoatDB also exposes flush() for application-controlled durability.

OperationGoatDB (Durable)GoatDBSQLiteSQLite Fast-Unsafe
Create instance821.7µs1.3ms73.7µs89.2µs
Open database (empty)316.8µs437.7µs333.6µs121.8µs
Open database (100k items)826.5ms643.7ms130.4µs143.2µs
Create item352.5µs35.6µs24.3µs13.6µs
Read item0.8µs1.3µs10.2µs8.8µs
Update item61.4µs6.3µs17.9µs10.0µs
Bulk create 100 items14.6ms2.8ms143.4µs128.7µs
Bulk read 100 items122.6µs162.1µs238.1µs129.1µs
Write 100k items2945.9ms2615.1ms153.3ms140.9ms
Read 100k items (cold)295.4ms278.5ms69.9ms69.8ms
Read 100k items (warm)6.5ms5.3ms ±37%70.6ms ±91%67.3ms
Filter query cold (100 items)10.8µs ±243%30.6µs37.2µs36.4µs
Filter query warm (100 items)0.2µs0.4µs28.9µs28.7µs
Filter query cold (100k → 1k results)113.6ms114.8ms540.9µs565.6µs
Filter query warm (100k → 1k results)0.2µs0.3µs534.9µs504.9µs
Filter query cold (100k → 10k results)122.6ms124.1ms5.5ms5.6ms
Filter query warm (100k → 10k results)0.5µs0.8µs5.4ms5.5ms
Filter + sort query cold (100 items)3.3µs7.0µs17.7µs17.8µs
Filter + sort query warm (100 items)0.3µs0.6µs3.1µs2.0µs
Live query update (100 items)175.7µs195.7µs907.1µs816.4µs
Live query update (1k items)1.3ms1.2ms3.0ms3.1ms
Live query update (10k items)11.0ms9.5ms21.1ms21.0ms
Count operation1.5µs1.3µs6.5µs6.4µs
Keys operation1.1µs2.9µs11.9µs10.6µs

Data: Deno. Only operations where at least one column differs >1.3-1.5× — omitted rows are comparable. See Detailed Statistics for full data.

Storage Formats: Binary vs JSONL

GoatDB defaults to binary format (.goat, fixed-layout binary with length-prefixed framing). An optional JSONL format stores each commit as a plain-text JSON line, making the database human-readable with cat, jq, or any text editor — useful for debugging and data recovery. Only operations where the formats diverge meaningfully are shown.

OperationBinary (default)JSONL
Open database (empty)437.7µs271.8µs
Open database (100k items)643.7ms879.5ms
Create item35.6µs10.6µs
Read item1.3µs0.5µs
Update item6.3µs2.2µs
Read 100k items (cold)278.5ms103.2ms
Count operation1.3µs0.6µs
Keys operation2.9µs1.0µs

Data: GoatDB on Deno. Only operations where formats diverge >1.3-1.5× — omitted rows are comparable. See Detailed Statistics for full data.

The binary format (the default) produces smaller files on disk and enables fast sequential I/O. JSONL is useful for debugging — the log is human-readable with cat or jq. As the table above shows, JSONL is currently faster for some steady-state operations; binary encoding overhead is a known trade-off for compactness.

Methodology

3–10 samples per operation with warmup. Color coding: green = meaningfully faster (>1.3× ms / >1.5× μs), amber = meaningfully slower (>1.3× ms / >1.5× μs), grey = statistical tie (ranges overlap — variance makes winner uncertain), plain = within noise.

Operations with fewer than 3 samples should be treated as indicative rather than precise. In particular, live query update at 10k items runs a single iteration due to its long execution time.

Test environment
PlatformHardwareRuntime
DenoApple M4 Pro, 24GB RAMdeno 2.7.5 (darwin aarch64)
Node.jsApple M4 Pro, 24GB RAMnode v25.2.1 (darwin arm64)
BrowserApple M4 Pro, 24GB RAM (OPFS)browser Chrome 145.0 (Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36)
Full statistics per suite

GoatDB

OperationAverageMedianStddevCVSamplesThroughput
Create instance1.3ms1.3ms126.9µs10%10781 ops/s
Open database (empty)423.2µs430.6µs43.9µs10%72K ops/s
Open database (100k items)643.7ms648.3ms18.4ms3%72 ops/s
Create item35.6µs35.9µs10.8µs30%1028K ops/s
Read item1.3µs1.3µs0.3µs25%10774K ops/s
Update item6.3µs6.3µs1.2µs19%10158K ops/s
Bulk create 100 items2.8ms2.7ms116.7µs4%10359 ops/s
Bulk read 100 items166.5µs163.4µs18.4µs11%106K ops/s
Write 100k items2615.1ms2616.7ms9.9ms0%70 ops/s
Read 100k items (cold)278.5ms276.9ms5.1ms2%74 ops/s
Read 100k items (warm)6.2ms5.4ms2.3ms37%7162 ops/s
Filter query cold (100 items)307.3µs30.4µs847.5µs276%103K ops/s
Filter query warm (100 items)1.8µs0.4µs3.8µs214%10561K ops/s
Filter query cold (100k → 1k results)114.8ms115.0ms1.1ms1%109 ops/s
Filter query warm (100k → 1k results)0.3µs0.3µs0.1µs43%102.96M ops/s
Filter query cold (100k → 10k results)124.1ms123.3ms2.4ms2%78 ops/s
Filter query warm (100k → 10k results)0.8µs0.3µs0.9µs116%71.28M ops/s
Filter + sort query cold (100 items)113.3µs6.6µs324.0µs286%109K ops/s
Filter + sort query warm (100 items)0.8µs0.7µs0.5µs60%101.22M ops/s
Live query update (100 items)200.3µs198.7µs16.1µs8%205K ops/s
Live query update (1k items)1.2ms1.2ms133.8µs11%20842 ops/s
Live query update (10k items)9.5ms9.5ms<0.1µs0%1105 ops/s
Count operation1.3µs1.3µs0.3µs20%10777K ops/s
Keys operation2.9µs2.0µs1.5µs52%10351K ops/s

GoatDB (Trusted)

OperationAverageMedianStddevCVSamplesThroughput
Create instance846.3µs844.9µs32.2µs4%101K ops/s
Open database (empty)366.6µs339.6µs59.5µs16%73K ops/s
Open database (100k items)742.1ms740.1ms17.7ms2%71 ops/s
Create item15.8µs16.2µs3.2µs20%1063K ops/s
Read item0.8µs0.8µs0.4µs43%101.19M ops/s
Update item2.5µs2.5µs0.8µs33%10395K ops/s
Bulk create 100 items848.3µs827.7µs54.5µs6%101K ops/s
Bulk read 100 items131.8µs131.5µs6.7µs5%108K ops/s
Write 100k items679.2ms674.2ms23.0ms3%71 ops/s
Read 100k items (cold)291.7ms291.1ms1.9ms1%73 ops/s
Read 100k items (warm)6.6ms5.3ms2.5ms38%7152 ops/s
Filter query cold (100 items)205.6µs10.8µs607.4µs296%105K ops/s
Filter query warm (100 items)0.3µs0.2µs0.4µs131%103.34M ops/s
Filter query cold (100k → 1k results)114.2ms113.9ms2.2ms2%109 ops/s
Filter query warm (100k → 1k results)0.3µs0.2µs0.2µs63%103.58M ops/s
Filter query cold (100k → 10k results)121.2ms119.9ms3.0ms2%78 ops/s
Filter query warm (100k → 10k results)0.4µs0.2µs0.3µs72%72.80M ops/s
Filter + sort query cold (100 items)36.3µs3.4µs95.4µs263%1028K ops/s
Filter + sort query warm (100 items)0.4µs0.2µs0.3µs86%102.73M ops/s
Live query update (100 items)168.3µs168.5µs7.3µs4%206K ops/s
Live query update (1k items)972.1µs964.5µs125.7µs13%201K ops/s
Live query update (10k items)10.4ms10.4ms<0.1µs0%196 ops/s
Count operation1.0µs1.0µs0.2µs20%10984K ops/s
Keys operation1.9µs1.5µs0.8µs43%10524K ops/s

GoatDB (Durable)

OperationAverageMedianStddevCVSamplesThroughput
Create instance849.3µs814.7µs95.1µs11%101K ops/s
Open database (empty)316.8µs329.8µs24.7µs8%73K ops/s
Open database (100k items)826.5ms827.1ms19.4ms2%71 ops/s
Create item359.0µs359.7µs41.8µs12%103K ops/s
Read item1.1µs0.9µs0.6µs54%10923K ops/s
Update item63.5µs59.8µs9.8µs15%1016K ops/s
Bulk create 100 items14.6ms15.6ms2.1ms14%1068 ops/s
Bulk read 100 items122.6µs121.4µs2.4µs2%108K ops/s
Write 100k items2945.9ms2946.4ms12.1ms0%70 ops/s
Read 100k items (cold)295.4ms296.6ms3.8ms1%73 ops/s
Read 100k items (warm)6.5ms5.5ms2.2ms34%7155 ops/s
Filter query cold (100 items)58.5µs10.5µs141.9µs243%1017K ops/s
Filter query warm (100 items)0.3µs0.2µs0.4µs128%103.16M ops/s
Filter query cold (100k → 1k results)113.6ms113.9ms1.2ms1%109 ops/s
Filter query warm (100k → 1k results)0.2µs0.2µs0.1µs37%104.53M ops/s
Filter query cold (100k → 10k results)122.6ms121.8ms3.1ms3%78 ops/s
Filter query warm (100k → 10k results)0.5µs0.3µs0.5µs94%71.95M ops/s
Filter + sort query cold (100 items)53.6µs3.0µs150.2µs280%1019K ops/s
Filter + sort query warm (100 items)0.4µs0.2µs0.4µs104%102.67M ops/s
Live query update (100 items)177.1µs177.0µs9.5µs5%206K ops/s
Live query update (1k items)1.3ms1.3ms81.1µs6%20795 ops/s
Live query update (10k items)11.0ms11.0ms<0.1µs0%191 ops/s
Count operation3.2µs1.4µs4.0µs126%10315K ops/s
Keys operation1.1µs1.1µs0.1µs11%10873K ops/s

GoatDB JSONL

OperationAverageMedianStddevCVSamplesThroughput
Create instance918.4µs907.8µs114.7µs12%101K ops/s
Open database (empty)271.8µs274.5µs22.3µs8%74K ops/s
Open database (100k items)929.9ms875.0ms138.1ms15%71 ops/s
Create item11.8µs10.9µs3.9µs33%1085K ops/s
Read item0.5µs0.5µs0.1µs26%102.00M ops/s
Update item2.2µs2.1µs0.5µs25%10455K ops/s
Bulk create 100 items2.6ms2.6ms48.2µs2%10383 ops/s
Bulk read 100 items130.4µs125.8µs10.4µs8%108K ops/s
Write 100k items2668.8ms2667.1ms10.7ms0%70 ops/s
Read 100k items (cold)103.2ms101.8ms4.3ms4%710 ops/s
Read 100k items (warm)6.9ms5.2ms3.0ms43%7145 ops/s
Filter query cold (100 items)285.7µs10.5µs855.5µs299%103K ops/s
Filter query warm (100 items)0.2µs0.1µs0.2µs110%106.00M ops/s
Filter query cold (100k → 1k results)115.9ms116.0ms1.4ms1%109 ops/s
Filter query warm (100k → 1k results)0.2µs0.1µs0.1µs95%106.66M ops/s
Filter query cold (100k → 10k results)120.0ms120.5ms2.3ms2%78 ops/s
Filter query warm (100k → 10k results)0.4µs0.3µs0.5µs117%72.40M ops/s
Filter + sort query cold (100 items)162.8µs4.3µs489.7µs301%106K ops/s
Filter + sort query warm (100 items)0.2µs0.1µs0.1µs67%105.70M ops/s
Live query update (100 items)182.0µs180.8µs12.4µs7%205K ops/s
Live query update (1k items)1.2ms1.2ms47.0µs4%20848 ops/s
Live query update (10k items)11.1ms11.1ms<0.1µs0%190 ops/s
Count operation0.6µs0.6µs0.1µs21%101.63M ops/s
Keys operation1.0µs0.9µs0.2µs21%101.04M ops/s

SQLite

OperationAverageMedianStddevCVSamplesThroughput
Create instance77.1µs74.9µs7.6µs10%1013K ops/s
Open database (empty)333.6µs314.3µs34.7µs10%73K ops/s
Open database (100k items)130.4µs124.8µs20.7µs16%78K ops/s
Create item26.5µs24.6µs5.0µs19%1038K ops/s
Read item10.2µs9.5µs2.0µs20%1098K ops/s
Update item17.9µs18.0µs1.0µs6%1056K ops/s
Bulk create 100 items143.4µs143.0µs3.1µs2%107K ops/s
Bulk read 100 items238.1µs231.9µs14.9µs6%104K ops/s
Write 100k items153.3ms150.8ms3.8ms3%77 ops/s
Read 100k items (cold)69.9ms68.0ms5.0ms7%714 ops/s
Read 100k items (warm)107.3ms69.0ms97.5ms91%79 ops/s
Filter query cold (100 items)38.7µs36.1µs5.4µs14%1026K ops/s
Filter query warm (100 items)29.2µs28.8µs1.0µs4%1034K ops/s
Filter query cold (100k → 1k results)543.3µs540.1µs9.4µs2%102K ops/s
Filter query warm (100k → 1k results)539.5µs534.6µs17.2µs3%102K ops/s
Filter query cold (100k → 10k results)5.6ms5.5ms486.3µs9%10178 ops/s
Filter query warm (100k → 10k results)5.5ms5.4ms444.3µs8%10181 ops/s
Filter + sort query cold (100 items)20.0µs17.0µs8.0µs40%1050K ops/s
Filter + sort query warm (100 items)3.3µs3.0µs0.8µs23%10300K ops/s
Live query update (100 items)982.8µs919.3µs305.5µs31%201K ops/s
Live query update (1k items)3.0ms3.2ms240.9µs8%20329 ops/s
Live query update (10k items)21.1ms20.9ms2.8ms13%2047 ops/s
Count operation7.1µs6.3µs2.2µs31%10140K ops/s
Keys operation11.9µs11.3µs1.4µs12%1084K ops/s

SQLite Fast-Unsafe

OperationAverageMedianStddevCVSamplesThroughput
Create instance89.2µs84.4µs13.8µs16%1011K ops/s
Open database (empty)121.8µs122.7µs9.6µs8%78K ops/s
Open database (100k items)143.2µs142.0µs8.5µs6%77K ops/s
Create item15.3µs13.7µs6.4µs42%1065K ops/s
Read item8.8µs8.0µs2.4µs27%10114K ops/s
Update item10.0µs9.9µs1.3µs13%10100K ops/s
Bulk create 100 items128.7µs129.6µs2.6µs2%108K ops/s
Bulk read 100 items129.1µs128.1µs6.4µs5%108K ops/s
Write 100k items140.9ms140.5ms2.1ms2%77 ops/s
Read 100k items (cold)69.8ms69.4ms5.4ms8%714 ops/s
Read 100k items (warm)67.3ms66.8ms4.1ms6%715 ops/s
Filter query cold (100 items)36.4µs35.9µs1.9µs5%1027K ops/s
Filter query warm (100 items)28.7µs27.5µs1.9µs6%1035K ops/s
Filter query cold (100k → 1k results)572.8µs565.5µs25.2µs4%102K ops/s
Filter query warm (100k → 1k results)501.7µs503.5µs13.1µs3%102K ops/s
Filter query cold (100k → 10k results)6.0ms5.7ms763.2µs13%10167 ops/s
Filter query warm (100k → 10k results)5.8ms5.5ms731.8µs13%10172 ops/s
Filter + sort query cold (100 items)19.1µs17.9µs5.2µs27%1052K ops/s
Filter + sort query warm (100 items)2.2µs1.9µs0.8µs35%10454K ops/s
Live query update (100 items)850.6µs832.7µs81.4µs10%201K ops/s
Live query update (1k items)3.1ms3.1ms325.7µs11%20326 ops/s
Live query update (10k items)21.0ms20.7ms3.2ms15%2048 ops/s
Count operation6.4µs6.2µs1.3µs20%10155K ops/s
Keys operation10.6µs10.1µs1.6µs15%1094K ops/s

Running Your Own Benchmarks

git clone https://github.com/goatplatform/goatdb
cd goatdb
deno task bench

The benchmark suite runs on Deno, Node.js, and browser automatically.