Mar 2026

Worktrees, tmux, and Parallel Tasks

When I work on several tasks at the same time, the biggest slowdown is context switching.

GitWorkflowtmuxAgents

You are halfway through a feature. Then a bug appears. Or you suddenly want to try another idea.

If everything happens in a single working directory, switching branches quickly becomes messy.

You usually end up doing one of these:

  • committing something that is not ready
  • stashing changes and later trying to remember what you were doing
  • copying code somewhere just to avoid losing it

It works, but doing this many times a day adds friction. It also makes reviewing changes harder because work from different tasks can end up mixed together.

This becomes even more noticeable when running multiple coding agents at the same time.

Before: one working directory

Normally everything happens in a single workspace.

repo
  │
  ▼
working directory
  │
  ├─ branch: feature
  │
  (switch)
  │
  ├─ branch: bugfix
  │
  (switch)
  │
  └─ branch: experiment

Everything shares the same folder. If several sessions or tools work on the repository, their changes can easily collide.

Using worktrees

Git worktrees solve this in a simple way.

A worktree is another working directory connected to the same repository. Each one can check out a different branch.

Instead of switching branches in the same folder, each task gets its own directory.

repo
 ├─ task-feature
 │   └─ branch: feature
 │
 ├─ task-bugfix
 │   └─ branch: bugfix
 │
 └─ task-refactor
     └─ branch: refactor

Each task now has its own workspace. Changes stay isolated and the diffs remain clean.

Running agents in parallel

This setup becomes very useful when running coding agents.

I often run OpenCode in several sessions at the same time. Each worktree gets its own OpenCode instance working on that task.

task-feature   → OpenCode instance
task-bugfix    → OpenCode instance
task-refactor  → OpenCode instance

Because each instance works inside its own worktree and branch, the sessions stay independent and do not interfere with each other.

Each one produces changes only for its branch, which makes reviewing and merging much easier.

My setup with tmux

To manage everything I combine worktrees with tmux.

For each task I create:

  • a worktree
  • a branch
  • a tmux session

Inside each tmux session I open the editor in that worktree and run an OpenCode instance for that directory.

tmux session 1 → task-feature → OpenCode instance
tmux session 2 → task-bugfix → OpenCode instance
tmux session 3 → task-refactor → OpenCode instance

Switching tasks now just means switching tmux sessions.

Everything runs in parallel and each task stays completely independent.

                repository
                      │
        ┌─────────────┼─────────────┐
        │             │             │
     worktree      worktree      worktree
     feature        bugfix        refactor
        │             │             │
   tmux session 1 tmux session 2 tmux session 3
        │             │             │
   OpenCode inst.  OpenCode inst.  OpenCode inst.

Creating a worktree

Creating a new one is simple:

git worktree add ../task-1 -b task-1

This creates a new directory and checks out a new branch inside it.

From there you can open the folder and start working immediately.

The idea

What helped me most was treating worktrees as small task sandboxes.

One task.
One worktree.
One branch.
One OpenCode instance.
One clean diff.

When the work is done, merge the branch and remove the worktree.