Back to Articles

Beads: Why Your AI Coding Agent Keeps Forgetting Its Own Plan

[ View on GitHub ]

Beads: Why Your AI Coding Agent Keeps Forgetting Its Own Plan

Hook

Your AI coding agent has amnesia. It writes a perfect plan in PLAN.md, then forgets half of it two hours later when you switch branches. Beads fixes this by treating task memory like database rows, not text files.

Context

Coding agents like Claude Code and Cursor struggle with long-horizon tasks because they rely on markdown files for planning. These files create merge conflicts when you work across branches, lose dependency information when agents rewrite sections, and bloat context windows with stale task history. The problem compounds in multi-agent workflows: two agents creating tasks simultaneously will generate conflicting IDs, and there’s no way to query “which tasks are actually ready to work on right now?”

Beads replaces markdown plans with a version-controlled SQL database powered by Dolt. Tasks become graph nodes with typed relationships (blocks, relates_to, parent-child). Hash-based IDs like bd-a3f8 prevent collisions. Cell-level merging eliminates conflicts. Most importantly, agents can query structured data (“show me P0 tasks with no open blockers”) instead of parsing freeform text. It’s designed for the workflow where agents are the primary interface, not humans clicking through a web UI.

Technical Insight

Beads’ architecture centers on Dolt, a SQL database with git-like semantics. When you run bd init, it creates a .beads/embeddeddolt/ directory containing a full Dolt database with schema migrations for tasks, dependencies, and audit trails. The embedded mode runs Dolt in-process using CGO bindings to its C libraries—this is why building from source requires a C compiler. Single-writer access is enforced via file locking, which keeps the mental model simple for solo developers or single-agent workflows.

The command interface prioritizes agent ergonomics. Instead of forcing agents to construct SQL queries, Beads provides task-specific commands with JSON output:

# Agent queries ready tasks
bd ready --json
# Returns: [{"id":"bd-a3f8","title":"Implement auth","priority":0,"blockers":[]}]

# Agent atomically claims work
bd update bd-a3f8 --claim --json
# Sets assignee AND status to in_progress in one transaction

# Agent checks what's blocking this task
bd show bd-a3f8 --json
# Returns full dependency graph, audit history, related messages

The --claim flag demonstrates a key insight: agents need atomic operations. Without it, two agents could both read “this task is unclaimed,” then both try to assign it to themselves. The atomic claim prevents this race condition.

Hash-based IDs solve the distributed workflow problem. When you create a task, Beads generates an ID by hashing timestamp + random data, producing identifiers like bd-a3f8 or bd-7k2m. Unlike auto-increment IDs, these never collide across branches or agents. If you create bd-x9f1 on branch A and an agent creates bd-p4s2 on branch B, merging is trivial—Dolt’s cell-level merge just combines both rows. Hierarchical IDs extend this: bd-a3f8.1 represents the first sub-task of epic bd-a3f8, and you can nest arbitrarily (bd-a3f8.1.2 for sub-sub-tasks).

Compaction addresses context window limits through semantic summarization. When you run bd compact, Beads identifies closed tasks older than a threshold, generates AI summaries of their work, and marks them as compacted. Agents see the summary instead of full details, reclaiming tokens. The dependency graph remains intact—if bd-old1 blocked bd-new5, that relationship persists even after compaction. This implements a form of “lossy compression” for agent memory, analogous to how humans remember project outcomes but forget daily standup details.

The messaging system adds ephemeral context. Running bd create "Investigate flaky test" --type message --thread bd-a3f8 creates a note tied to an existing task. Messages have replies_to relationships for threading and are automatically deleted after configurable retention periods. This separates durable task state (“implement feature X”) from transient discussion (“I tried approach Y, didn’t work”), preventing context pollution.

For teams, server mode unlocks concurrent writes. You start an external Dolt SQL server (dolt sql-server from the Dolt CLI), then initialize with bd init --server --server-host=10.0.1.5. Now multiple agents or developers can write simultaneously—Dolt handles transaction isolation at the database level. The tradeoff is operational complexity: you’re running a persistent server instead of just executing a binary.

Gotcha

Embedded mode’s single-writer limitation is stricter than you might expect. If an agent has bd running in one terminal (even just bd ready with a slow query), and you try bd create in another terminal, the second command blocks until the first releases the lock. This isn’t a bug—it’s SQLite-style file locking—but it feels clunky compared to tools that allow concurrent reads. Server mode fixes this, but now you’re operating a database server, which is overkill for many solo projects.

The CGO requirement complicates deployment. You can’t trivially cross-compile a Linux binary from macOS without Docker and a cross-compiler toolchain. The npm and Homebrew packages ship prebuilt binaries to work around this, but if you’re on an unsupported platform (say, Alpine Linux with musl libc), you’re building from source with non-trivial C dependencies. On Windows, MinGW works, but the install script notes that ICU libraries fall back to pure Go—performance characteristics may differ.

The “community tools” documentation is telling. The README links to a dedicated file listing UIs and integrations, but as of this analysis, the ecosystem is nascent. With 20,104 stars, you’d expect mature tooling; the framing suggests it’s early. If you need a polished web dashboard today, GitHub Issues or Linear are more batteries-included. Beads is optimized for CLI-first agent workflows, and the human tooling will catch up later (or may never be the priority).

Verdict

Use Beads if you’re building multi-step agent workflows where tasks span days or branches, and you’ve been burned by markdown merge conflicts or agents losing track of dependencies. The Dolt foundation makes it especially compelling for teams experimenting with multiple agents working in parallel—the version control semantics are unmatched. It’s also valuable if you’re in a monorepo or polyglot VCS environment (the git-optional BEADS_DIR mode works anywhere). Skip it if you’re doing short-lived, single-session agent tasks where a markdown checklist suffices, or if you need a mature ecosystem with native mobile apps and Slack integrations today. Also skip if CGO build requirements are a dealbreaker for your CI/CD pipeline. For human-first issue tracking with occasional agent access, Linear or GitHub Issues offer better UX. Beads is agent-first infrastructure, and that focus is both its strength and its niche.

// QUOTABLE

Your AI coding agent has amnesia. It writes a perfect plan in PLAN.md, then forgets half of it two hours later when you switch branches. Beads fixes this by treating task memory like database rows,...

[ Tweet This ]
// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/gastownhall-beads.svg)](https://starlog.is/api/badge-click/developer-tools/gastownhall-beads)