Markdown vs. Graph Database Memory for AI Agents: The Case for Files
A few days ago I came across OpenLobster — a fork of OpenClaw that rewrites the backend in Go, adds real multi-user support, fixes a fairly embarrassing security posture, and, most interestingly, replaces MEMORY.md with Neo4j.
The README has a line that stuck with me:
“MEMORY.md and a folder of markdown files is not a memory system, it’s a wiki.”
They’re not wrong. And since soul.py is built entirely on that “wiki” approach, it’s worth engaging with the argument seriously.
What OpenLobster is actually building
OpenLobster is a sophisticated piece of work. The critiques of OpenClaw’s architecture are largely fair:
- MEMORY.md as a concurrent write target — if multiple sessions try to update it simultaneously, you get conflicts. OpenClaw’s docs literally listed “only the main session writes to MEMORY.md” as a feature. That’s a design constraint dressed up as documentation.
- The HEARTBEAT.md scheduler — a daemon that wakes up every 30 minutes and reads a checklist file is not a scheduler. It’s a polling loop with extra steps.
- 40,000 exposed instances on Censys — OpenClaw shipped with authentication disabled by default. The security community found it fast.
- Multi-user was an afterthought — one flat memory file, one main session, no concept of per-user history or permissions.
OpenLobster’s solutions are all reasonable: Neo4j for relational memory, Go for a single deployable binary, real cron for scheduling, auth on by default, secrets in OpenBao. If you’re building a multi-user AI assistant for a team, this is the right direction.
The case for files
But OpenLobster is solving a different problem than soul.py.
The “wiki” critique assumes that the goal is to build a self-hosted AI server that handles multiple users, manages complex relationships between entities, and runs as persistent infrastructure. For that use case, yes — a graph database is better.
soul.py’s premise is different: agent memory should be portable, private, and require nothing to run.
Here’s what that means in practice:
1. Zero infrastructure
pip install soul-agent
soul init
That’s it. No database to install, configure, secure, back up, or migrate. The memory lives in two text files. You can move them with cp. You can back them up with git push. You can read them with any text editor.
OpenLobster requires running Neo4j — either locally (Docker, 512MB minimum RAM) or managed (AuraDB, $0 on free tier but with limits). That’s a non-trivial dependency for a personal agent.
2. Git as the storage layer
soul.py’s memory files are designed to live in a private Git repo. That gives you:
- Version history — see every change to your memory, diff between dates, roll back
- Portability — move between any Git host without touching the data
- Privacy — a private GitHub repo is not a third-party database. Your memories are yours.
- Auditability — every commit shows what the agent added and when
SoulSearch, our new browser extension, is built entirely on this model: your SOUL.md and MEMORY.md live in a private repo on whatever host you choose — GitHub, GitLab, Gitea, a Raspberry Pi. Neo4j memory can’t do that cleanly.
3. Human readability
A MEMORY.md file looks like this:
## About Prahlad
- PhD, Carnegie Mellon (Biomedical Engineering)
- Working on soul.py, SoulSearch, AATS AI tools
## Research this week
- KEYNOTE-942 trial data for mRNA-4157
- OpenLobster's Neo4j memory architecture
You can read it, edit it, restructure it, delete entries you don’t want. The agent’s memory is transparent and controllable.
A Neo4j graph requires Cypher queries to inspect, a running database to access, and a UI to browse. It’s more powerful — but it’s also opaque in a way that matters for trust and privacy.
4. Embeddability
soul.py is a Python library that runs inside your application. You can embed it in a browser extension (SoulSearch), a Slack bot, a mobile app, or a CLI tool. The memory is just files — they go wherever your app goes.
Neo4j is an external service. You connect to it. That’s fine for server infrastructure, but it’s not portable.
Where the graph wins
None of this means graph databases are wrong for agent memory. They’re better in specific situations:
Multi-user deployments. If 50 people are talking to the same agent, you need per-user isolation, proper concurrency handling, and relationship queries across users. Markdown falls apart here. A graph database with typed nodes per user is the right call.
Complex relationship modeling. “What do I know about Prahlad’s connections to people at Bayer?” is a multi-hop graph traversal. You can approximate it in markdown but it gets messy fast. Neo4j handles it cleanly.
Structured knowledge bases. If the agent is building a knowledge graph of entities and relationships from documents, a graph database is the natural fit. Extracting triples from text and storing them as nodes/edges is what graph databases were built for.
Enterprise/team agents. OpenLobster’s multi-user model, per-user permissions, and proper secrets management make it the right foundation for an organization deploying AI assistants at scale.
The architectural choice is the product
The more I think about it, the more I think this isn’t a debate with a right answer — it’s a design choice that reflects what you’re building.
OpenLobster is building infrastructure — a self-hosted AI assistant platform that organizations can deploy. The graph database, Go backend, and multi-user model are all correct choices for that use case.
soul.py is building a memory primitive — a portable, private, zero-dependency layer that makes any AI agent persistent. The markdown files, Git integration, and SoulSearch browser extension are all correct choices for that use case.
The “wiki” critique is fair if your goal is enterprise deployment. It misses the point if your goal is personal, portable, privacy-preserving memory.
What’s next
soul.py v2.0 already has RAG (vector search over memory) and RLM (full synthesis across all memory) via the SoulMate API. The roadmap includes structured memory schemas and optional SQLite backing for users who want something between flat files and a full graph database.
OpenLobster’s Neo4j integration is worth watching closely. If they add a Cypher-to-natural-language query layer on top, the gap between “a wiki” and “a proper memory system” closes considerably. Competition here is good.
For personal agents, browser extensions, and anything where you want your memory to be yours: soul.py — pip install soul-agent.
For multi-user deployments where you need real relationship modeling: OpenLobster is doing serious work.
Both beat MEMORY.md with auth disabled and 40,000 exposed instances on Censys.
Related: SoulSearch — AI Browser Extension with Private Git Memory · soul.py v2.0 — RAG+RLM Hybrid Memory · soul.py vs MeMU — Agent Memory Compared