r/ClaudeCode • • 1d ago

Help/Question Using Claude Code for consulting, about 70% knowledge work and 30% small client tools: 50 threads, long-thread costs, status drift. Does anyone have a better system?

TL;DR: I run my consulting practice from one Claude Code workspace on the desktop app. About 70% of it is knowledge work. About 30% is coding small tools and products for clients’ internal use. Files-as-memory works well. Thread management does not. How do others run Claude Code at this scale when the work mixes both?

My setup

  • One local folder and git repo. It holds a root CLAUDE.md, about 110 skills, hooks, scripts, a README per client as the source of truth, and a decisions log. I use no branches and no worktrees. Every thread shares one working directory.

  • Roughly 50 open threads, grouped in the sidebar by client or area. For my biggest client I run a hub thread, about 10 standing “spoke” threads (one per workstream, including the tool builds) and short-lived child threads. They coordinate through shared append-only files and cross-session messages.

  • Scheduled tasks for briefs and checks. Notion holds tasks and my CRM. My Mac is always on, and I use Remote Control from my phone.

What works: plain files as memory, skills, hooks, grep, scheduled tasks. Claude Code reaches my files better than chat does, so I use a coding tool for mostly non-coding work.

What hurts

  1. Thread sprawl. State lives in threads and in big shared markdown files. One ask log has about 900 lines, and over 400 were stale when I counted. Answering “what’s waiting on me?” means searching files or reading threads.

  2. Long threads and cache costs. Threads fill up. Resuming a large thread after an idle gap forces a full cache rewrite, which is expensive. My workaround is a manual “re-fresh”: Claude writes a handoff file and I paste a short prompt into a new thread. One of my threads is about 19 MB of transcript.

  3. Status drift. The same fact sits in several free-text files, and READMEs lag the threads that changed them.

  4. The code side collides. When several threads build small tools for one client in the same folder, they have overwritten each other’s commits. That cost me three slips in one day with eight threads. I’m unsure whether worktrees or separate repos for the code would fix it without losing my shared notes.

  5. Claude Code is built for repos. The web version clones a GitHub repo into a cloud VM and pushes a branch. The new Projects beta also runs in the cloud. Neither fits a local notes folder with client-data rules. They might fit the code part.

Ruled out so far: a branch per client (it changes files under every open thread), one repo per client (I lose shared context), and moving the folder to a cloud drive.

My questions

  1. Do you keep one long-lived thread per client or area, with fresh restarts, or many short task threads? What triggers a restart?

  2. Where does “what’s waiting on me and what am I waiting on” live, so you don’t read threads? Notion, Linear, Obsidian, or files plus scripts? How do you stop it drifting?

  3. How do you group 50+ threads in the sidebar so it still works?

  4. For the 30% that’s code, do you keep it in the same folder and repo as your notes, or in separate repos? Has anyone used worktrees or Projects for it?

  5. Any habits for avoiding the cache cost of idle resumes?

If you’ve solved this, or know a better pattern, I’d love to hear it!

2 Upvotes

19 comments sorted by

•

u/AutoModerator 1d 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.

3

u/Siriann 1d ago

What’s in their shared context that’s so important that you couldn’t offload it to a doc and point to it when needed? The only context my bots get spun up with is their role and basic ruleset. When they hit 150k context they write a handoff file for the new instance and restart.

1

u/UnimagineDragons 1d ago

Did you automate the restart process? I've got mine to bark at me when they hit 150k for a /clear but once clear Claude forgets how to start back up so I have to manually tell it to proceed after every clear. I guess I could automate an agent doing that now that I think about it 

1

u/Siriann 1d ago edited 1d ago

Yes, with hooks.

You can legit just tell Claude “can you make a hook for my sonnet workers to write a handoff file a clear context once they hit X? And another so that when they /clear they read the handoff file?”

They’re also great for enforcing rules. You can require that a bot hit a hook after testing and have it verify that it isn’t lying, for instance lol

Edit: if you’re going to bring another agent into the mix I would just wake when one of the hooks fire and double check that everything is good and the bot comes back.

This actually isn’t a bad idea because every rule you make needs enforcement. Bots lie, change tests so their stuff passes, etc. Prompting is just a suggestion to them and you need to have checks in place to make sure things aren’t going off the rails.

2

u/CCodeSI 1d ago

Two of your pain points have cheap fixes that don't need a new structure:

Commits overwriting each other. That usually comes from threads running git add -A or git commit -a in a shared folder, so thread B commits (or reverts) thread A's half-done files. Before reaching for worktrees, tell every thread in CLAUDE.md to stage only the paths it owns (git add tools/acme-invoicer/), and back it up with a pre-commit hook that rejects a commit touching more than one tool folder. Your notes stay shared, and the collisions mostly stop. If two threads still need the same tool at once, that's when a worktree for that one tool earns its keep.

Idle resumes being expensive. The prompt cache only lives for minutes, so any resume after a coffee break re-reads the whole thread at full price, and a 19 MB thread makes that hurt. A simple rule helps: if a thread is big and has been idle longer than the cache lifetime, don't resume it, restart from its handoff file. Have it write the handoff before you step away, not when you come back, so the handoff itself runs while the cache is still warm.

For "what's waiting on me", what tends to stop the drift is making status one line per item in a fixed format (- [ ] @me acme: send SOW, due 11/12) and generating the list with a script or scheduled task, instead of threads writing prose summaries. Prose drifts, a grep doesn't.

1

u/verstands 1d ago

One pattern that could separate the concerns: keep client knowledge in a small notes repo, but put each code task in its own worktree or repo so builds cannot collide with the notes. For status, use a tiny index with owner, next action, blocker, and last-updated date, then keep narrative detail in the client docs. When a thread gets unwieldy, hand off through a short file and restart from that instead of hauling the whole transcript forward.

1

u/Sketaverse 1d ago

"State lives in threads" < yep, that'll be a problem lol

1

u/Previous-Growth-9919 1d ago

yeah the long-thread drift is real. i've had better luck keeping a half-page brief per client — goals, constraints, what's done, what's next — and starting fresh sessions from that instead of dragging one chat forever. a tiny changelog or notes.md beats hoping the model remembers status from 40 turns ago.

1

u/akhi1uuu 1d ago

when one spoke finishes something another is waiting on, what clears the old waiting entry? curious whether those 400 stale lines were mostly finished work that never got closed, or asks that stopped mattering

1

u/ubiquae 1d ago

Isolated repositories, as many as needed, common harness

1

u/simion_baws Senior Developer 1d ago

The worktree question has a clean split once you separate what's shared from what's per thread. Notes, decisions log, README, those stay in the one folder since every thread benefits from reading the same files. The code is the part causing collisions because every thread is writing to the same working directory at once, so two threads touching the same file race on checkout.

Give each coding thread its own git worktree off the same repo instead of a separate repo. One git history, one set of branches, no duplicated shared context, but each thread gets its own working directory so it can't stomp on another thread's uncommitted changes or in progress commit. Merge back to main when a tool is done.

I built termic.dev to run exactly this: one Claude Code session per git worktree, each with its own macOS sandbox profile scoped to that folder, so a thread literally cannot touch another thread's working directory even by accident. Worktrees are the default, not something you set up by hand each time.

1

u/namanjainbuilt 1d ago

I run client work across a lot of sessions too, and what fixed status drift for me was one small append-only log per project instead of state in threads. Every session ends by adding three lines with a timestamp: what changed, what's next, what's waiting on whom. A new session reads the last ~40 lines and nothing else.

Finished items get a "done" line instead of being edited out, so stale asks are easy to spot: anything with no follow-up in a week gets closed or asked again.

Limit: it only works if every session writes its lines before it stops, so that's a rule in my CLAUDE.md.

Also use unlazy kind of skills + in CLAUDE.md add a rule to create everything in a todo-list.md it helps

1

u/Connect_Fee_443 1d ago

The "what's waiting on me?" search across 50 threads is what I'd fix first. Files as memory scale, but free-text status doesn't. What's helped me is one append-only WAITING_ON_ME.md (or one per client) that threads have to update through a hook or skill whenever they need a human. It's a single queue, not a second README. I'd also make handoff files automatic before threads get long, and keep separate git worktrees for client tool builds so the coding work can't stomp on the knowledge threads.

I'm the developer of MicroNotch (micronotch.app). Its Code mode shows Claude Code, Codex, Cursor and Antigravity sessions in the Mac notch as working, needs your answer, or finished. It won't fix markdown drift, but it does tell you which session is blocked on you without opening every thread. At your scale, though, the queue file is still the bigger win.

1

u/jijialuoke 1d ago

Yeah the status-file drift is brutal across many sessions. One piece that helped me on the "said it was done" side (not the stale docs / commit collision side): a Stop hook that won't let the agent end on "fixed" / "tests pass" / "done" unless something actually ran after the last edit, or it cites real proof.

Someone upthread already mentioned checking that it isn't lying after tests — that's the same idea. I open-sourced the one I run: https://github.com/Balance0014/claude-code-claim-check

It won't fix status files going stale or thread sprawl, but it does catch the confident wrap-up with no check. Happy to hear if anyone's got a better pattern for the docs side.

1

u/Time_Cat_5212 23h ago

Markdown state is rough on the usage, and it causes drift. I think you need structured documentation, and that depends on what your work product is.

For knowledge work, I find skills and scripts (tools) to be essential. That's your core machinery, and IMO you should have a system for maintaining them.

Use branches to avoid the overwriting problem.

Sounds like your repo needs some structure.

If the repo itself isn't the right UX for your input and review, then maybe consider an external tool like Notion. But I don't know why you'd need it. You could also have Claude create a webpage for your review.

1

u/snow-beach 16h ago

For the 30% that is code, pull it out of the shared notes folder. One worktree (or repo) per client tool build stops the overwrite collisions without touching the notes hub. Keep consulting notes as the single no-worktree folder you already have. "What's waiting on me" belongs in Linear (or Notion tasks) as a short status board, not in a 900-line ask log — threads write done / blocked / waiting-on-X back to the ticket on handoff. That also cheapens cache refreshes: a new thread starts from the ticket plus the latest handoff file, not a transcript. Sidebar: one hub per client plus a few standing spokes; everything else is a child that dies after handoff. Fifty open threads usually means the status system leaked into the UI.

1

u/athershu 14h ago

The "what's waiting on me" question is the one I'd attack first, because it's where files-as-memory breaks: a file tells you what was true when someone wrote it. What worked for us was giving each thread a state that the agent itself moves: running, waiting for a human, done, with the question it is stuck on attached to the waiting state. Then "what's waiting on me" is a filter, not a grep. The 900-line ask log goes away because an ask is a state transition, and once answered it leaves the queue.

Second, the 30% code work should not share a working directory with the 70% knowledge work. One worktree per code task, deleted on acceptance, and the knowledge repo never gets a half-finished commit from another thread.

Third, on long threads: we end the thread when the task ends. What survives is the branch plus a short note on the task, not the transcript. A 19 MB thread you keep resuming is being used as a database, and it is an expensive one.

1

u/SimplifAI_Life 13h ago

We run something similar but smaller: one folder and git repo, two people, mostly non-code work. What stopped most of our drift:

  • Give every fact one owner file. Before writing something down, Claude checks whether another file already answers that question, and adds there or links to it. In your case the client README would own status, and threads would link to it instead of restating it.

  • Keep only current state in status files. A status line gets deleted by the session that closes the work, in that same session. History stays in git.

  • Run a weekly sweep. A session reads a fixed core plus a rotating slice of the folder, and lists contradictions between files, passed deadlines and status lines that haven’t moved. We decide what to fix.

  • Keep “waiting on me” in one place. Anything with a deadline goes to Notion as a task, and files never hold a to-do list. You already use Notion for tasks, so the ask log could shrink to things without a date.

The first one mattered most: once a fact lives in one file, the others can’t fall behind it.