> ## Documentation Index
> Fetch the complete documentation index at: https://docs.maximem.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Letta (MemGPT) to Synap

> Looking for a Letta / MemGPT alternative? Map Letta's agent-coupled core and archival memory onto Synap: concept mapping, SDK call equivalents, and the re-architecture involved.

You're using Letta (formerly MemGPT) and want to evaluate or move to Synap. This page covers how Letta stores memory, how its concepts map onto Synap, and why this migration is a re-architecture rather than a drop-in.

<Note>
  This page is the Letta-specific mapping. For the method every migration shares — scope mapping, configuring your instance, pilot, verify, cut over — see [How migration works](/migrations/how-it-works).
</Note>

## How Letta stores memory

Letta tightly couples memory and agent runtime: agents have `core_memory` (small, always-in-prompt), `archival_memory` (large, retrieval-only), and recall memory. It's a single-process agent state model, not a multi-tenant memory service.

<Note>
  Letta was renamed from MemGPT and its SDK surface has evolved (e.g., `client.agents.archival_memory.create(...)`-style methods in current versions). The names below describe the conceptual mapping. Check your installed Letta SDK version for exact call signatures.
</Note>

## The mapping

| Letta concept                           | Synap concept                                                                                                                                                                  |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `agent.core_memory`                     | Build it from `sdk.user.context.fetch` results at every turn: it's not stored in Synap, it's assembled at retrieval time. Use `get_context_for_prompt` for the cached version. |
| `agent.archival_memory.insert(text)`    | `sdk.memories.create(document=text, document_type="document", user_id=..., customer_id=...)`                                                                                   |
| `agent.archival_memory.search(query)`   | `sdk.user.context.fetch(user_id=..., search_query=[query], types=[ContextType.FACTS])` (import `ContextType` from `maximem_synap.models.enums`, or pass the string `"facts"`)  |
| `agent.recall_memory` (last N messages) | `sdk.conversation.record_message` + `get_context_for_prompt` (returns recent + compacted)                                                                                      |
| Per-agent state                         | Per-user + per-conversation state: Letta's "one agent" maps to Synap's `(user_id, conversation_id)` pair                                                                       |

## The bigger shift

Letta wants you to think in terms of "one persistent agent per user." Synap is provider-agnostic: the LLM provider doesn't matter; Synap is just memory. Migrating means:

1. Splitting agent state from memory: keep agent logic in your app code; move memory to Synap.
2. Replacing Letta's runtime with whichever LLM SDK you actually want (OpenAI, Anthropic, etc.).
3. Re-modeling `core_memory` as a prompt template populated from `ContextResponse` at every turn.

This is a re-architecture, not a drop-in. The win is that your agent loop becomes portable across LLM providers.

## Next

Once you've split memory out of the agent, follow the shared [migration method](/migrations/how-it-works) to map scopes, backfill archival memory, pilot one user, verify, and cut over.
