How to Use the runtime.sqlite File in Apache Maka: A Complete Guide
The runtime.sqlite file is Maka's operational-state SQLite database that stores session events, tool-ledger entries, and workspace continuation state; access it programmatically using acquireOperationalStateDatabase() for safe concurrent connections or createSqliteRuntimeStore() for high-level CRUD operations.
Apache Maka uses runtime.sqlite as the single source of truth for all runtime operational data. This SQLite database resides in your workspace storage root and manages everything from session events to tool-ledger integrity. Understanding how to interact with this file through Maka's TypeScript APIs enables you to build extensions, debug sessions, and perform migrations safely.
What Is runtime.sqlite?
The runtime.sqlite file serves as the operational-state database within the Apache Maka ecosystem. According to the source code in packages/storage/src/operational-state-store.ts, this file maintains the authoritative record for session events, tool-ledger entries, workspace version authority, and continuation state. Unlike configuration files, this database is read and written during active Maka sessions, making proper access patterns critical for data integrity.
Locating the Database File
By default, Maka places runtime.sqlite directly in the workspace root directory. The storage package provides a dedicated helper to resolve this path consistently across platforms.
import { resolveOperationalStateDatabasePath } from '@maka/storage';
const dbPath = resolveOperationalStateDatabasePath(workspaceRoot);
// Returns: /path/to/workspace/runtime.sqlite
This function performs a standard path.resolve(workspaceRoot, 'runtime.sqlite') operation, ensuring cross-platform compatibility whether you are on Windows, macOS, or Linux.
Core APIs for Database Access
Maka provides two primary entry points for interacting with runtime.sqlite, each designed for different concurrency and abstraction requirements.
Low-Level Lease Management
For multi-component applications where several processes might access the database simultaneously, use acquireOperationalStateDatabase() defined in packages/storage/src/operational-state-store.ts. This function returns an OperationalStateDatabaseLease that implements reference counting and exclusive ownership guarantees.
import { acquireOperationalStateDatabase } from '@maka/storage';
const lease = acquireOperationalStateDatabase(workspaceRoot);
// lease.database provides a node:sqlite DatabaseSync instance
// lease.transaction('write', () => { ... }) executes atomic transactions
The lease pattern prevents the "cannot rename an open SQLite database" error common on Windows and ensures the underlying connection closes automatically when the last holder calls lease.close().
High-Level Store Interface
For most application logic, createSqliteRuntimeStore() in packages/storage/src/sqlite-runtime-store.ts offers a typed, promise-based API over the raw SQLite connection. This class exposes methods like appendRuntimeEvent(), readImmutableRuntimeEvents(), and backup() while handling schema migrations automatically.
import { createSqliteRuntimeStore } from '@maka/storage';
const runtimeStore = createSqliteRuntimeStore(dbPath, { databaseLease: lease });
// or for read-only scripts:
const readStore = createSqliteRuntimeStore(dbPath, { readOnly: true });
When you supply a databaseLease, the store reuses the existing connection; otherwise, it manages its own file handle.
Working with Runtime Events
The primary purpose of runtime.sqlite is persisting the canonical event stream that represents a Maka session's execution history.
Appending Events
To record new tool calls or session milestones, use the appendRuntimeEvent() method. This automatically canonicalizes events and enforces tool-ledger invariants.
import { encodeCanonicalRuntimeEvent } from '@maka/core/canonical-runtime-event';
const event = encodeCanonicalRuntimeEvent({
id: 'event-1',
sessionId: 'sess-123',
runId: 'run-456',
type: 'tool_call',
toolName: 'search',
args: { query: 'Maka architecture' },
});
await runtimeStore.appendRuntimeEvent('sess-123', 'run-456', event);
Reading Event History
Retrieve immutable event logs for debugging or audit purposes using readImmutableRuntimeEvents(). This returns the complete ordered history for a specific session and run combination.
const events = await runtimeStore.readImmutableRuntimeEvents('sess-123', 'run-456');
// Returns array of canonical runtime events
Database Maintenance and Migration
Maka automatically manages schema evolution between versions, but you can inspect and maintain the database manually when necessary.
Schema Versioning and Migrations
The constructor of SqliteRuntimeStore automatically invokes configureSqliteRuntimeDatabase() and migrateSqliteRuntimeDatabase() from packages/storage/src/sqlite-runtime-schema.ts. You can verify the current schema state using:
const version = runtimeStore.schemaVersion(); // e.g., 2
const journalMode = runtimeStore.journalMode(); // typically 'wal'
If the version is lower than SQLITE_RUNTIME_SCHEMA_VERSION (defined in the schema module), the migration routines execute automatically to bring older runtime.sqlite files up to date.
Creating Backups
Before major migrations or for disaster recovery, use the lease's backup() method, which wraps SQLite's native backup API for fast, consistent copies.
const bytesCopied = await lease.backup('/path/to/backup/runtime.sqlite');
console.log(`Backed up ${bytesCopied} bytes`);
This method validates that the destination path differs from the source and performs a page-by-page copy without locking the database for extended periods.
Direct Access vs. Lease-Based Access
Choose your access pattern based on concurrency requirements and operational context:
- Lease-based access: Required when multiple components (session manager, tool ledger, workspace-version authority) share the database. Prevents file-handle leaks and Windows file-locking issues through automatic reference counting.
- Direct store access: Suitable for single-process scripts or read-only analysis tools where you open the file, query data, and exit immediately.
For read-only inspection without the overhead of lease management:
const store = createSqliteRuntimeStore('/path/to/runtime.sqlite', { readOnly: true });
const events = await store.readImmutableRuntimeEvents('sess-1', 'run-1');
Complete Code Examples
Listing All Runs for a Session
For audit scripts or debugging tools, query the database directly using the store's underlying connection:
import { resolveOperationalStateDatabasePath, createSqliteRuntimeStore } from '@maka/storage';
async function listRuns(workspaceRoot: string) {
const dbPath = resolveOperationalStateDatabasePath(workspaceRoot);
const store = createSqliteRuntimeStore(dbPath, { readOnly: true });
const runs = store.db.prepare(`
SELECT DISTINCT run_id FROM runtime_events
WHERE session_id = ?
`).all('my-session') as { run_id: string }[];
console.log('Runs for session "my-session":', runs.map(r => r.run_id));
}
Recording Tool Calls with Lease Management
When integrating with the active Maka runtime, always acquire a lease to ensure safe concurrent access:
import {
acquireOperationalStateDatabase,
createSqliteRuntimeStore,
} from '@maka/storage';
import { encodeCanonicalRuntimeEvent } from '@maka/core/canonical-runtime-event';
async function recordToolCall(root: string, sessionId: string, runId: string) {
const lease = acquireOperationalStateDatabase(root);
const store = createSqliteRuntimeStore(root, { databaseLease: lease });
const event = encodeCanonicalRuntimeEvent({
id: 'event-1',
sessionId,
runId,
type: 'tool_call',
toolName: 'search',
args: { query: 'Maka architecture' },
});
await store.appendRuntimeEvent(sessionId, runId, event);
lease.close(); // Releases reference count and closes connection if last holder
}
Automated Backup Routine
Implement disaster recovery by backing up the database before critical operations:
import {
acquireOperationalStateDatabase,
resolveOperationalStateDatabasePath,
} from '@maka/storage';
import { join } from 'node:path';
async function backupRuntime(root: string) {
const lease = acquireOperationalStateDatabase(root);
const backupPath = join('/tmp/backups', 'runtime.sqlite');
await lease.backup(backupPath);
console.log('Backup saved to', backupPath);
lease.close();
}
Summary
- The
runtime.sqlitefile in Apache Maka stores all operational state including session events and tool-ledger entries at the workspace root. - Use
resolveOperationalStateDatabasePath()to locate the file,acquireOperationalStateDatabase()to obtain a concurrency-safe lease, andcreateSqliteRuntimeStore()for high-level data operations. - The lease pattern prevents file-locking issues on Windows and ensures automatic cleanup of database connections through reference counting.
SqliteRuntimeStoreautomatically handles schema migrations defined inpackages/storage/src/sqlite-runtime-schema.ts, bringing older databases up to the currentSQLITE_RUNTIME_SCHEMA_VERSION.- For read-only analysis scripts, you can bypass the lease and open the database directly with the
readOnly: trueoption.
Frequently Asked Questions
Where is the runtime.sqlite file located in a Maka workspace?
By default, Maka creates runtime.sqlite in the root directory of your workspace. The @maka/storage package exports resolveOperationalStateDatabasePath(workspaceRoot) to reliably resolve this location across operating systems, performing a platform-aware path join between the workspace root and the filename 'runtime.sqlite'.
How do I prevent database locking errors when accessing runtime.sqlite?
Always use acquireOperationalStateDatabase() to obtain an OperationalStateDatabaseLease before writing to the database. This lease implements reference counting and guarantees that only one process-local owner holds the connection at a time, which prevents the "database is locked" and "cannot rename an open SQLite database" errors common on Windows and busy systems.
Can I read from runtime.sqlite without acquiring a lease?
Yes, for simple read-only scenarios or offline analysis, you can call createSqliteRuntimeStore(dbPath, { readOnly: true }) without providing a databaseLease. This opens an independent connection to the SQLite file suitable for querying events or inspecting schema versions, though you should avoid this pattern in active Maka extensions that run concurrently with the main process.
How does Maka handle schema migrations for runtime.sqlite?
Maka automatically manages migrations through the SqliteRuntimeStore constructor, which invokes configureSqliteRuntimeDatabase() and migrateSqliteRuntimeDatabase() from packages/storage/src/sqlite-runtime-schema.ts. These functions check the current schemaVersion() against SQLITE_RUNTIME_SCHEMA_VERSION and apply incremental migrations to bring the database up to date without manual intervention.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →