A reproducible benchmark of SQLite-backed static lookup data in WebAssembly, tested with Wasmtime and WasmEdge.
This repository examines a practical question for WebAssembly in serverless, edge-computing, cloud-runtime, and Kubernetes-adjacent environments:
If a Wasm module needs a large amount of mostly static data at startup, should the module embed that data directly in its binary?
The idea has clear appeal. A single Wasm artifact can carry code and data together, avoid runtime parsing, simplify distribution, and create a deployment unit that hosts can cache, verify, and move easily.
This benchmark tests that approach with SQLite as the embedded data format.
The benchmark supports a narrower conclusion than the claim that “SQLite in Wasm is faster”:
- Embedding prebuilt SQLite pages in Wasm can outperform startup-time JSON parsing for large static lookup data.
- In this CLI cold-start benchmark, guest SQLite reading an external SQLite file through WASI remained faster than embedding the same database bytes in the Wasm module.
- Large Wasm data segments add measurable loading and instantiation cost before SQLite query performance becomes relevant.
- SQLite-embedded Wasm is therefore best understood as a packaging and deployment tradeoff with specific use cases.
The benchmark compares several ways to provide static lookup data to a Wasm guest:
| Variant | Description |
|---|---|
| JSON parsing | The guest represents static data as JSON and parses it during startup. |
| External SQLite | The guest reads an external SQLite database file exposed through WASI. |
| Embedded SQLite | The Wasm module carries the SQLite database bytes as static data. |
| Dummy data-segment controls | Zero-query Wasm modules compare an empty payload with a 72,978,432-byte embedded payload. |
The workload uses read-only, key-value-style lookups over generated static data. It isolates startup, loading, and data-organization effects rather than modeling a complete database workload.
The embedded SQLite path eliminates JSON parsing and rebuild work, but it also makes the Wasm module larger.
In the tested cold-start setting, the module’s loading and instantiation cost outweighed that benefit. The external SQLite path remained faster, especially as data size increased.
The result defines a useful boundary case:
For large, read-only static data, embedding data in Wasm is tempting, but external file-backed data can remain the better performance default.
WebAssembly is a candidate for edge computing, serverless runtimes, plugin systems, and lightweight sandboxed workloads. These environments often prioritize:
- low cold-start latency,
- portable artifacts,
- deterministic deployment,
- local caching,
- read-only data lookup,
- minimal repeated initialization work, and
- low host and runtime complexity.
A single Wasm artifact that contains code and static data can simplify distribution. This benchmark shows when that simplicity helps, when it costs performance, and why deployment speed depends on more than file count.
The result also informs discussions about Wasm memory control, file mapping, WASI filesystem behavior, and large static data segments.
Embedding static data in Wasm may fit when:
- single-file distribution matters more than raw startup speed,
- the data set is small or medium-sized,
- the deployment environment lacks a stable filesystem path,
- the artifact must be content-addressed and self-contained,
- the workload benefits from eliminating text parsing or index construction, or
- deployment simplicity matters more than binary size.
External data may fit better when:
- the data set is large,
- startup latency is dominated by Wasm loading and instantiation,
- the host can provide external files efficiently,
- many modules or instances share the same data, or
- data updates occur more frequently than code updates.
.
├── README.md
├── REPRODUCING.md
├── docs/
│ └── large-static-data-in-wasm-sqlite-case-study.md
├── guest/
│ └── Wasm guest programs
├── data/
│ └── data-generation scripts
├── scripts/
│ └── build and benchmark harness
├── third_party/
│ └── SQLite source dependency
└── results/
└── benchmark outputs and release artifacts
See REPRODUCING.md for setup, build commands, benchmark execution, and result collection.
The benchmark uses Wasmtime and WasmEdge and targets reproducibility. The measurements apply to the tested runtimes, hosts, and deployment modes; readers should run the benchmark in their own environments.
The full technical report covers the motivation, benchmark design, measured results, interpretation, limitations, and implications for future WebAssembly static-data and memory-mapping work.
This repository contains an exploratory benchmark that documents a negative performance result and a boundary case. Its scope is measurement and interpretation; runtime implementation, packaging standards, compiler work, and replacement data-file systems fall outside that scope.
This project is released under the MIT License.