# How to Implement Persistent User Memory Across Agent Sessions

> Learn how to implement persistent user memory across agent sessions using PostgresMemoryStore and MemoryFactory. Ensure user data survives process restarts with this guide.

- Repository: [Bojie Li/ai-agent-book](https://github.com/bojieli/ai-agent-book)
- Tags: how-to-guide
- Published: 2026-08-17

---

**You implement persistent user memory across agent sessions by configuring a PostgreSQL-backed `PostgresMemoryStore`, initializing the `MemoryFactory` singleton with a `MemoryConfig`, and accessing the cached instance via `MemoryFactory.instance()` to ensure user data survives process restarts.**

Maintaining continuity across conversations is critical for AI agents that need to remember user preferences and context. The `bojieli/ai-agent-book` repository provides a modular memory subsystem that supports both ephemeral and durable storage backends. This guide explains how to implement persistent user memory across agent sessions using the `MemoryFactory` pattern and PostgreSQL integration.

## Understanding the Memory Architecture

The memory system centers on the `MemoryFactory` singleton defined in [`aworld/memory/main.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/main.py). This factory manages the lifecycle of concrete `MemoryBase` implementations, caching instances in a module-level `MEMORY_HOLDER` dictionary to ensure global access to the same storage backend throughout the application lifecycle.

### The MemoryFactory Singleton Pattern

The `MemoryFactory` class implements a singleton pattern that guarantees a single source of truth for memory storage. When you call `MemoryFactory.init()` at lines 158-166 of [`aworld/memory/main.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/main.py), the factory registers your chosen storage implementation—either ephemeral or persistent—in the global `MEMORY_HOLDER` dict. Subsequent calls to `MemoryFactory.instance()` (lines 174-182) retrieve this cached instance, ensuring all agent components access the same memory store regardless of when or where they initialize.

### Storage Backends: Ephemeral vs Persistent

The repository provides two primary storage implementations:

- **`InMemoryMemoryStore`** (lines 55-79 of [`aworld/memory/main.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/main.py)): Stores items in a Python list that disappears when the process terminates. Ideal for testing and stateless deployments.
- **`PostgresMemoryStore`** (lines 224-229 of [`aworld/memory/db/postgres.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/db/postgres.py)): Persists memory items to PostgreSQL using SQLAlchemy models (`MemoryItemModel` and `MemoryHistoryModel`), writing to the `aworld_memory_items` table.

## Configuring Persistent Storage with PostgreSQL

To achieve durability across agent sessions, you must configure the `PostgresMemoryStore` and bind it to the factory.

### Setting up PostgresMemoryStore

The `PostgresMemoryStore` class requires a database connection string and uses SQLAlchemy ORM models to manage data persistence. According to the source code in [`aworld/memory/db/postgres.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/db/postgres.py), this store handles serialization of `MemoryItem` objects to relational rows, ensuring your user data survives process restarts and system reboots.

### The MemoryConfig Object

The `MemoryConfig` class (defined in [`aworld/memory/models.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/models.py)) encapsulates configuration settings including the provider type (`"aworld"`, `"mem0"`, or custom), embedding model settings, and vector store configurations. When initializing persistent storage, you instantiate this config alongside your concrete store implementation.

## Initializing the Memory Factory

The initialization process follows a strict three-step pattern to ensure the singleton is properly configured before any agent logic executes.

First, create your concrete store and configuration:

```python
from aworld.memory.main import MemoryFactory, MemoryConfig
from aworld.memory.db.postgres import PostgresMemoryStore

# Configure PostgreSQL connection

postgres_store = PostgresMemoryStore(
    db_url="postgresql://user:pwd@host/db"
)

config = MemoryConfig(
    provider="aworld",
    embedding_config=...,          # Your embedding model

    vector_store_config=...,       # Vector DB (e.g., FAISS, Milvus)

)

```

Second, initialize the factory with your custom store:

```python

# Register the persistent store in the global singleton

MemoryFactory.init(
    custom_memory_store=postgres_store, 
    config=config
)

```

Third, retrieve the instance anywhere in your codebase:

```python
memory = MemoryFactory.instance()  # Returns the same PostgresMemoryStore

```

## Accessing and Manipulating User Memory

Once initialized, agents interact with memory through the uniform `MemoryBase` API, agnostic of the underlying storage mechanism.

### The MemoryBase API

Both storage implementations expose methods defined in `MemoryBase`: `add()`, `get()`, `get_all()`, `delete()`, and `history()`. This abstraction allows you to switch between in-memory and persistent storage without modifying agent code.

### Cross-Session Memory Retrieval

To maintain continuity, agents store user-specific data with metadata identifiers, then retrieve them in subsequent sessions:

```python
from aworld.memory.models import MemoryHumanMessage, MessageMetadata

# Store user preference in session 1

memory.add(
    MemoryHumanMessage(
        content="My favorite color is blue",
        metadata=MessageMetadata(
            user_id="user_123", 
            session_id="sess_001"
        )
    )
)

# Retrieve in session 2 (different process/instance)

memory = MemoryFactory.instance()  # Same PostgreSQL store

prev = memory.get_first(
    filters={"user_id": "user_123"}
)
print(prev.content)  # Output: "My favorite color is blue"

```

## Implementation in Agent Workflows

Real-world agents in the repository access this memory system through the factory pattern. In [`aworld/agents/llm_agent.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/agents/llm_agent.py), agents call `MemoryFactory.instance()` to read historical context and write new observations, ensuring user context persists across multiple interaction cycles.

The pattern guarantees that when an agent finishes a session, the serialized memory state remains in PostgreSQL. When the next session begins, `MemoryFactory.instance()` reconnects to the same database, retrieves the prior snapshot, and restores the conversation context.

## Summary

- **Use `MemoryFactory`** as the central singleton to manage memory store lifecycle across your application.
- **Choose `PostgresMemoryStore`** (defined in [`aworld/memory/db/postgres.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/db/postgres.py)) for durability, or `InMemoryMemoryStore` for ephemeral testing.
- **Initialize once** using `MemoryFactory.init()` with a `MemoryConfig` and custom store, then access globally via `MemoryFactory.instance()`.
- **Leverage the `MemoryBase` API** (`add`, `get`, `get_all`) to remain storage-agnostic in your agent logic.
- **Persist across sessions** by storing user data with identifiers (`user_id`, `session_id`) and retrieving via filters in subsequent agent instantiations.

## Frequently Asked Questions

### What is the difference between InMemoryMemoryStore and PostgresMemoryStore?

The `InMemoryMemoryStore` (lines 55-79 of [`aworld/memory/main.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/main.py)) maintains items in a Python list that is destroyed when the process exits, making it suitable for testing or single-session deployments. The `PostgresMemoryStore` (lines 224-229 of [`aworld/memory/db/postgres.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/db/postgres.py)) uses SQLAlchemy models to write memory items to a PostgreSQL database, ensuring data survives process restarts and enabling cross-session persistence for production agents.

### How does MemoryFactory ensure the same store instance is returned across different parts of the code?

`MemoryFactory` implements a singleton pattern that caches the initialized store in a module-level `MEMORY_HOLDER` dictionary. When you call `MemoryFactory.init()` (lines 158-166), it stores the instance globally. All subsequent calls to `MemoryFactory.instance()` (lines 174-182) retrieve this cached object, guaranteeing that every component—from agents to middleware—accesses the same underlying storage connection.

### Can I use a different database backend instead of PostgreSQL?

Yes. While the repository provides `PostgresMemoryStore` as the reference persistent implementation in [`aworld/memory/db/postgres.py`](https://github.com/bojieli/ai-agent-book/blob/main/aworld/memory/db/postgres.py), you can implement the `MemoryBase` abstract class to create custom backends for MongoDB, Redis, or other databases. Pass your custom implementation to `MemoryFactory.init(custom_memory_store=your_store)` to integrate alternative storage solutions.

### How do I migrate from in-memory storage to persistent storage in existing agents?

Migration requires changing the initialization call from using the default in-memory store to explicitly providing a `PostgresMemoryStore`. Update your bootstrap code to instantiate `PostgresMemoryStore` with your database URL, pass it to `MemoryFactory.init()`, and ensure your `MemoryConfig` specifies the appropriate provider. No changes are required to agent logic since both stores implement the same `MemoryBase` interface.