Beads: A Version-Controlled Task Graph That Solves the Multi-Agent Coordination Problem
Hook
When two AI agents simultaneously create tasks in separate branches, traditional issue trackers choke on merge conflicts. Beads treats your task list like Git treats your code—and that changes everything for agent-based development.
Context
AI coding agents like Claude Code and GitHub Copilot are getting smarter, but they’re still forgetful. Ask an agent to refactor a codebase, switch contexts, then return hours later—it has no memory of what it planned, what it completed, or what dependencies exist between tasks. Traditional issue trackers like Jira or Linear solve this for humans with UIs and centralized servers, but they’re architecturally incompatible with agent workflows that operate across branches, repositories, and concurrent contexts.
The fundamental problem is merge semantics. If two agents (or one agent in two branches) both create tasks, assign IDs, or update status, you get conflicts that require human intervention. Markdown TODO lists avoid this with simple text merging, but sacrifice queryability and structured relationships. What agent-based development needs is Git’s merge semantics applied to task graphs—a way to version control not just code, but the planning layer that coordinates who builds what and when. That’s the insight behind Beads.
Technical Insight
Beads is built on Dolt, a SQL database that’s literally Git for data. Every row change gets a commit hash, branches are first-class citizens, and merges happen at the cell level rather than the file level. This architectural choice solves the coordination problem at the database layer, letting Beads focus on task graph semantics.
The schema is deceptively simple but powerful. Each task gets a hash-based ID (like bd-a1b2c3d4) generated from content and timestamp, making collisions mathematically improbable even with thousands of concurrent agents. Tasks have types (issue, message, milestone), status (open/closed), and most critically, a blocks field that encodes the dependency graph. Here’s how you create a task with dependencies:
# Create a parent task
beads new issue "Implement user authentication"
# Output: Created bd-a1b2c3d4
# Create subtasks that block the parent
beads new issue "Set up JWT middleware" --blocks bd-a1b2c3d4
beads new issue "Add login endpoint" --blocks bd-a1b2c3d4
# Query the graph as JSON for agent consumption
beads list --format json --filter 'status:open AND blocks:bd-a1b2c3d4'
The JSON output is explicitly designed for LLM context windows. It’s not pretty-printed for humans—it’s compact, structured, and includes only the metadata agents need to make decisions. When an agent asks “what should I work on next?”, you can pipe beads list --format json directly into its prompt with filters for unblocked open issues.
The real magic happens with semantic compaction. As your task graph grows to hundreds of items, older closed tasks consume precious context tokens without providing current value. Beads includes a compaction command that uses an LLM to summarize completed work:
# Compact tasks closed before 30 days ago
beads compact --before 30d --model claude-3-5-sonnet
This replaces verbose task descriptions with semantic summaries, preserving historical context while reducing token consumption by 60-80%. The summaries live in the same version-controlled database, so you can still query or diff them across branches.
Beads operates in two modes that map to different collaboration patterns. Embedded mode (default) runs Dolt in-process with a file lock, giving you single-writer semantics perfect for a solo agent working in a repository. Server mode connects to an external Dolt SQL server, enabling multi-writer scenarios where multiple agents coordinate through the same task graph. Switching between modes is a single environment variable:
# Embedded mode (default)
beads list
# Server mode
export BEADS_SERVER="localhost:3306"
export BEADS_DATABASE="myproject_beads"
beads list
The Git integration is thoughtfully optional. By default, Beads stores its Dolt database in .beads/ at your repository root and auto-commits task changes to Git. But you can decouple this with BEADS_DIR, storing task data in a separate repository or directory. This enables “contributor mode” for open-source projects—contributors run Beads locally without polluting the main repo, while maintainers can optionally sync a planning repository. The flexibility here is subtle but crucial: Beads doesn’t force Git semantics, it offers them as an option.
One underappreciated feature is the message issue type. Unlike persistent issues, messages support threading and act as ephemeral communication between agents or between humans and agents. You can ask a question, get a response threaded under it, then mark the whole thread closed—all without cluttering your persistent task graph. This creates a clean separation between planning (issues) and coordination (messages), something traditional trackers conflate.
Gotcha
The CGO dependency is Beads’ biggest operational friction. Because Dolt’s embedded engine requires C bindings, you can’t go build on a fresh system without a C compiler toolchain. macOS users need xcode-select --install, Linux needs build-essential, and cross-compilation becomes significantly more complex. If you’re building in Docker or CI/CD pipelines, you’ll need to factor in build time and image size increases. The project provides prebuilt binaries, but if you’re modifying Beads or integrating it as a library, expect build complexity.
Embedded mode’s single-writer constraint is a subtle footgun. If you run beads new issue in one terminal while another process (or agent) has the database locked, you’ll get a cryptic lock acquisition error. This is fine for typical agent workflows where one agent operates sequentially, but if you’re experimenting with truly parallel agent coordination, you’ll need to run a Dolt server—which adds deployment complexity and negates the “just works” simplicity of embedded mode. The documentation could be clearer about when you actually need server mode versus when embedded suffices.
Windows support exists but comes with antivirus false positives. The ANTIVIRUS.md file explains that Dolt’s embedded engine triggers heuristic scanners because it dynamically generates code paths. You’ll need to manually verify binaries and whitelist the Beads executable, which is a non-starter for some enterprise environments. This isn’t Beads’ fault per se—it inherits Dolt’s runtime characteristics—but it’s a real deployment barrier that the project acknowledges honestly.
Verdict
Use Beads if you’re building multi-agent systems where agents need shared memory across sessions or branches, running long-horizon coding tasks where context persistence matters more than ephemeral prompts, or managing distributed development where AI agents work in parallel on feature branches that eventually merge. The version-control semantics and conflict-free merging are genuinely novel, and the agent-optimized JSON output shows deep understanding of LLm workflow constraints. Skip it if your agents only handle single-session tasks where markdown TODOs suffice, your deployment pipeline can’t accommodate CGO dependencies, you’re on Windows in a locked-down enterprise environment, or you need real-time multi-agent coordination with millisecond latency (Dolt’s merge model trades latency for consistency). The tool is opinionated about solving a specific problem—distributed agent coordination with version control semantics—and excels in that niche.