Skip to main content
A ready-to-run example is available here!
Persistent memory lets an agent keep what it learned — root causes, environment quirks, project decisions, user preferences — in plain Markdown files that are loaded back into the system prompt at the start of every new conversation. The agent maintains the files itself as it works, so it gets better at a project over time. The feature is opt-in and off by default: without it, agents keep the existing AGENTS.md-based guidance and prompts are unchanged.

Enabling Persistent Memory

Set load_memory=True on the agent’s AgentContext:
That single flag does two things:
  1. At session start, the conversation reads the MEMORY.md indexes from both memory tiers and injects them into the system prompt as a <MEMORY_CONTEXT> block.
  2. The system prompt’s <MEMORY> section switches to instructions that teach the agent where its memory lives and how to maintain it.

The Two Tiers

Each tier contains:
  • MEMORY.md — a curated index of durable facts. This is the only file injected into the prompt, so the agent is instructed to keep it small and high-value.
  • Daily logs (YYYY-MM-DD.md) — free-form working notes. They are never injected automatically; the agent reads them on demand with its file tools when MEMORY.md points to them.
The files are plain Markdown: you can review, edit, or delete them at any time, and a project team can even commit .openhands/memory/ to share agent-learned knowledge.

What Gets Injected

At the start of each opted-in conversation, the resolved memory appears in the system prompt like this (user tier first, then project tier):
A few properties worth knowing:
  • Size budget: the combined indexes are capped at ~6,000 characters. When the budget is exceeded, whole lines are dropped from the top of each over-budget tier (the oldest content) — partial lines never survive, the tier headers are always kept, and a truncation notice appears under the header of any tier that lost lines. Keep indexes curated.
  • Untrusted by design: the injected block is wrapped in <UNTRUSTED_CONTENT>. Memory files are typically agent-written, but anyone with access to the workspace or repository can edit or commit them (a cloned repo may ship a .openhands/memory/MEMORY.md), so the agent is told they may contain prompt injection, and to treat them as unverified hints, never as authoritative instructions.
  • Never persisted: the resolved memory text is re-read from disk each session and is excluded from conversation persistence (base_state.json) and API payloads.
  • Best-effort: an unreadable memory file logs a warning and the conversation starts normally without it.

How the Agent Maintains Memory

When memory is enabled, the system prompt instructs the agent to:
  • record durable, broadly useful facts in MEMORY.md near the end of a task (creating the directories and files if missing), and put long detail in daily logs;
  • merge duplicates, prune stale entries, and keep the indexes concise;
  • never record secrets or credentials, and skip facts that are trivially re-discoverable (directory listings, obvious commands);
  • keep AGENTS.md for instructions addressed to any agent working in the repository — memory is for what the agent learned itself.

Ready-to-run Example

This example is available on GitHub: examples/01_standalone_sdk/55_persistent_memory.py
examples/01_standalone_sdk/55_persistent_memory.py
You can run the example code as-is.
The model name should follow the LiteLLM convention: provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o). The LLM_API_KEY should be the API key for your chosen provider.
ChatGPT Plus/Pro subscribers: You can use LLM.subscription_login() to authenticate with your ChatGPT account and access Codex models without consuming API credits. See the LLM Subscriptions guide for details.

Next Steps

  • Skills - Inject reusable instructions and context into agents
  • Context Condenser - Keep long conversations within the context window
  • Persistence - Save and restore conversation state across sessions