Skip to content

Sessions

A session is one VM plus its persistent disk, created from a repo and a branch. All state lives in instance tags and on the disk.

From inside a git repo:

pier <branch> [base]

The session checks out <branch> off base (default HEAD), applies your uncommitted edits as a git patch, carries non-ignored untracked files and the ignored files .pier/include lists, and runs .pier/setup.sh in its own tmux window. Then it attaches.

When the repo has a warm pool, the create claims a parked, set-up session instead: resume, check out your branch, re-push secrets, apply your dirty edits. Setup doesn’t run again, and a new session is ready in about 25 seconds.

Flags:

-d, --detach create without attaching
--idle <dur|never> park after this much idle time (default from settings)
--cap <dur|never> unattended runaway cap (default 8h)
--no-park shorthand for --idle never
--no-pool launch fresh instead of claiming a pooled session

Or press n in the app. Creates from the app run in the background and the row flips when ready.

The cloud says “running” long before a session is usable, so pier doesn’t:

  • A session lists as starting until the bootstrap’s last act marks the instance ready (a tag on AWS, a label on GCP). A session claimed from the pool reads starting too, until it’s resumed and on your branch.
  • Attaching early gets a plain “still setting up”, not a raw connection error.
  • (setup running) and (setup failed) surface the setup script outcome, and pier logs <session> shows why.
  • running (strained) flags sustained cpu or memory pressure (kernel PSI).
  • A deleted session lists as deleting until the cloud actually removes it. GCE takes a minute there and would otherwise read as parked.
  • A create that fails cleans up its own instance and lists as create failed until you clear it.

Rows show the steady state: starting, running, parked, deleting, or create failed. What a running session is doing right now (agent working, quiet, you’re attached) is in the app’s detail pane and in pier ls --json.

An in-VM supervisor samples every 5 seconds for attached (tmux clients, or a live forwarded TCP connection) and busy (a running setup script, agent process-tree CPU, recent pty output):

  • attached or busy resets the idle clock
  • detached and quiet past idle_timeout parks
  • detached but busy past unattended_cap parks anyway, so a looping agent can’t burn compute for days

A parked session costs disk-only prices, about $3-4 a month. Attach to resume:

$ pier attach checkout-flow
resuming checkout-flow (~20-60s)...

Files, git state, and installed tools survive parking. A wake also brings back the arrangement:

  • your tmux layout: windows, panes, cwds, and scrollback
  • claude and codex, reopened on their conversations
  • the Docker containers that were running when it parked

Other processes don’t survive the stop. A dev server started in a pane comes back as its command typed at the prompt, one Enter away, and an agent mid-turn stops at its last saved message. Setup never re-runs on a wake.

While you’re attached, the session uses your laptop’s browser:

  • anything in the session that opens a URL (an agent’s OAuth login, gh auth login, “open in browser”) opens it in your laptop’s browser
  • ports the session listens on (an OAuth callback, a dev server) are reachable at the same port on your laptop

That makes every in-session browser login work, for any agent or CLI. See Secrets and MCP.

Disable idle self-park for a session that should stay up:

pier keep <session>

Or press p in the app. The unattended cap still applies unless created with --cap never.

pier rm <session> [-f]

Destroys the session and its disk. Or press d in the app.