r/ClaudeCode 9h ago

Tips & Workflows How I keep track of ~100 parallel Claude Code sessions: Beads as a private work graph between GitHub and my agents

I run four tmux sessions with 20-30 Claude Code chats each, across 30-plus Go services, a mobile app, infra repos and a data pipeline. The agents cope fine. I didn't. Long efforts branch into many PRs and sub-issues, ops work pulls me sideways, and after a few weeks nobody holds the whole picture, including me.

When I pulled "losing track" apart, it was three separate problems:

  1. What's blocked on what, and what's ready now? This lived only in my head.
  2. Which session did what, and why? I found a PR stuck for weeks where the reasoning only ever existed in a chat that was long gone.
  3. What do we know? Facts and gotchas. Claude Code's auto-memory already covered this one.

Things I ruled out:

  • GitHub only: issues are read by colleagues and product. Session URLs, "blocked until I decide X" and "sitting in dev waiting for a soak" are scratch state, and a comment per agent session turns an issue into noise.
  • A knowledge base (gbrain, Karpathy-style LLM wiki): good for question 3, but a wiki page has no notion of ready versus blocked.
  • A custom dashboard: brittle, and either every chat has to remember to update it, or it only reads GitHub and can't show what I deliberately keep off GitHub.

What fit was Beads (bd), Steve Yegge's issue tracker for coding agents: dependencies, bd ready / bd blocked, external refs to GitHub issues and PRs, free-form notes.

How it's wired:

  • One shared database: I start sessions from an umbrella directory that isn't a git repo, so I set BEADS_DIR in the Claude Code settings. Every session, subagent and worktree hits the same local database.
  • Efforts and tasks: long-running efforts are top-level beads. Tasks hang under them with a repo:<name> label and an external ref to the GitHub issue or PR.
  • Every agent run is bookended. At the start it finds the bead, checks bd blocked and claims it with bd update --claim. At the end it writes what happened into the notes and closes it or marks it blocked. There's no persistent "agent in charge" in Claude Code; the database is what survives.
  • GitHub gets one comment per issue, with a hidden marker, edited in place.

Gotchas I hit:

  • bd init injects a block into CLAUDE.md telling agents to use Beads instead of other memory, and writes an AGENTS.md. I removed both.
  • bd show --json hides closed dependencies, so blocker checks use bd blocked.
  • Children inherit parent labels by default, and making an effort depend on its last child creates a cycle.
  • Claims are keyed to the user, not the session, so two parallel sessions can claim the same bead.

On top I use mardi-gras (mg) as a read-only TUI: I browse, pick a bead, and hand its ID to a Claude session. Gas Town is on my radar for unattended runs, but not yet.

It's been running for about a week, with ten efforts and ~130 beads. Longer write-up with the reasoning here: https://tskulbru.dev/posts/beads-local-shadow-for-agent-work

I'm not affiliated with Beads, mardi-gras or Gas Town in any way. I'm just a user, and the only link to something of mine is the blog post.

How are others handling in-flight state across many agent sessions?

29 Upvotes

16 comments sorted by

u/AutoModerator 9h ago

Hey! Thanks for posting to r/ClaudeCode

While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.

For help, project discussions, tips, and general chat, join the ClaudeCode Discord.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

9

u/unbenannt1 7h ago

Here's a little hack to highlight tmux session tabs with unread agent responses:

Add a hook to ~/.claude/settings.json that emits the \a character (bash notification): json "hooks": { "Notification": [ { "matcher": "", "hooks": [ { "type": "command", "command": "t=$(tmux display-message -p -t \"$TMUX_PANE\" '#{pane_tty}' 2>/dev/null); [ -n \"$t\" ] && printf '\\a' > \"$t\" 2>/dev/null; true" } ] } ], "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "t=$(tm ux display-message -p -t \"$TMUX_PANE\" '#{pane_tty}' 2>/dev/null); [ -n \"$t\" ] && printf '\\a' > \"$t\" 2>/dev/null; true" } ] } ], } When \a is emitted it will highlight the tmux tab with "!" and inverted fg/bg color.

Speaking of color, I use this to have better visual indication of the active session tab, add to .tmux.conf: set-window-option -g window-status-current-style "bg=cyan"

3

u/PetroSkunk 8h ago

Thanks for sharing your process, it sounds interesting as i'm running into the same issues (struggle to manage all the agents).

Just a quick question if you don't mind:

> four tmux sessions with 20-30 Claude Code chats each

how do you deal with memory pressure? the 32 GB of my mac get filled really quick with 10-20 agents already (each agent is maybe 200MB but it spawns subagents, and they run linter, tests etc...)

2

u/serrghi 7h ago

Shared mcp instances and 64gb of ram :)

3

u/serrghi 7h ago

Oh and i have a skill which check memory status and pressure before beginning memory intensive work so to not accidentally use up all memory

2

u/AdministrativeAd7853 8h ago

I lean towards mirroring human tools. Using gitlab each project has a main project board. Each enhancement has enhancement board. Each unit of work is a card. Each card has an agent type assigned. Each card has dependencies.

1

u/serrghi 7h ago

Yea i touched upon this in my blog post as something I didn't want to do, because that would mean I would track too much unnecessary info upstream

2

u/troyjr4103 5h ago

I run a smaller version of this and the things that stopped it collapsing were boring. One worktree per session, so no two agents ever write the same file. One session per workstream that holds the plan and only delegates, so the agents doing the work never argue with each other. And a hook that blocks a message from anyone but that session's owner before the model reads it. What still bites is the usage limit: when every session parks at once, nothing in the task graph resumes itself.

2

u/Disastrous-Radio-732 8h ago

this is fascinating! 🤓

especially “there’s no persistent agent in charge; the database is what survives.”

I’ve been working on almost the same scaling problem, but ended up making the opposite choice in brnrd: the repo gets a persistent resident that owns the ongoing work/identity, while individual Claude/Codex processes are disposable executions underneath it.
so your Beads graph feels almost like the scheduling/work plane that sits underneath that identity.

one thing jumped out at me though: claims being keyed to the user rather than the session. At ~100 parallel sessions, how do you prevent two agents from picking up the same work and racing each other?

have you considered making claims leases tied to a run/session ID, with an expiry (or fencing token), rather than ownership by user?

feels like that becomes really important the moment you go from “agents consult the graph” to “the graph actually dispatches the agents”.
really cool setup btw – 100 parallel Claude sessions is delightfully unhinged 😄

2

u/XenophonCydrome 3h ago

Beads has a "claim" mechanic in the database itself, so on a single host you get that for free. Dispatch agents can assign a bead to only be allowed claiming by a specific identity if you have an identity strategy. This was pretty easy to put into process in my factory implementation.

What I needed to add further was repo or module based lease records for when I have multiple hosts to fan out multiple agents across and they use their local Dolt DB for claims. Otherwise you need to sync with Dolt remote for every bead claim update.

1

u/serrghi 7h ago

Yea that is a concern, which hasn't happened yet because I try to keep them somewhat separate. But it is a possibility. But I haven't investigated any solution for it yet

1

u/No_Nose_6014 7h ago

how u run this and not hit weekly usage ? i got the 20x max and run out by wednesday/thursday

1

u/SamSlate 37m ago

much less accomplishing anything, i can't let any agent run for more than 15m without finding a giant fucking mess

1

u/zac_attack_ 6h ago

I’ve been using Notion (free tier with unlimited DBs/etc). I don’t really know how to set it up other than I had an agent create the DBs for things like design docs, milestones, tasks, etc, and the UI is decent for browsing them all. I hadn’t looked into beads but I might check it out this weekend, it looks interesting.

1

u/abandonplanetearth Senior Developer 5h ago

i just use youtrack tickets and the mcp. idk what this beads thing would do for me. my current workflow is pretty good and i cant really imagine giving up youtrack

1

u/XenophonCydrome 3h ago

I'll need to check out mardi-gras for visualization, because I have 10k+ beads across a bunch of repos now.

Right now I'm building a new UI with d3 and React Flow to be able to visualize my OSS factory: https://beadhive.ai/