# How Apache Maka Ensures Durable Runtime Event Persistence Against Crashes

> Discover how Apache Maka ensures durable runtime event persistence against crashes using an append-only SQLite database, transactional writes, and deterministic recovery.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: internals
- Published: 2026-09-02

---

**Apache Maka guarantees crash-resilient event persistence by recording every agent interaction in an append-only SQLite database (`runtime.sqlite`) with transactional writes, strict schema versioning, and deterministic recovery protocols.**

All runtime events—model messages, tool calls, tool results, and termination facts—are stored in a single **Runtime Event Log** that survives process termination, system crashes, or power loss. On restart, Maka reopens this log to reconstruct exact run states and resume safely without duplicating side effects.

## Single Canonical Store with Transactional Durability

Apache Maka centralizes all runtime facts in one SQLite database. The `SqliteRuntimeStore` class in [`packages/storage/src/sqlite-runtime-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/sqlite-runtime-store.ts) executes every insert inside a single transaction, leveraging SQLite's ACID guarantees (v3.35+) for atomicity and durability.

```typescript
// packages/storage/src/sqlite-runtime-store.ts
// All events are inserted transactionally
await db.run('BEGIN TRANSACTION');
// ... insert statements
await db.run('COMMIT');

```

This design eliminates partial writes. Either the entire event batch persists to disk, or none of it does—preventing corruption even if the process terminates mid-write.

## Append-Only Semantics Prevent History Loss

Events are **never modified or deleted**. Compaction and pruning operations only affect provider projections; the underlying facts in `runtime.sqlite` remain immutable. As documented in [`ARCHITECTURE.md`](https://github.com/apache/maka/blob/main/ARCHITECTURE.md), this append-only approach ensures accidental operations cannot erase execution history.

## Hardened Schema with Protective PRAGMAs

The runtime schema enforces durability through explicit configuration:

| PRAGMA | Purpose |
|--------|---------|
| `busy_timeout` | Prevents lock contention timeouts |
| `foreign_keys` | Maintains referential integrity |
| `query_only` (read mode) | Blocks accidental writes during recovery |

The schema version (`SQLITE_RUNTIME_SCHEMA_VERSION`) in [`packages/storage/src/sqlite-runtime-schema.js`](https://github.com/apache/maka/blob/main/packages/storage/src/sqlite-runtime-schema.js) enables migration detection and prevents opening incompatible database files.

## Recovery-First Design for Crash Scenarios

When Maka restarts after a crash, the recovery protocol activates before any new run begins. The system calls `openRuntimeEventPersistence` (or `openRuntimeEventReadPersistence` for read-only access) to:

1. Reopen `runtime.sqlite`
2. Replay immutable events to reconstruct run state
3. Resolve terminal status using the recovery resolver

Per [`docs/architecture/runtime-resume-architecture.md`](https://github.com/apache/maka/blob/main/docs/architecture/runtime-resume-architecture.md), the recovery resolver examines stored events to classify tool operations as:
- **Completed** — result was persisted
- **Unknown** — outcome indeterminate, requires parking
- **Pending** — never executed, safe to retry

## Transactional Claims Prevent Duplicate Side Effects

The `claimContinuation` mechanism protects against exactly-once violations. When a run claims a continuation, the claim and its triggering event are written together. If the process dies mid-write, the next startup detects the missing claim and treats the run as unfinished—preventing duplicate tool executions.

```typescript
// From packages/storage/src/sqlite-runtime-store.ts
await persistence.runtimeEventStore.appendRuntimeEvent(
  'session-1',
  'run-42',
  {
    id: 'evt-123',
    ts: Date.now(),
    content: { kind: 'function_call', name: 'readFile', args: { path: 'foo.txt' } },
  },
  { durable: true }  // Forces fsync to disk
);

```

The `durable: true` option ensures SQLite executes `fsync`, guaranteeing the write survives power loss.

## Authority Isolation for Deterministic State

The **Runtime Event Log** is the sole source of truth. All other components—Graph, Context, and UI—maintain only projections derived from this log. This isolation eliminates divergent state and makes recovery deterministic: replay the same events, reconstruct the same state.

## Working with Runtime Event Persistence

### Opening Writable Persistence

```typescript
import { openRuntimeEventPersistence } from '@maka/storage';

const persistence = await openRuntimeEventPersistence({
  workspaceRoot: '/my/workspace'
});
// Creates or opens runtime.sqlite in the workspace

```

### Appending Events Durably

```typescript
await persistence.runtimeEventStore.appendRuntimeEvent(
  'session-1',
  'run-42',
  {
    id: 'evt-123',
    ts: Date.now(),
    content: { 
      kind: 'function_call', 
      name: 'readFile', 
      args: { path: 'foo.txt' } 
    },
  },
  { durable: true }
);

```

### Recovery and Replay

```typescript
import { openRuntimeEventReadPersistence } from '@maka/storage';

const readOnly = await openRuntimeEventReadPersistence({
  workspaceRoot: '/my/workspace'
});

const events = await readOnly.runtimeEventStore.readRuntimeEvents(
  'session-1', 
  'run-42'
);
// events contains the immutable, ordered log for reconstruction

```

## Key Implementation Files

| File | Responsibility |
|------|--------------|
| [`packages/storage/src/sqlite-runtime-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/sqlite-runtime-store.ts) | Core SQLite operations, transactions, and durability guarantees |
| [`packages/storage/src/runtime-event-persistence.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/runtime-event-persistence.ts) | High-level persistence layer initialization |
| [`packages/storage/src/sqlite-runtime-schema.js`](https://github.com/apache/maka/blob/main/packages/storage/src/sqlite-runtime-schema.js) | Schema definitions and version tracking |
| [`ARCHITECTURE.md`](https://github.com/apache/maka/blob/main/ARCHITECTURE.md) | System-wide architecture documentation |
| [`docs/architecture/runtime-resume-architecture.md`](https://github.com/apache/maka/blob/main/docs/architecture/runtime-resume-architecture.md) | Crash recovery and continuation protocols |

## Summary

- **Runtime Event Log** in `runtime.sqlite` provides durable, append-only event storage
- **Transactional writes** via `SqliteRuntimeStore` guarantee atomic persistence
- **Schema versioning and PRAGMAs** protect against corruption
- **Recovery-first startup** reconstructs state before accepting new work
- **Transactional claims** prevent duplicate side effects after crashes
- **Authority isolation** ensures deterministic recovery through event replay

## Frequently Asked Questions

### How does Apache Maka prevent data loss during a power failure?

Maka uses **durable writes** with SQLite's `fsync` guarantee. The `durable: true` flag in `appendRuntimeEvent` forces the operating system to flush data to physical storage before returning. Combined with SQLite's WAL mode and transactional boundaries, events survive power loss regardless of when the crash occurs.

### Can Maka resume a run that crashed mid-tool-execution?

Yes. The **recovery resolver** examines the immutable event log to determine tool completion status. In [`docs/architecture/runtime-resume-architecture.md`](https://github.com/apache/maka/blob/main/docs/architecture/runtime-resume-architecture.md), Maka defines three states: completed operations resume with stored results, unknown operations are parked for manual review, and pending operations retry safely.

### Why does Maka use SQLite instead of a distributed database?

SQLite provides **single-file portability**, zero external dependencies, and proven crash durability—critical for a local-first agent runtime. The `runtime.sqlite` file travels with the workspace, enabling seamless transfer and offline operation without network requirements.

### What happens if the database file becomes corrupted?

The **schema version check** and **PRAGMA integrity constraints** detect corruption early. Maka opens read-only stores with `query_only` enabled during recovery, preventing further damage. For unrecoverable corruption, the append-only design means partial event logs may still be salvageable for forensic reconstruction.