How I Built a Zero-Cost Memory System That Actually Works for AI Agents
A complete iteration log: from "forgets everything after each chat" to structured persistent memory. Built on a real OpenClaw multi-agent production environment over 17 days.
Why Agents Need a Memory System
AI agents have one fatal flaw: they don't actually remember anything.
Every conversation runs inside a context window. It looks like memory, but it gets compressed, it degrades, and it resets on restart. You spend a whole day with your agent — making decisions, setting preferences, tracking progress — and the next morning it's gone. All of it.
Worse, the agent doesn't know what it forgot. It'll confidently repeat the same suggestions, make the same mistakes, ask you questions you already answered.
There's only one fix: write memory to files.
Anything you don't write to a file = something you never knew.
That's the first law I learned after 17 days of real-world use.
Architecture: Three Memory Layers + Three Retrieval Layers
Three Memory Layers
- Workbench:
NOW.md— current status board, refreshed every heartbeat - Journal:
memory/YYYY-MM-DD.md— daily event log, appended in real time - Long-term wisdom:
MEMORY.md— cross-day lessons, updated rarely
Key rule: never mix them.
NOW.mdholds only factual state (who's doing what, what's blocked) — no lessons- The journal holds everything in detail (decisions, completions, mistakes) — it's the most complete source
MEMORY.mdholds only genuinely universal wisdom — updated at most once a day
Three Retrieval Layers
When an agent needs to recall something:
L1: INDEX.md (directory scan, ~1 sec)
↓ not found
L2: directory + grep (file-level search, ~3 sec)
↓ not found
L3: semantic search (full-text, ~5 sec)
Most queries hit at L1. INDEX.md is the entry point for the whole system.
V1: The Naive Approach (Days 1–10)
The original setup was simple:
MEMORY.md — all long-term memory
NOW.md — current state
memory/
2026-01-29.md
2026-01-30.md
...
Problems
MEMORY.mdkept growing (43 lessons crammed into one file), slow to read- Journal was a raw stream — finding a specific decision meant scanning days of logs
- No categorization — investment lessons mixed with cron scheduling lessons
- Writes were unreliable: the Edit tool's exact-match logic silently dropped appended content
V2: Structured Memory (Days 11–15)
The Counterintuitive Finding
After studying the ClawVault project, I found something surprising:
Plain Markdown files had 74% memory accuracy — higher than purpose-built vector databases at 68.5%.
Why? Structured Markdown is naturally LLM-friendly. No embedding step, no retrieval pipeline, no extra moving parts.
The Restructure: Add Index, Add Types
memory/
INDEX.md ← master index (first file agent reads on startup)
YYYY-MM-DD.md ← daily journal (unchanged)
decisions/ ← decision records (with frontmatter)
lessons/ ← lessons learned (organized by topic)
people/ ← person profiles
projects/ ← project records
preferences/ ← preference settings
Decision Record Template
Every decision file gets YAML frontmatter:
---
date: 2026-02-08
type: decision
status: active
tags: [community, monetization]
---
# Build community before monetizing
## Context
Considered launching a paid course, but the community hadn't built enough trust yet.
## Decision
Grow the community first, build trust, then push the paid course.
## Alternatives Considered
- Launch paid bootcamp directly → rejected (no trust base, low conversion)
How to Organize Lessons
Not by date — by topic. All lessons on the same topic go into the same file:
# Cron Scheduling Rules
## US Market Timezone Alignment (2026-02-13)
Beijing time maps to US trading days Tue–Sat. Set cron to `2-6`.
## Write vs Edit Trap (2026-02-13)
Isolated cron sessions tend to use Write and overwrite entire files.
All memory/ writes must use printf >> to append.
The Write Mechanism: printf >> Is All You Need
printf '\n### 14:30 — Memory system docs complete\n\n- Finished full iteration doc for memory system\n' >> memory/2026-02-15.md
Why printf >>?
>>appends — it never overwritesprintfis more reliable thanecho(handles special characters)- No dependency on any tool's exact-match logic
- Creates the file automatically if it doesn't exist
Consolidating Into the Heartbeat Skill
Wrap all memory write logic into a Skill, executed by the main session on every heartbeat:
Heartbeat fires (every 1 hour)
↓
Phase 1: Memory writes
1.1 Scan conversation context → find decisions/completions/lessons/preference changes
1.2 Append to daily log (printf >>)
1.3 Route to decisions/ or lessons/ if applicable
1.4 Update INDEX.md (only when new files are created)
1.5 Refresh NOW.md (every time)
↓
Phase 2: External scan + flywheel check
Why consolidate? Saves $2–3/day, and write quality is higher — the heartbeat runs in the main session where it can see the full conversation.
Backup: Three Layers of Protection
# Runs automatically at 23:00 every night
cd memory && git add -A && git commit -m "backup: $(date +%Y-%m-%d)" && git push
- Local files (real-time)
- Obsidian Sync (real-time sync to phone)
- Private GitHub repo (nightly backup with version history)
The entire memory/ directory is an Obsidian vault. Install Obsidian + Sync on your phone and you can browse your agent's memory anytime.
Anti-Patterns
❌ Don't
- Use Edit to append to memory/ files
- Use Write to overwrite existing files
- Write filler like "system idle, no changes"
- Create a new file for every lesson
- Put lessons in NOW.md
- Put daily records in MEMORY.md
✅ Do
- Use
exec printf >> - Only use Write when the file doesn't exist yet
- Skip writing if there's nothing worth recording
- Append to existing topic files
- Keep entries 3–10 lines: specific but not bloated
Summary: For Anyone Building an Agent Memory System
- Files are memory. Don't overcomplicate it — Markdown files are more reliable than vector databases
- Three-layer separation. Workbench (NOW), journal (daily), wisdom (MEMORY) — never mix them
- Organize lessons by topic, not by date. All investment lessons in one file beats hunting through 30 days of journals
- Write mechanism matters more than write content.
printf >>will never corrupt your data - Merge overlapping systems. A separate checkpoint cron + heartbeat doing the same thing wastes money and accuracy — consolidate
- INDEX.md is the key. One file to navigate the entire memory library on startup
Stack: OpenClaw + Markdown + Git + Obsidian Cost: Near zero (Gemini Flash heartbeat + free private GitHub repo) Result: Agent maintains consistency across sessions, days, and context compactions