Why local AI agents need process supervision, not heavy background daemons

Most multi-agent tools borrow their design from web backends: an always-on server plus a database queue. On a developer laptop that design hangs, leaks memory and quietly lies about what was delivered. Here is a lighter architecture that is more reliable, not less.

TL;DR
  • Local AI agents need process supervision: start agents, keep them alive, deliver messages, notice when one dies, and recover after restarts.
  • An always-on orchestrator server with a database queue is the common answer, and it fails in five predictable ways on a developer machine.
  • Almost all coordination work can happen inside the command that asked for it. tmux already keeps the agents alive. Only timed jobs need a background process, and that one can exit when idle.
  • Team Agent follows this design: no daemon, no database, append-only inbox files, and a 0 MB idle footprint.

01What is process supervision for AI agents?

Process supervision means managing the lifecycle of long-running programs: starting them, keeping them running, restarting them when they fail, and knowing at any moment which ones are healthy. Operating systems do this with tools like launchd and systemd; container platforms do it with orchestrators.

When you run several AI coding agents on one machine, such as Claude Code, OpenAI Codex and Pi, you need the same thing in a smaller form. Something has to:

  • start each agent CLI with the right role, model and permissions,
  • deliver tasks and messages to the right agent, even when it is busy,
  • bring results back to whoever is coordinating,
  • notice when an agent exits, and
  • restore the whole team, with context, after a restart.

The question is not whether you need supervision. It is how heavy that supervisor should be.

02The heavy-daemon pattern

The familiar design looks like a small web backend. An orchestrator process starts when you begin working and stays resident. It polls every agent on a timer, writes every message into a database (often SQLite), and a delivery loop works through the queue. It is easy to reason about on a whiteboard, which is why so many tools start there.

It also matches what we built first. Earlier versions of Team Agent ran a background coordinator with a SQLite message store. Running it daily on real projects taught us exactly where that design breaks.

03Five ways background daemons fail on a developer machine

1. Memory that never goes away

A resident process holds memory whether or not anyone is working. Multiply that by every project you have open, add the slow growth that any long-lived process accumulates, and your laptop is paying a constant tax for agents that are asleep. Long-running orchestrators are also where memory leaks live: a process that never exits never gets a clean slate.

2. Version skew after upgrades

You upgrade the tool, but the daemon started yesterday is still running yesterday's binary. Now your CLI speaks one protocol and the daemon another. Tools end up adding rotation logic and compatibility checks just to manage a problem they created by staying resident.

3. One stuck queue stops everyone

A central delivery loop is a single point of failure. If one message hits a bad state, or one check refuses to pass, the loop can stall for every agent behind it. We saw this firsthand: a single blocked delivery check once held up outgoing messages for every team on the machine until it was fixed.

4. Database locks and growth

A shared database becomes a global lock. Every agent that sends, every status poll and every result write contends for it. The file grows with every observation the daemon records; in long-running workspaces ours passed 100 MB. A crash in the middle of a write needs recovery logic, and recovery logic needs testing that nobody enjoys writing.

5. Status that lies

A queue can mark a message as “delivered” or “consumed”, but an interactive terminal app gives no reliable acknowledgment. Thousands of messages can end up in states that sound final but were never actually observed. When status cannot be trusted, people start re-sending, and duplicated instructions are worse than late ones.

The pattern behind all five

Each failure comes from a check, a lock or a process that is wider than the thing it protects: one lock for every agent, one loop for every team, one database for every message, one process for every hour of the day.

04The alternative: lightweight, stateless supervision

If you sort the work a coordinator does by when it has to happen, a better design falls out:

Kind of workExamplesWhere it belongs
Immediatesend a task, report a result, start or stop an agentInside the command that asked for it
Event-drivenan agent's process exited, you attached to the leaderTerminal multiplexer hooks (tmux)
On requestis this agent busy? is it healthy?Computed live when you ask, never cached
Timedreminders, recurring check-ins, retry laterA short-lived process that exists only while jobs exist

Only the last row needs anything that outlives a command. Turned into rules, that gives seven principles:

  1. Do the work where it is requested. send delivers the message before it returns. There is no queue for a background loop to drain later.
  2. Let tmux do the babysitting. tmux is already a resident server built to keep terminal programs alive across disconnects. Agents run in its panes; there is no second supervisor to keep in sync with it.
  3. Keep state in small files with one writer. Each agent's messages go into its own append-only inbox file. Records are added, never rewritten, so a crash cannot corrupt older history.
  4. Lock the smallest thing. Locks cover one agent or one inbox, never the whole workspace. A stuck agent can only fail its own operations.
  5. Wake only for scheduled work. Reminders start a background process on demand, supervised by the operating system (launchd on macOS), and it exits when the schedule is empty.
  6. Compute status live. Ask the terminal what is running right now instead of trusting a record written minutes ago.
  7. Report only what you can verify. “Typed and submitted” is a fact. “The agent accepted it” is a guess, and the system should say so.

A side effect: every command runs the binary you just installed. There is no old daemon to drift out of date, so upgrades take effect immediately.

05What “0 MB idle” actually means, and how to check it

Bold resource claims deserve precise definitions. For Team Agent, 0 MB idle means: there is no background process. Close your agents and, with nothing scheduled, no Team Agent process remains. Not a sleeping process with low memory: no process at all.

While agents are running, the only Team Agent processes are attached to them: the launcher of your leader session, and a small helper per agent that gives it the team messaging tools. Each one is part of its agent's process tree and exits with it. tmux and the agent CLIs use memory exactly as they would without Team Agent.

You can verify the idle claim yourself. Stop the team, exit your leader session, then:

team-agent stop --workspace .
# exit the leader conversation, then:
pgrep -fl team-agent || echo "no team-agent processes running"

team-agent stop also checks that the team's own processes and resources are gone before it reports success, so a clean stop means nothing was left behind.

06How this prevents hangs and memory leaks

  • Nothing lives long enough to leak. Coordination code runs in commands that exit in seconds. The long-running processes are the agent CLIs themselves, which you can see and restart individually.
  • Failures stay local. With per-agent locks and per-agent inboxes, a hung agent returns an error for that agent only. Everyone else keeps working.
  • Nothing to crash in the background. If there is no central loop, there is no silent stall. Each send succeeds or fails on its own, loudly.
  • Diagnosis is a command, not an investigation. team-agent doctor checks six things in order (scope, host, agents, storage, message routes and the return path to the leader). Healthy output is a single line; a failure stops at the first broken step and suggests one fix.

07Checklist: evaluating a local multi-agent orchestrator

Whatever tool you choose, these questions separate robust designs from fragile ones:

  1. What is still running when no agent is working? How much memory does it hold?
  2. If I upgrade while agents are running, which version handles the next message?
  3. Can one stuck agent block messages to the others?
  4. Where are messages stored? Can I read them with ordinary tools?
  5. What exactly does “delivered” mean? Is it observed or assumed?
  6. What happens to messages sent while an agent is busy, or while I am typing in its window?
  7. After a reboot, do agents come back with their conversation history?
  8. Does it run the official CLIs with my configuration, or replace them with API calls?

08FAQ

Do local AI coding agents need a background server to coordinate?

No. Sending a task, starting an agent and reading a result can all happen inside the command that asked for them. The terminal multiplexer (such as tmux) already keeps agent processes alive. A background process is only needed for timed work such as reminders, and it can start on demand and exit when the schedule is empty.

How do I prevent memory leaks when running AI agents locally?

Avoid long-lived orchestration processes that accumulate memory, prefer short-lived commands that exit after each job, keep agent state in small files instead of a growing database, and use a stop command that verifies no processes are left behind. Then check with a process listing that nothing remains after shutdown.

What does a 0 MB idle footprint mean for Team Agent?

Team Agent has no daemon. Every Team Agent process you will see is attached to an agent you are running: the launcher of your leader session and a small messaging helper per agent, each exiting with its agent. Close your agents and, with nothing scheduled, no Team Agent process remains, so it uses no memory. tmux and the agent CLIs use memory as they normally would.

Why not use SQLite as a message queue for local agents?

A shared database becomes one global lock that every agent and command must pass through. Under concurrent writes it contends, it grows over time, and a crash mid-write needs recovery. Append-only files with one lock per recipient isolate failures so a problem with one agent cannot block the others.

Keep reading