If your MEMORY.md is over 15KB, your agent is silently losing the bottom of the file every single session. Same with HEARTBEAT.md. Bootstrap truncation cuts whatever doesn't fit, and it doesn't tell your agent what it missed.

I just hit this. MEMORY.md was 65KB — only the top 18KB was loading. That means 47KB of accumulated knowledge was invisible every session. HEARTBEAT.md was 22KB with the bottom 70 lines (scheduled tasks, monitoring checklists) getting cut every time. My agent was literally never seeing them.

The fix is simple and it works immediately.

The Pattern: Index + Topic Files

Turn your monolith file into a small dispatch index that points to topic files.

MEMORY.md becomes a ~3KB routing index:

```text Client backups: mysqldump→S3 via rclone, daily 8am UTC, SSH key prod-rsa → memory/client-ops.md SaaS app: AI-powered tool, $25/mo tier, 590 users, acquisition in progress → memory/saas-product.md Home server: i5-11320H 16GB Ubuntu 24.04, Tailscale, PM2 → memory/infrastructure.md ```

Each line is 200–300 chars with 2–3 keywords so memory_search knows when to pull the full topic file. The index loads every session with zero truncation. Topic files load on demand via memory_search.

Important: MEMORY.md and HEARTBEAT.md work differently here. MEMORY.md is passive context — your agent doesn't read it as instructions. The pointer lines exist for the benefit of memory_search, which automatically finds and retrieves the right topic file when your agent needs information. You don't need to tell your agent "go read memory/infrastructure.md" — the search system handles that.

HEARTBEAT.md is the opposite — your agent reads it as a checklist and executes it top to bottom. It's an instruction set. So when the agent hits a reference to a sub-file, it needs to be told explicitly what to do with it. This means the refs in HEARTBEAT.md must be executable instructions, not passive pointers.

HEARTBEAT.md becomes a ~8KB dispatch file:

Core agent logic stays inline (session rollover, checkpoint loop, WAL — the stuff that runs every heartbeat). Everything else becomes an executable ref:

```text Run sales check: read and execute heartbeat/sales.md Run NR health check: read and execute heartbeat/newrelic.md ```

If it just says "sales check → heartbeat/sales.md" your agent might note the reference and move on without actually opening the file. "Read and execute heartbeat/sales.md" is an instruction it will follow.

What the Directory Structure Looks Like

Before — everything in one file:

```text MEMORY.md ← 65KB monolith, bottom 70% truncated HEARTBEAT.md ← 22KB monolith, bottom 70 lines cut ```

After — lean index files pointing to topic directories:

```text MEMORY.md ← ~3KB routing index, loads fully every session memory/ client-ops.md ← backups, hosting, SSH, deployments saas-product.md ← product details, pricing, users, roadmap infrastructure.md ← servers, networking, Tailscale, PM2 finances.md ← income, rates, targets (no auto-expiry) projects.md ← side projects, SEO sites, experiments system.md ← agent setup, plugins, memory architecture people.md ← contacts, team, roles (no auto-expiry)

HEARTBEAT.md ← ~8KB dispatch file, loads fully every heartbeat heartbeat/ sales.md ← sales monitoring script analytics.md ← GA4/GSC check newrelic.md ← uptime and performance health check pipeline.md ← data pipeline monitor autopublish.md ← scheduled content publishing instructions ```

Each memory/.md file is one topic with everything your agent needs on that subject. Each heartbeat/.md file is one runnable task with the full script or instructions.

The Refactor Process

Don't just split and pray. Here's the sequence:

1. Git snapshot before touching anything 2. Prune the monolith first — remove duplicates, stale entries, one-time fixes, anything already in your git repos. This alone took our MEMORY.md from 65KB to ~30KB. 3. Split the cleaned content into topic files 4. Rewrite MEMORY.md as a pointer index — one line per topic, 200–300 chars with keywords 5. Verify memory_search finds the new files (run a few test queries)

Same process for HEARTBEAT.md: prune, extract the scripts and checklists into heartbeat/*.md files, rewrite the dispatch file with executable refs.

Watch Out For

  • The glob pattern. OpenClaw's memory_search default pattern is `memory/*/.md` which is recursive — subdirectories work. But test this before you commit. We caught this early: a flat `memory/*.md` glob won't find files in `memory/topics/`. Drop a test file in your target directory and run a search before you restructure everything.
  • Pointer line length matters. Too short and memory_search won't have enough keywords to know when to pull a topic file. Too long and you're back to the bloat problem. 200–300 chars with 2–3 specific keywords per line is the sweet spot.
  • Don't duplicate. If something already exists in another file (like a checklist in memory/), point to it. Don't create a copy in heartbeat/. Every duplicate is a future contradiction.
  • Retention policies per topic. Not everything expires on the same schedule. Financial info and contacts don't have a 60-day shelf life. Set per-topic retention: some files get date-based pruning, some get manual review only.

Bonus: Move Monitoring to Cron

If your heartbeat is running fixed monitoring scripts (sales checks, uptime pings, analytics pulls), those don't need your agent's brain. Move them to cron jobs that alert on failure only. Your agent's heartbeat should be agent self-management — not spending 500 tokens to conclude "yep, sales look normal" every 30 minutes.

---

If you're building with OpenClaw and want to give your agents browser-native vision and interaction, check out our open-source tool: Mame — a zero-config MCP server that connects Claude and OpenClaw to Chrome DevTools Protocol, no headless browsers or screenshots required.

More Reading
April 5, 2026

The AI Agent Memory Landscape in April 2026: What Everyone Is Converging On

Read →
October 26, 2025

How to Prepare Your Business Website for AI Search: Beyond Traditional SEO

Read →
October 23, 2025

Fast Websites Win Customers: Why I Build With Next.js Instead of WordPress

Read →
Work With Us

Want to work together?

Start a Project