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

# Long-term memory

Long-term memory persists important information across sessions and over time — user preferences, task history, key facts, or long-lived state. Short-term memory only lives within a single session; long-term memory lets an agent remember facts **across different sessions**.

Why you need it:

* Continuous conversation experience across sessions;
* Retain learnings and user-specific information over many interactions;
* Avoid repetitive questions, improving satisfaction and efficiency;
* Support long-term strategy optimization such as personalization or task tracking.

## Single entry point: `LongTermMemory`

Whatever backend you use, you interact with `veadk.memory.long_term_memory.LongTermMemory`. It plugs directly into an agent as its memory service and selects the storage backend through `backend`.

```python lines theme={null}
from veadk.memory.long_term_memory import LongTermMemory

ltm = LongTermMemory(backend="viking", app_name="ltm_demo")
```

### Parameters

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `backend` | `"local" \| "opensearch" \| "redis" \| "viking" \| "mem0"` | `"opensearch"` | Selects the backend. `viking_mem` is deprecated and maps to `viking`. |
| `backend_config` | `dict` | `{}` | Backend-specific settings. If `index` is absent, VeADK fills it from `index` or `app_name`. |
| `top_k` | `int` | `5` | Number of most-similar chunks to retrieve. |
| `index` | `str` | `""` | Index/collection name for storing memories. Falls back to `app_name`, then `default_app`. |
| `app_name` | `str` | `""` | The owning application name; used for data isolation and as the `index` fallback. |
| `user_id` | `str` | `""` | **Deprecated**, kept only for backward compatibility. |

<Note>
  Vector backends (`local`, `opensearch`, `redis`) embed memories, which requires `pip install "veadk-python[extensions]"` and an embedding model (env prefix `MODEL_EMBEDDING_`, falling back to `MODEL_AGENT_API_KEY`). `viking` and `mem0` are managed services and need no local embedding.
</Note>

## Choosing a backend

Use `local` for debugging; prefer `viking` or `mem0` in production.

| Backend | Storage | Requires | Use case | Docs |
| :- | :- | :- | :- | :- |
| `local` | In-memory vector index | `extensions` + embedding | Local debugging | [In-memory](/productions/veadk/archives/1.0.2/en/components/memory/local) |
| `viking` | VikingDB memory (managed) | Volcengine account | Recommended for production | [VikingDB](/productions/veadk/archives/1.0.2/en/components/memory/vikingdb) |
| `mem0` | Mem0 memory (managed) | Mem0 API key | Recommended for production | [Mem0](/productions/veadk/archives/1.0.2/en/components/memory/mem0) |
| `opensearch` | OpenSearch vector store | OpenSearch + embedding | Self-hosted vector search | [OpenSearch](/productions/veadk/archives/1.0.2/en/components/memory/opensearch) |
| `redis` | Redis vector store | Redis (RediSearch) + embedding | Self-hosted vector search | [Redis](/productions/veadk/archives/1.0.2/en/components/memory/redis) |

## Binding to an Agent

Passing `long_term_memory` to an `Agent` **auto-injects the `load_memory` tool** so the agent can retrieve past sessions at run time.

```python lines theme={null}
from veadk import Agent, Runner
from veadk.memory.long_term_memory import LongTermMemory

APP_NAME = "ltm_demo"
ltm = LongTermMemory(backend="viking", app_name=APP_NAME)

root_agent = Agent(
    name="ltm_agent",
    instruction="Answer the user. If the answer might be in past conversations, use the `load_memory` tool.",
    long_term_memory=ltm,
)
runner = Runner(agent=root_agent, app_name=APP_NAME)
```

## Managing memory

### Write: `add_session_to_memory`

When a session ends or hits a checkpoint, call the async `add_session_to_memory` to persist it. `LongTermMemory` first filters events (keeping user text events to improve retrieval quality), then hands them to the backend.

```python lines theme={null}
completed_session = await runner.session_service.get_session(
    app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID
)
await ltm.add_session_to_memory(completed_session)
```

### Retrieve: `search_memory`

Besides the agent's automatic retrieval via `load_memory`, you can call the async `search_memory` directly for semantic search — useful for debugging or custom RAG:

```python lines theme={null}
response = await ltm.search_memory(
    app_name=APP_NAME,
    user_id=USER_ID,
    query="favorite project",
)
print(response.memories)
```

<Note>
  `get_user_profile(user_id)` is supported only by the `viking` backend; others return an empty string.
</Note>

## Auto-save sessions

Set `auto_save_session=True` on the `Agent` with long-term memory configured, and VeADK persists sessions automatically — no manual `add_session_to_memory`.

```python lines theme={null}
from veadk import Agent
from veadk.memory.long_term_memory import LongTermMemory

agent = Agent(
    name="ltm_agent",
    auto_save_session=True,
    long_term_memory=LongTermMemory(backend="viking", app_name="ltm_demo"),
)
```

To avoid frequent index re-initialization, VeADK exposes `MIN_MESSAGES_THRESHOLD` and `MIN_TIME_THRESHOLD` env vars to tune the save cadence: by default it saves after 10 accumulated events or a 60-second interval; additionally, when you switch `session_id` and start a new turn, VeADK saves the previous session to long-term memory.

## Cross-session example

An end-to-end flow: session #1 tells the agent a fact and auto-archives it, then a **brand-new** session #2 asks a question — and the agent recalls the fact via memory retrieval (not the context window). This uses the `local` backend, which needs `pip install "veadk-python[extensions]"`.

```python lines theme={null}
import asyncio

from veadk import Agent, Runner
from veadk.memory.long_term_memory import LongTermMemory

APP_NAME = "ltm_demo"
USER_ID = "user-42"


def build_runner() -> Runner:
    ltm = LongTermMemory(backend="local", app_name=APP_NAME)
    agent = Agent(
        name="ltm_agent",
        instruction=(
            "You are a personal assistant. When the user asks about something they "
            "told you earlier, use the `load_memory` tool to recall it."
        ),
        long_term_memory=ltm,
        auto_save_session=True,
    )
    return Runner(agent=agent, app_name=APP_NAME, user_id=USER_ID)


async def main() -> None:
    runner = build_runner()

    print(
        "Session 1 ->",
        await runner.run(
            messages="Note this: I'm allergic to peanuts and I'm vegetarian.",
            session_id="session-1",
        ),
    )

    print(
        "Session 2 ->",
        await runner.run(
            messages="Recommend a dish for me, considering my dietary restrictions.",
            session_id="session-2",
        ),
    )


if __name__ == "__main__":
    asyncio.run(main())
```

In session #2 the agent recognizes the same user's preferences left in session #1 and answers coherently and personally (e.g. a peanut-free vegetarian dish).
