Hermes Agent memory: budgets, limits, and what to keep out
Aperisa ยท 8 min read
When a Hermes agent's memory is full, the next write fails. The agent then has to decide, in the same turn, what to forget.
Hermes Agent memory is two capped files that load into the system prompt at session start: MEMORY.md at 2,200 characters and USER.md at 1,375. Around them sit a full-text search over past sessions and an optional external provider. The caps are small on purpose, and they make one thing clear. Memory is for how your agent works. Facts from your contracts, invoices and inbox belong in a record the agent looks up, with the source attached.
How does the Hermes Agent memory system work?
Per the Hermes memory docs, both files live in ~/.hermes/memories/:
- MEMORY.md holds the agent's own notes: environment facts, conventions, things it learned. 2,200 characters, about 800 tokens.
- USER.md holds your profile: preferences, communication style. 1,375 characters, about 500 tokens.
The agent writes through the memory tool. It has three actions: add, patch and remove. There's no read action, because the contents are already in the prompt. Every call needs a top-level target of "memory" or "user", and patch and remove match on a short unique substring in old_text. If that substring matches more than one entry, the call fails and asks for something more specific.
Two details we like. The old replace action is gone, because it wiped other facts in multi-fact entries, and it now returns an error that points to patch. And entries are scanned for prompt injection and credential exfiltration patterns before they're accepted. Exact duplicates are dropped with a "no duplicate added" message.
The settings live in ~/.hermes/config.yaml:
memory:
memory_enabled: true
user_profile_enabled: true
memory_char_limit: 2200
user_char_limit: 1375
Set both *_enabled keys to false and the memory tool disappears entirely.
What fits in 2,200 characters?
Less than you'd think, and more than you need if you're strict. Here are four made-up MEMORY.md entries of the kind a coding agent keeps:
Repo lives at ~/src/orchestra. Use pnpm, not npm.
Deploys go through make ship. Never push to main.
Morning digest goes to Telegram at 07:30, under 10 lines.
Run tests with pnpm test. The e2e/webhooks suite is flaky; retry once.
That's 225 characters, about a tenth of the budget. At that density you get roughly 30 entries before you hit 80%, the point where the docs tell the agent to consolidate. USER.md fits a bit more than half as many.
You can raise both limits. Just remember what the number buys. Every character in these files is injected into the system prompt of every session, whether the task needs it or not. A 10,000-character MEMORY.md is a 10,000-character tax on each session your always-on agent starts.
The docs also list what to skip: facts the agent can rediscover with a search, session-specific ephemera like temp paths and one-off debugging context, and raw data dumps such as logs and tables. That list is a good filter. If an entry would go stale without anyone telling the agent, it probably doesn't belong here either.
What happens when Hermes Agent memory is full?
Hermes doesn't compact memory for you. An add that would cross the limit returns success: false with an error that shows current usage (the docs' example reads "Memory at 2,100/2,200 chars"), how far over the new entry would go, and the existing entries.
The agent then frees space itself, in the same turn, by removing or shortening entries in one batch before retrying. The limit is checked against the batch result. A patch that lengthens an entry can overflow too.
In practice this means your agent is editing its own long-term memory mid-task, often while you're talking to it over Telegram or Slack and not watching the tool calls. Three habits help:
- Check the usage percentage in the memory header of the system prompt. The docs say to consolidate above 80%, before the write fails.
- Keep entries short and single-fact. Merging is easier, and a
patchwon't clobber a neighbor. - Read ~/.hermes/memories/MEMORY.md yourself now and then. It's a plain file. You'll see what the agent chose to keep and what it dropped.
Why don't memory edits show up until the next session?
The memory block is a frozen snapshot. The docs say the injection "is captured once at session start and never changes mid-session," and that this is intentional, to preserve the model's prefix cache.
Writes still hit disk immediately, and tool responses show the live state. But the agent's system prompt keeps the version from session start. For a short CLI session that barely matters. For an always-on agent with a long-running session, the copy in its prompt can be hours or days older than the file on disk. If you correct a fact through memory, don't expect the prompt to reflect it until the next session starts.
How does Hermes session search fit in?
Session search is the other half of Hermes Agent memory management. All CLI and messaging sessions are stored in SQLite at ~/.hermes/state.db and indexed with FTS5. The session_search tool returns stored messages directly, with no model summarizing or truncating them, and it can scroll forward or back inside a session it found. hermes sessions list lets you browse them yourself.
This is a good split. MEMORY.md holds the few things the agent needs every time. Session search holds everything that was said, retrievable on demand. Neither one holds what was never said in a session.
Running more than one Hermes agent
If you run several agents, give each its own profile. The docs are blunt: "Don't point two agent processes at the same Hermes home directory," because "two writers sharing one home will compound each other's entries into state neither of them (nor you) authored."
Per the Hermes profiles docs, a profile is a separate Hermes home with its own config, API keys, memory, sessions and skills. hermes profile create coder creates one under ~/.hermes/profiles/, and it becomes its own command (coder chat).
That isolation is right for memory. It also means each agent learns its own version of things. We cover what that does to a multi-agent setup in context layers for multi-agent loops.
Why business facts don't belong in MEMORY.md
Look at what feeds each part. MEMORY.md and USER.md hold what the agent chose to write. Session search holds what was said. Both start from the chat. Most business facts never pass through it. The payment terms are on page four of a signed agreement in Drive. The new start date is in a calendar invite.
Here's how that goes wrong, with made-up data. Three weeks ago you told the agent the Larkspur retainer is "about $4,000 a month." It saved a 53-character entry. Since then a signed change order raised it to $4,600, by email, and the agent was never told. You ask for next month's invoice and get $4,000.
Memory did its job. It remembered what you said. What you said wasn't the record, and the entry has no source to check it against.
The fix is a tool, not a bigger file. Hermes reads MCP servers from the same config.yaml, under mcp_servers, per the Hermes MCP docs. A remote server takes a url and optional headers, and you can allowlist tools so a source of facts only exposes reads. With a made-up server:
mcp_servers:
records:
url: "https://records.example.com/mcp"
tools:
include: [search_records, get_document]
The tools register as mcp_records_search_records and so on, and /reload-mcp picks up changes inside a session. Then add one line to MEMORY.md, which is exactly what memory is for: "Amounts, dates and terms: look them up with mcp_records, cite the document."
For the provider side of this, see Hermes Agent memory providers.
Where does Aperisa fit?
Aperisa is one example of an outside record. It reads Gmail, Drive, Calendar and Contacts with read-only Google access, plus the bank accounts you link, and keeps a searchable copy to answer from. It maps those records into one structured record and serves it through a read-only remote MCP server with no send, write or delete tools. It looks up your records instead of asking a model to recall them, and answers come with the email or document they came from.
Keep memory small, and point it at the record
Hermes Agent memory works best the way it was designed: a short, strict list of how your agent should work, a searchable history of what was said, and nothing that will quietly go stale. Put the facts in a record your agent queries, and let the memory file hold the rule that says to use it.
Aperisa connects as a remote MCP server over Streamable HTTP with a Bearer key, and each key can be limited by data area and level of detail. Try it out.
FAQ
What happens when Hermes Agent memory is full? The write fails. Per the Hermes docs, an add that would pass the limit returns success false with an error showing current usage and the existing entries. The agent then has to remove or shorten entries in the same turn before it retries. Memory does not compact itself.
Can I raise the Hermes Agent memory limit? Yes. The limits are set in ~/.hermes/config.yaml as memory_char_limit (default 2200) and user_char_limit (default 1375). Every character you add is injected into the system prompt at the start of each session.
Why doesn't my Hermes agent see a memory edit it just made? The memory block is a frozen snapshot taken once at session start, to keep the model's prefix cache intact. Edits are saved to disk right away and appear in the system prompt from the next session. Tool responses show the live state.
Can two Hermes agents share one memory? The docs advise against it. Memory is scoped per profile, and two agent processes pointed at one Hermes home will write entries into each other's state. Give each agent its own profile with hermes profile create.
Sources
- Hermes Agent memory docs
- Hermes Agent profiles docs
- Hermes Agent MCP docs
- Hermes Agent memory providers docs
Questions
What happens when Hermes Agent memory is full?
The write fails. Per the Hermes docs, an add that would pass the limit returns success false with an error showing current usage and the existing entries. The agent then has to remove or shorten entries in the same turn before it retries. Memory does not compact itself.
Can I raise the Hermes Agent memory limit?
Yes. The limits are set in ~/.hermes/config.yaml as memory_char_limit (default 2200) and user_char_limit (default 1375). Every character you add is injected into the system prompt at the start of each session.
Why doesn't my Hermes agent see a memory edit it just made?
The memory block is a frozen snapshot taken once at session start, to keep the model's prefix cache intact. Edits are saved to disk right away and appear in the system prompt from the next session. Tool responses show the live state.
Can two Hermes agents share one memory?
The docs advise against it. Memory is scoped per profile, and two agent processes pointed at one Hermes home will write entries into each other's state. Give each agent its own profile with hermes profile create.
Published
Keep reading
- OpenClaw MCP setup: a remote server with a Bearer header
OpenClaw MCP setup for a remote server with a Bearer header: mcp.servers, not mcpServers or mcporter, an env-backed token, and 2026.6.5 or later.
- n8n MCP Client node: connect a remote MCP server, and fix a missing auth header
Set up the n8n MCP Client and MCP Client Tool nodes against a remote MCP server, and fix the missing Authorization header behind most 401s, step by step.
- Codex CLI and remote MCP servers: running unattended with a Bearer key
Connect Codex CLI 0.162 to a remote MCP server with a Bearer key in config.toml, then make codex exec call its tools unattended without turning off the sandbox.