# How Apache Maka Manages Sessions and Turns: A Three-Layer Architecture Guide

> Explore how Apache Maka manages sessions and turns using its three layer architecture for efficient handling of long conversational transcripts.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: architecture
- Published: 2026-08-29

---

**Apache Maka manages Sessions and Turns through a three-layer architecture that separates SQLite persistence, runtime orchestration, and client-side virtualization to handle long conversational transcripts efficiently.**

Apache Maka implements a robust conversation management system where Sessions and Turns are handled across distinct persistence, runtime, and UI layers. This architecture ensures durable storage of conversation history while maintaining smooth scrolling performance even with thousands of turns. Understanding how these components interact reveals the engineering decisions behind Maka's scalable approach to stateful AI conversations.

## The Three-Layer Architecture for Session and Turn Management

Maka splits responsibility for Sessions and Turns across three architectural layers:

- **Persistence Layer**: Handles durable storage of session metadata and turn records in SQLite via the `SessionStore` API ([`packages/storage/src/session-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/session-store.ts)).
- **Runtime Layer**: Exposes the public API through `SessionManager` ([`packages/runtime/src/session-manager.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/session-manager.ts)), orchestrating turn generation and session-wide state.
- **Client Layer**: Manages UI virtualization through [`use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/use-turn-virtualizer.ts) ([`packages/ui/src/use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/use-turn-virtualizer.ts)), rendering only visible turns for performance.

### Persistence Layer and SessionStore

The `SessionStore` class in [`packages/storage/src/session-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/session-store.ts) provides the canonical storage implementation for Sessions and Turns. It validates session IDs using `isSafeSessionId` (lines 99-100) before persistence and manages SQLite tables defined in [`sqlite-session-metadata-store.ts`](https://github.com/apache/maka/blob/main/sqlite-session-metadata-store.ts).

When creating a session, the store generates a UUID and returns a `SessionHeaderSnapshot` (lines 31-34). For querying, it projects a **session catalog** via `SessionCatalogRecord` (lines 42-45), enabling efficient listing and summary operations. The store also handles safe deletion through `probeSessionRemoval` and `removeSession` (lines 136-140), preserving immutable audit trails while retiring session rows.

### Runtime Layer and SessionManager

The `SessionManager` class in [`packages/runtime/src/session-manager.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/session-manager.ts) serves as the primary interface for Sessions and Turns manipulation. It coordinates between `SessionStore`, the AI `AgentBackend`, and the `ExecutionBoundary` sandbox.

Key responsibilities include:

1. Creating sessions via `createSession()`, which internally calls `createStableSession`
2. Managing turn lifecycle through `appendTurn()`
3. Providing read models via `RuntimeReadModel` to answer queries about session lists, summaries, and transcript pages

### Client Layer and Turn Virtualization

For UI performance, Maka implements turn virtualization in [`packages/ui/src/use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/use-turn-virtualizer.ts). This React hook builds a `TurnVirtualLayout` that maps turn IDs to cumulative heights and manages a `TurnVirtualWindow` representing the currently rendered subset. The `revealTurn(turnId)` function (lines 72-78) scrolls specific turns into view, while `reconcileTurnVirtualWindow` (lines 90-122) adjusts the visible slice based on scroll position.

## Session Lifecycle Implementation

### Creation and ID Validation

Sessions begin with validation. The `SessionStore` validates IDs using `isSafeSessionId` before accepting any operation. The creation flow generates a UUID and persists session headers to SQLite, returning a `SessionHeaderSnapshot` that serves as the authoritative read model.

### Turn Aggregation and Storage

Turns are stored as `TurnRecord` objects (imported in `session-store.ts:84-85`). The runtime aggregates raw messages into turns using `deriveTurnRecords` (`runtime-manager.ts:100-102`), ensuring each turn maintains sequence integrity within the session transcript.

## Turn Management Protocol

### Server-Side Protocol Definitions

The wire format for Turns is defined in [`packages/runtime-host/src/protocol/session-turns.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/session-turns.ts). The `SessionTurnContribution` interface specifies:

```typescript
export interface SessionTurnContribution {
  readonly turnId: string;
  readonly firstSequence: number;
  readonly latestState: { readonly sequence: number; readonly message: TurnStateMessage } | null;
  readonly userPromptPreview: string | null;
  readonly hasAssistantMessage: boolean;
}

```

Before transmission, `projectSessionTurnContributionForWire` (lines 20-44) sanitizes contributions by truncating large strings via `truncateUtf8` and validating IDs through `requireEntityId`. These contributions stream to clients via `SessionTurnsQueryResult` (lines 88-94).

### Cross-Layer Turn Flow

When a new turn generates:

1. `SessionManager` records the `TurnStateMessage` in SQLite
2. `RuntimeReadModel` aggregates the turn into a `SessionTurnContribution`
3. The client receives the contribution via WebSocket/RPC
4. [`use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/use-turn-virtualizer.ts) updates the `TurnVirtualLayout`; if the turn falls outside the current `TurnVirtualWindow`, the virtualizer slides the window to include it while preserving scroll position

## Practical Implementation Examples

### Creating a Session

```typescript
import { SessionManager } from '@maka/runtime';

async function startNewSession(name: string, sessionManager: SessionManager) {
  const input = {
    sessionName: name,
  };
  const result = await sessionManager.createSession(input);
  console.log('New session ID:', result.sessionId);
}

```

This orchestrates `createStableSession` in `SessionStore`, which validates the ID and writes to SQLite.

### Appending a Turn

```typescript
import { TurnRecord } from '@maka/core/session';

const turn: TurnRecord = {
  turnId: 'turn-1',
  firstSequence: 1,
  // ...additional fields
};

await sessionManager.appendTurn(sessionId, turn);

```

The `appendTurn` method persists to SQLite and updates the read model for immediate client availability.

### Virtualized Turn Navigation

```typescript
import { useTurns } from '@maka/ui';

function SessionTranscript({ sessionId, scrollRef }) {
  const { turnIds, revealTurn } = useTurns({
    sessionId,
    scrollRef,
  });
  
  // Scroll to specific turn
  const handleJump = () => revealTurn('turn-42');
  
  return (
    // Render only turns in the virtual window
  );
}

```

The `revealTurn` function (lines 72-78 in [`use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/use-turn-virtualizer.ts)) handles scrolling and window reconciliation.

## Summary

- **Sessions** persist in SQLite through `SessionStore` ([`packages/storage/src/session-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/session-store.ts)), which validates IDs via `isSafeSessionId` and manages metadata through `SessionHeaderSnapshot` and `SessionCatalogRecord` projections.
- **Turns** flow from `TurnRecord` storage through `SessionTurnContribution` wire formats defined in [`session-turns.ts`](https://github.com/apache/maka/blob/main/session-turns.ts), sanitized by `projectSessionTurnContributionForWire`.
- **Runtime orchestration** occurs in `SessionManager` ([`packages/runtime/src/session-manager.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/session-manager.ts)), bridging storage, AI backends, and sandbox boundaries.
- **UI scalability** relies on [`use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/use-turn-virtualizer.ts), which implements `TurnVirtualWindow` and `revealTurn` to render only visible turns from potentially thousands of conversation entries.

## Frequently Asked Questions

### How does Apache Maka validate session IDs?

Maka validates session IDs through the `isSafeSessionId` function in [`packages/storage/src/session-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/session-store.ts) (lines 99-100). This safety check runs before any persistence operation to ensure IDs meet canonical format requirements and prevent injection attacks.

### What is the TurnVirtualWindow in Maka's UI layer?

The `TurnVirtualWindow` is a client-side construct managed by [`use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/use-turn-virtualizer.ts) ([`packages/ui/src/use-turn-virtualizer.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/use-turn-virtualizer.ts)) that represents the subset of turns currently rendered in the DOM. It works with `TurnVirtualLayout` to compute cumulative heights and enable smooth scrolling through long transcripts while maintaining minimal memory footprint.

### How are turns persisted in Maka's storage layer?

Turns are stored as `TurnRecord` objects within the session transcript. The `SessionStore` persists these to SQLite alongside session metadata. The runtime aggregates messages into turns using `deriveTurnRecords` (`runtime-manager.ts:100-102`) before storage, ensuring sequence integrity and immutable audit trails.

### What happens when a new turn is generated in a Maka session?

When a new turn generates, `SessionManager` first records the `TurnStateMessage` in SQLite through `SessionStore`. The `RuntimeReadModel` then aggregates this into a `SessionTurnContribution` and streams it to the client via the protocol defined in [`session-turns.ts`](https://github.com/apache/maka/blob/main/session-turns.ts). The UI layer receives the contribution, updates its virtual layout, and if necessary, slides the `TurnVirtualWindow` to include the new turn while preserving the user's scroll position.