On this page
Hermes Agent Postmortem: Why My Personal Agent Lives on a VPS
I run several coding agents every day. Hermes is different because its job is not to finish one coding task. Its job is to remember, schedule, and route the work that fills the rest of my day.
I run several coding agents every day. Planning, implementation, review, and frontend work each have a tool I trust.
Hermes is the odd one out. It writes less code than any of them, but it touches more of my day.
I installed Hermes Agent on a VPS because local-only workflows disappear when my Mac sleeps. The first useful version took a day to get right. The hard part was not installing the agent. It was deciding which jobs deserved autonomy and which ones still needed me in the loop.
That failure was useful. It forced me to stop thinking of Hermes as another coding agent and start thinking about it as a long-lived personal process. Claude Code helps me change a repository. Hermes helps me decide what deserves my attention, remember how I work, and hand the right task to the right tool.
That is the real difference. The model matters, but the lifecycle matters more.
The job I was missing
A coding agent is good at a bounded problem. Give Claude Code a repository, a bug, and a clear acceptance test. It can inspect files, run commands, use subagents, and edit the code. Its persistent knowledge comes from CLAUDE.md and auto memory loaded at session start.
That is a strong model for software work. It is not a model for a whole day.
My day contains open loops that do not belong to one repository: meeting follow-ups, design reviews, weekly reports, and coding work that needs to be handed to another specialist.
A coding agent can handle each task. I still have to open it, provide the context, and remember to ask.
Hermes changes the starting point. It runs a gateway, accepts messages from several surfaces, keeps sessions, runs scheduled jobs, searches past conversations, and loads skills when needed. The official documentation describes the gateway as one background process that connects platforms, handles sessions, runs cron jobs, and delivers messages.
%%{init: {"layout": "dagre"}}%%
flowchart LR
Events[Messages, schedules, files, commits] --> Hermes[Hermes gateway]
Hermes --> Memory[Memory and session search]
Hermes --> Skills[Skills and learned procedures]
Hermes --> Delegate[Delegated workers]
Delegate --> Tools[Claude Code, scripts, browsers, APIs]
Hermes --> Reply[Brief, draft, reminder, or decision]
The key insight: Hermes is not mainly a better prompt box. It is a process that stays present between prompts.
“An always-on agent should earn the right to interrupt me.”
Where to start: one boring workflow
Do not start by connecting every app you use. Start with one task that repeats at least twice a week and has a clear output.
| Start here | Input | Useful output |
|---|---|---|
| Meeting follow-up | Transcript, notes, decisions | Draft message plus owners and dates |
| Research digest | URLs, saved notes, open question | Source-linked summary with unanswered points |
| Coding handoff | Issue, screenshots, acceptance criteria | A context pack for Claude Code or Pi |
| Weekly review | Commits, shipped work, open loops | Short report of done, missed, and next |
| Inbox triage | New messages and task list | Grouped actions, not automatic replies |
My first useful workflow was not “run my life.” It was “turn this completed meeting into a follow-up draft.” The boundary was clear, the inputs were available, and I could review the result in under a minute.
Why this matters: a personal agent earns trust through small, reversible wins. If the first workflow sends an incorrect message or creates twenty reminders, you will disable the whole system before it learns anything useful.
Architecture: four loops, not one chatbot
I model Hermes as four loops connected by one gateway:
%%{init: {"layout": "dagre"}}%%
flowchart TB
subgraph Ingress["Ingress"]
Chat[Chat message]
Cron[Scheduled job]
Hook[External event]
end
Gateway[Gateway and session router]
Policy[Policy: should Hermes act?]
Memory[Bounded memory and session search]
Skill[On-demand or learned skill]
Executor[Tools, scripts, browsers, delegated agents]
Evidence[Sources, artifacts, run record]
Delivery[Draft, reminder, report, or handoff]
Chat --> Gateway
Cron --> Gateway
Hook --> Gateway
Gateway --> Policy
Policy --> Memory
Policy --> Skill
Memory --> Skill
Skill --> Executor
Executor --> Evidence
Evidence --> Delivery
Delivery --> Gateway
The gateway owns connections and sessions. The policy step decides whether an event deserves attention. Memory supplies durable facts or a search query. A skill supplies the procedure. Executors do the work. Evidence makes the result reviewable before delivery.
That last step is the part I would not skip. A personal agent needs to answer: what did you see, what did you change, and which parts still need my approval?
The implementation detail that matters in practice is the boundary between the gateway and the worker. Hermes’ gateway can run scheduled jobs and route messages, but the agent should not be responsible for keeping its own process alive. External service supervision, logs, and a health check belong outside the model loop.
I use a small conceptual event contract for new workflows:
event: meeting.completed
scope: work
action: draft_followup
requires_approval: true
evidence:
- transcript
- decisions
- action_items
This is not a Hermes config file. It is a design test. If I cannot name the event, the scope, the action, and the evidence, the workflow is not ready to automate.
Why this matters
Most agent demos end at the answer. Personal workflows do not. They need a durable record of the decision, a safe way to retry, and a human boundary around side effects. Without those three pieces, “always on” only means “always able to make the same mistake again.”
The interesting part is not “memory”
I have spent a lot of time studying memory systems. My short version is:
| System | My mental model | What it is best at |
|---|---|---|
| RAG | Searching historical records | Finding relevant documents or past text |
| Obsidian | Manually verified archives | Knowledge I chose to curate |
| Mem0 | A secretary sorting important facts | Extracting and updating user facts |
| Letta | An agent’s work notebook | State the agent edits during its life |
| GraphRAG | A relationship map | Connecting entities and concepts |
| Honcho | A long observation of a person | Building a model of user behavior |
| Hermes | A working memory plus a task history | Remembering me while doing recurring work |
This is my shorthand, not a formal taxonomy. For a deeper look at extraction, storage, and retrieval trade-offs, see my mem0 memory post. Hermes uses more than one memory pattern.
Hermes keeps two bounded stores in ~/.hermes/memories/: MEMORY.md for environment facts and learned conventions, and USER.md for preferences. The documented limits are 2,200 and 1,375 characters. That constraint is good. An unlimited memory file becomes a second prompt dump.
It also stores sessions in SQLite with FTS5 search:
Always relevant facts -> bounded memory at session start
Specific past details -> FTS5 search when needed
Reusable procedures -> skills loaded on demand
The memory documentation calls the first layer a frozen snapshot. If Hermes writes memory during a session, the prompt does not change until the next session. That protects the prompt cache and keeps the current turn stable.
Skills use progressive disclosure. Hermes sees a list first, then loads a procedure only when needed. It can also learn a skill from a source or a workflow I explained.
Why this works: facts, history, and procedures have different retrieval needs. Hermes does not treat all three as one vector index.
The best use cases are small and repetitive. I do not ask Hermes to invent a grand plan for my life. I give it jobs where remembering the pattern is worth more than writing another prompt.
In the morning, a scheduled brief can combine current work, open tasks, and yesterday’s unfinished items. During the day, I can message Hermes instead of opening a repository. It can summarize research, draft a follow-up, search an old decision, or prepare a handoff for a coding agent.
At the end of a work block, I want a record of what changed. A short update can become a PR description, a weekly note, or a reminder for tomorrow.
I also added oh-my-hermes. I treat it as an operating layer above Hermes, not a replacement. It adds workflows for planning, research, creation, coding handoffs, operations, and project memory with explicit evidence boundaries.
My model routing is deliberately boring:
| Work | Model choice |
|---|---|
| Sorting, summaries, routine replies | DeepSeek or another low-cost model |
| Research and harder reasoning | Claude |
| Repository changes | Claude Code through a handoff |
I left the expensive model on for routine work once and burned about $40 in an hour. It did not become four times more useful. It became four times more expensive.
Hermes versus Claude Code and OpenClaw
The usual comparisons are too shallow. They compare feature checklists when the useful question is: what owns the lifecycle?
| Dimension | Hermes Agent | Claude Code | OpenClaw |
|---|---|---|---|
| Center of gravity | Personal agent and learning loop | Repository and coding session | Gateway and channel connections |
| Default trigger | Message, schedule, skill, or task | User request inside a coding session | Message, event, automation, or connected client |
| Persistent state | Bounded memory, session search, skills | CLAUDE.md, auto memory, project context | Gateway sessions, workspace memory, plugins |
| Main output | Briefs, drafts, research, reminders, delegated work | Edits, commands, diffs, tests | Assistant replies and channel actions |
| Best fit | Repeated personal workflows that improve | Software changes with a clear repo boundary | One assistant reachable from many channels |
| Main failure mode | Noise, stale memory, wrong priorities | Wrong code or unsafe edits | Overexposed gateway, noisy channels, routing mistakes |
Claude Code has subagents and persistent memory. Calling it “just a one-shot terminal tool” would be wrong. Its center is still a coding session with a repository, permissions, and an implementation loop. That is why I use it for code.
For the worker-contract side of this design, I use the same questions from my omp subagent analysis: what can the worker return, can workers coordinate, and what evidence survives the handoff?
OpenClaw is closer to Hermes because both run continuously and connect messaging surfaces. Its Gateway documentation puts one long-lived gateway at the center. It owns provider connections, sessions, tools, events, and channel connections over a typed WebSocket API. Hermes also has a gateway, but its defining claim is the agent loop: memory, learned skills, session search, scheduling, and delegation.
My opinionated summary:
- Claude Code optimizes the coding loop.
- OpenClaw optimizes reach and routing.
- Hermes optimizes continuity and repeated work.
They overlap in features. They do not optimize the same bottleneck.
The failures were workflow failures
The first version was not defeated by a missing feature. It failed because I automated work before defining its boundary.
1. The morning brief became an inbox dump
I asked for a daily summary and got a neat list of everything that happened. It was accurate and useless. Five meetings, twelve messages, and three stale tasks did not tell me what to do first.
I changed the output to three decisions: what needs attention today, what can wait, and what I should decline. The brief became shorter and more useful.
summarization is not prioritization. An agent that repeats your inputs has not reduced your workload.
2. A retry created the same reminder twice
One scheduled task timed out after creating a reminder. Hermes retried, but the first request had succeeded. I ended up with two reminders for the same follow-up.
The fix was an idempotency key built from the event ID, action, and target date. A retry can now ask “did this action already happen?” before creating another side effect.
3. Memory preserved an old priority
I told Hermes that a project was urgent. Two weeks later, the project had moved down the list, but the memory still pushed it into summaries. The problem was not retrieval quality. The fact itself had expired.
Now I separate durable preferences from temporary priorities. A priority gets an owner, a review date, and a clear replacement path. Memory needs removal rules, not just an add function.
4. The coding handoff lost the important context
A research task ended with “ask Claude Code to implement this.” That sentence was not a handoff. It dropped the source links, screenshots, constraints, and acceptance criteria that made the research useful.
I now send a small context pack: the question, evidence, decisions, non-goals, and the exact definition of done. For larger parallel coding work, I still prefer a harness with explicit worker contracts. That is why omp’s typed subagent results matter in this layer.
5. Browser automation was the wrong first integration
I started one workflow by opening a browser because the website was easy to click by hand. The session expired, the login prompt changed, and the scheduled run failed without producing a useful artifact.
The replacement uses a direct API when one exists, with browser automation as a fallback. The run stores the source URL, response status, and output path. A workflow that cannot show what it saw is hard to trust.
6. “Send it” was not a safe default
Drafting a reply and sending a reply are different products. Early prompts blurred that line. The agent could produce a polished message, but polish is not permission.
My default is now draft-only for external communication, with explicit approval for sending, deleting, publishing, or changing a record. Silence is also a valid result. A good workflow may decide that nothing needs to be sent.
The pattern across all six failures is the same:
Event -> decision -> action -> evidence -> approval or delivery
I was skipping the decision and evidence steps. The agent looked autonomous, but the workflow was just a collection of optimistic prompts.
When to choose what
Choose Hermes if you:
- Repeat the same research, reporting, or operations tasks.
- Want one memory across CLI and messaging channels.
- Need schedules that keep running when your laptop is off.
- Want the agent to turn successful work into reusable skills.
- Are willing to operate a long-lived service.
Choose Claude Code if you:
- Need to change code in a repository.
- Care about diffs, tests, permissions, and code review.
- Want a focused implementation loop with optional subagents.
- Prefer to keep project context close to the project.
Choose OpenClaw if you:
- Want one gateway across many chat apps and device nodes.
- Care more about channel reach, routing, and plugins than learned procedure.
- Need a control plane for sessions and connected clients.
Choose Pi, omp, or a similar coding harness if you:
- Want a small, composable terminal workflow. My Pi workflow notes explain why less can be useful here.
- Prefer to choose the surrounding tools yourself.
- Need a coding layer underneath a personal orchestrator.
Letta, Mem0, GraphRAG, and Honcho are alternatives to parts of Hermes, not the whole system. They provide memory primitives or user modeling, not the same gateway, skills, schedules, terminal backends, and messaging.
The Bottom Line
Hermes did not replace my coding agents. It gave them a better entry point. Claude Code still owns repository changes. Hermes owns the space between tasks: what I forgot, what repeats, what needs a schedule, and what should be handed to another agent.
I would not install Hermes just to generate a README. I would install it for recurring work, several channels, an always-on machine, and the patience to supervise it properly.
The best personal agent remembers the right things, stays quiet when nothing matters, and sends the next task to the tool that can finish it.
Building a personal agent or running several coding agents? I would love to hear what failed first. Reach out on LinkedIn.