# TinyCortex Memory: How the In-Process Engine Powers OpenHuman Memory Trees

> Discover TinyCortex Memory, the in-process engine for OpenHuman memory trees. Experience O(1) snapshot reads and atomic persistence with lock-free efficiency.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: deep-dive
- Published: 2026-08-28

---

**TinyCortex Memory is the core in-process engine inside the OpenHuman Rust binary that manages hierarchical memory trees using lock-free data structures, providing O(1) snapshot reads and atomic persistence to SQLite without IPC overhead.**

TinyCortex Memory serves as the central nervous system for the [OpenHuman](https://github.com/tinyhumansai/openhuman) project, handling all persistent data as hierarchical trees within the same process as the core runtime. Implemented in the `openhuman-core` crate, this engine eliminates cross-process communication delays by keeping the memory tree in the application's address space. It powers everything from conversation history to document storage using a directed acyclic graph model that supports fast ancestor queries and deterministic versioning.

## Architectural Overview

### The Memory Tree Data Model

At its heart, TinyCortex Memory organizes data as a **memory tree**—a directed acyclic graph where each node represents a discrete piece of content such as a message, document, or tool result. Every node possesses a unique `path_scope` (e.g., `/chat/2024-08-28`) and optional metadata including tags and timestamps. This structure enables efficient traversal of deep conversation histories while maintaining referential integrity across parent-child relationships.

The tree structure is defined in the core memory modules, with the domain entry point at [`src/openhuman/memory/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/mod.rs). This file re-exports the public API and registers the memory domain controllers when `DomainSet::memory` is enabled in the runtime configuration.

### In-Process Execution Model

Unlike external memory services that require network calls or IPC, TinyCortex Memory runs **in-process** inside the OpenHuman core binary. It uses Rust's `Arc` (atomic reference counting) and `RwLock` primitives to manage concurrency: read-only snapshots are shared across concurrent turns through `Arc` clones, while writes are serialized through a single "write gate" to prevent conflicts.

This design choice eliminates the ~10ms overhead typical of RPC round-trips, allowing the LLM to read entire subtrees or write new nodes with minimal latency. The engine maintains the entire tree lifecycle—including creation, persistence, pruning, and snapshotting—within the same address space, as documented in the migration plans.

### Persistence and Versioning Layer

Durability is handled through a dual-layer approach. Hot data resides in RAM within `MemoryNode` structures, while the **SQLite** database (`memory.db`) provides atomic transactional storage. A background service (`memory::git::git_sync_worker` in [`src/openhuman/memory/git.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/git.rs)) mirrors state changes into a git-backed ledger, writing `MemoryDiff` objects that create an immutable audit trail.

This architecture supports deterministic replay and rollback capabilities, as each snapshot can be reconstructed from the sequence of diffs stored in the git repository.

## How TinyCortex Memory Works Internally

### Tree Initialization and Root Creation

When the OpenHuman core starts, the function `memory::init::init_memory_tree()` constructs the root node representing the tree base (`/`). This initialization assigns a unique ID and timestamp to the root `MemoryNode`, establishing the foundation for all subsequent operations.

The initialization logic resides within the memory domain registration flow in [`src/core/all.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/all.rs), ensuring that memory RPC endpoints (`/rpc/memory/*`) are available only when the domain is explicitly enabled.

### Node Insertion via Path Scopes

New content enters the tree through `memory::ops::insert_chunk()` (defined in [`src/openhuman/memory/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/ops.rs)). This operation creates a `Chunk` object containing the payload and metadata, then attaches it to a parent node identified by its `path_scope`.

The insertion process updates both the in-memory `MemoryNode` structures and the SQLite `chunks` table atomically. By using path-based scoping (e.g., `/chat/2024-08-28/message-001`), the engine maintains logical groupings that mirror the application's domain structure.

### Traversal and In-Memory Caching

Queries such as `memory::ops::query_subtree()` utilize depth-first iterators that traverse the `children` vectors stored in each `MemoryNode`. Because the engine caches entire subtrees in RAM, these operations yield `Chunk` objects without additional database hits once the data is loaded.

This caching strategy enables O(1) access to existing nodes through shared references, dramatically reducing latency when the LLM needs to retrieve conversation context or historical tool outputs during active turns.

### Versioned Snapshots for Consistent Views

At the end of each processing turn, the engine calls `memory::ops::snapshot()` to clone the `Arc<MemoryNode>` representing the current tree root. This creates an immutable, versioned view that can be passed to asynchronous tools or subsequent turns.

Because snapshots leverage atomic reference counting, tools can hold consistent views of the tree state even as the main thread continues inserting new nodes. The snapshotting mechanism guarantees that parallel "what-if" reasoning branches do not interfere with the canonical tree state.

## Working with TinyCortex Memory: Code Examples

The `tinymemory-api` contract exposes these capabilities through the `openhuman::memory` module. Below are practical examples demonstrating insertion, querying, and snapshotting:

```rust
// Insert a new memory chunk (e.g., a user message)
use openhuman::memory::{ops, Chunk, Metadata};

let msg = Chunk::new("User says: Hello!".into());
let meta = Metadata::default().with_tag("chat");
ops::insert_chunk(msg, "/chat/2024-08-28", meta)?;

```

```rust
// Query a subtree to retrieve all chat messages under a specific date
use openhuman::memory::ops::query_subtree;

let subtree = query_subtree("/chat/2024-08-28")?;
for chunk in subtree {
    println!("Message: {}", String::from_utf8_lossy(&chunk.payload));
}

```

```rust
// Take a snapshot for a tool that runs asynchronously
use openhuman::memory::ops::snapshot;
use std::sync::Arc;

let snap: Arc<MemoryNode> = snapshot()?;
tool::run_async(move || {
    // The tool sees a stable view even if new nodes are inserted later
    let view = snap.clone();
    // Process the snapshot...
});

```

All public types including `Chunk`, `Metadata`, and `MemoryNode` are defined in the `tinymemory-api` contract and re-exported through [`src/openhuman/memory/api.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/api.rs).

## Summary

- **TinyCortex Memory** is an in-process engine within OpenHuman's Rust core that manages hierarchical memory trees without IPC overhead.
- The engine uses **path scopes** and `MemoryNode` structures to create a directed acyclic graph optimized for ancestor/descendant queries.
- **Concurrency** is handled via `Arc` and `RwLock`, allowing O(1) snapshot reads and serialized writes through a single write gate.
- **Persistence** combines SQLite atomic transactions with a git-backed diff ledger for auditability and rollback support.
- Core operations including `insert_chunk()`, `query_subtree()`, and `snapshot()` are implemented in [`src/openhuman/memory/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/ops.rs) and exposed through the `tinymemory-api` contract.

## Frequently Asked Questions

### What is the difference between TinyCortex Memory and a traditional database?

TinyCortex Memory operates as an in-process engine rather than a separate database service. While it uses SQLite for persistence, the active tree lives entirely in RAM within the OpenHuman process, eliminating network latency and serialization costs. Traditional databases require IPC or network calls, whereas TinyCortex Memory shares memory directly with the LLM runtime through `Arc<MemoryNode>` references, enabling microsecond-scale access times for cached data.

### How does TinyCortex Memory handle concurrent read and write operations?

The engine implements a **read-heavy** concurrency model using Rust's `Arc` (atomic reference counting) for shared ownership and `RwLock` for synchronization. Multiple readers can hold snapshots simultaneously without blocking, while writes are serialized through a single "write gate" to ensure consistency. This design allows the LLM to read historical context in O(1) time while new chunks are being inserted, with locks held only for milliseconds during atomic commit operations.

### Where is the memory tree data physically stored?

Data persists in two locations: a local **SQLite database** (`memory.db`) stores the current state of all chunks and metadata, while a **git-backed ledger** maintains an immutable history of changes. The background worker defined in [`src/openhuman/memory/git.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/git.rs) periodically writes `MemoryDiff` objects to the git repository, creating a tamper-evident audit trail. This dual-layer approach combines the speed of in-memory access with the durability and versioning capabilities of transactional storage.

### Can TinyCortex Memory be accessed from external processes or only within OpenHuman?

Currently, TinyCortex Memory is strictly **in-process** and designed to run exclusively within the OpenHuman core binary. All access occurs through the `tinymemory-api` contract exposed via [`src/openhuman/memory/api.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/memory/api.rs). While the internal RPC endpoints (`/rpc/memory/*`) provide structured access for native modules loaded by the core, there is no external IPC interface—this design prioritizes security and latency by keeping memory operations within the same sandbox and address space as the LLM runtime.