# Performance Differences Between Native SQLite and WASM Backends in CodeGraph

> Discover native SQLite vs WASM backend performance in CodeGraph. Native SQLite runs 5-10x faster, offering superior efficiency over WASM for your technical needs.

- Repository: [Colby Mchenry/codegraph](https://github.com/colbymchenry/codegraph)
- Tags: performance
- Published: 2026-05-17

---

**Native SQLite via better-sqlite3 runs 5–10× faster than the WASM fallback, with the latter disabling memory mapping and using DELETE journal mode for reduced I/O efficiency.**

CodeGraph stores its knowledge graph in an SQLite database and automatically selects between a native C extension and a WebAssembly implementation based on runtime availability. Understanding the performance differences between native SQLite and WASM backends in CodeGraph is critical for developers optimizing indexing speed and incremental sync operations on large codebases.

## Backend Selection Architecture

At initialization, CodeGraph attempts to load the native **better-sqlite3** driver first. If the compiled binary fails to load—typically due to missing build tools or incompatible CI environments—the system falls back to the pure-JavaScript **node-sqlite3-wasm** implementation.

In [`src/db/sqlite-adapter.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/db/sqlite-adapter.ts) (lines 46-52), the `createDatabase` factory function implements this fallback logic. When the WASM path activates, the adapter prints a warning banner to stderr explicitly stating that operations will run **5–10× slower** than the native backend, ensuring developers understand the performance implications immediately.

## Execution Model and Throughput

The architectural differences between the two backends create dramatic performance gaps:

**Native (`better-sqlite3`):** Operates as a synchronous C extension compiled for the host platform. This implementation executes hundreds of thousands of statements per second with direct access to SQLite’s optimized memory management and platform-specific CPU instructions.

**WASM (`node-sqlite3-wasm`):** Runs as a WebAssembly module interpreted by the JavaScript engine. Every `INSERT`, `SELECT`, and `PRAGMA` call incurs WebAssembly call overhead and boundary crossing costs between JS and WASM memory spaces, resulting in the documented 5–10× throughput reduction highlighted in the source code comments.

## Resource Utilization and Journal Modes

Beyond raw execution speed, the backends differ fundamentally in I/O efficiency. In [`src/db/sqlite-adapter.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/db/sqlite-adapter.ts) (lines 77-85), the WASM adapter explicitly configures the database with constraints that reduce performance:

- **DELETE journal mode** instead of the high-performance **WAL (Write-Ahead Logging)** mode used by native SQLite
- **Disabled memory mapping (mmap)** support, forcing all database I/O through standard read/write operations rather than direct memory access

These constraints significantly reduce I/O efficiency during large-scale indexing operations, exacerbating the throughput limitations of the WebAssembly interpreter.

## Impact on CodeGraph Workflows

The backend selection directly affects two primary CodeGraph operations where database throughput is critical:

**Full Indexing (`codegraph index`):** The WASM backend processes bulk `INSERT` operations significantly slower. Projects that index in seconds with the native driver may require tens of seconds or minutes under WASM due to the combination of execution overhead and DELETE journal mode disk I/O.

**Incremental Sync (`codegraph sync`):** Each batch of changes incurs the same WebAssembly call overhead during incremental updates. developers running frequent sync operations on large codebases will notice substantially slower iteration cycles when the WASM backend is active.

## Detecting Your Active Backend

To determine which SQLite implementation is currently active, inspect the `backend` property exposed by the database connection instance:

```typescript
import { CodeGraph } from 'codegraph';

const cg = await CodeGraph.init('/path/to/project');

// Query which SQLite backend is currently in use
const { backend } = cg.db;  // DatabaseConnection defined in src/db/index.ts
console.log(`Active backend: ${backend}`);
// Output: "Active backend: native" or "Active backend: wasm"

```

When the native driver loads successfully, `backend` returns `"native"`. If the system falls back to WebAssembly, it returns `"wasm"` and triggers the performance warning banner.

### CLI Status Verification

Alternatively, use the command-line interface to verify backend status:

```bash
codegraph status

```

This command (implemented in [`src/bin/codegraph.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/bin/codegraph.ts)) reports the active backend alongside other database statistics. If you observe `Backend: wasm` in the output, expect indexing and sync operations to run several times slower than the native baseline.

## Restoring Native Performance

The WASM fallback activates when `better-sqlite3` fails to load, typically due to missing Python, C++ build tools, or compilation errors during installation. To restore native performance:

1. Install platform-specific build dependencies (Python, C++ compiler, and node-gyp requirements)
2. Reinstall `better-sqlite3` to trigger native binary compilation
3. Verify via `codegraph status` that the output shows `Backend: native`

The unit tests in [`__tests__/sqlite-backend.test.ts`](https://github.com/colbymchenry/codegraph/blob/main/__tests__/sqlite-backend.test.ts) validate this fallback path and confirm that the performance-related warning emits correctly when the WASM adapter initializes.

## Summary

- **Native SQLite** (`better-sqlite3`) provides synchronous C-extension performance with WAL journaling and memory mapping, handling hundreds of thousands of statements per second.
- **WASM SQLite** (`node-sqlite3-wasm`) runs 5–10× slower due to WebAssembly interpretation overhead, forcing DELETE journal mode and disabling mmap for reduced I/O efficiency.
- CodeGraph automatically selects backends in [`src/db/sqlite-adapter.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/db/sqlite-adapter.ts), warning users when the slower WASM fallback activates via console output.
- Check your active backend via `cg.db.backend` or the `codegraph status` CLI command; native restoration requires proper build tools for recompiling `better-sqlite3`.

## Frequently Asked Questions

### How much slower is the WASM backend compared to native SQLite in CodeGraph?

The WASM backend runs **5–10× slower** than the native implementation. This performance degradation is documented in the warning banner at [`src/db/sqlite-adapter.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/db/sqlite-adapter.ts) (lines 49-51) and manifests during both bulk indexing operations and incremental sync cycles due to WebAssembly call overhead and disabled memory mapping.

### Why does the WASM backend disable WAL mode and memory mapping?

In [`src/db/sqlite-adapter.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/db/sqlite-adapter.ts) (lines 77-85), the WASM adapter explicitly configures **DELETE** journal mode instead of WAL and disables mmap because the WebAssembly runtime lacks efficient support for the shared memory mapping primitives required by SQLite’s high-performance modes. This configuration reduces I/O efficiency but ensures compatibility across all JavaScript environments.

### How can I check which SQLite backend CodeGraph is currently using?

Access the `backend` property on the database connection instance (`cg.db.backend`) after initializing CodeGraph, or run `codegraph status` from the terminal. The property returns `"native"` when using `better-sqlite3` or `"wasm"` when using the fallback implementation, as defined in [`src/db/index.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/db/index.ts).

### What causes CodeGraph to fall back to the WASM implementation?

The fallback occurs when the native `better-sqlite3` binary fails to load, typically on systems without C++ build tools, Python, or compatible compilation environments. The factory function in [`src/db/sqlite-adapter.ts`](https://github.com/colbymchenry/codegraph/blob/main/src/db/sqlite-adapter.ts) catches these load failures and automatically instantiates the `WasmDatabaseAdapter`, printing a performance warning to stderr during initialization.