Running Background Agents and Scheduled Tasks
Offload long-running work — code reviews, memory consolidation, research — to background agents so your session stays responsive, and set up recurring tasks that run on a schedule.
Prerequisites
- A running pi session with the orchestrator extension loaded
- At least one specialist agent available (check with
/status)
Quick Example
Ask pi to run a code review in the background while you keep working:
Review the changes on this branch for security issues — run it in the background
The orchestrator dispatches the review agent asynchronously. You'll see ⏳ async: 1 in your status bar, and the result appears in your conversation when it finishes.
Check on it anytime:
/async-status
How Async Agents Work
When the orchestrator delegates a task with async: true, it spawns a detached pi process that runs independently. Your session stays free for other work.
There are two delivery modes:
| Mode | Result Delivery | Use Case |
|---|---|---|
| Tracked (default) | Result injected into your conversation when complete | Code reviews, research, analysis |
| Fire-and-forget | Terminal notification only, no conversation injection | Memory dreaming, maintenance tasks |
What Happens When an Async Agent Finishes
- A desktop/terminal notification fires: "Async agent Code Review completed (2m34s)"
- For tracked agents, the full output appears in your conversation as a follow-up message
- The status bar updates from
⏳ async: 1to⏳ async: 0
Monitoring Background Agents
Checking Status
Run /async-status to see all running and recently completed agents:
/async-status
If agents are running, you'll get an interactive selector. Pick one to see its live output — a scrollable view that updates in real time as the agent works.
| Key | Action |
|---|---|
| ↑/↓ | Scroll line by line |
| PgUp/PgDn | Scroll by page |
| Home/End | Jump to top/bottom |
| Esc | Close the viewer |
Tip: The status bar always shows the current async agent count (
⏳ async: N). You can also see async status via/statusfor a unified snapshot.
Killing Background Agents
To stop a runaway or unwanted agent:
/async-kill
This opens an interactive selector. Pick the agent to terminate.
You can also kill by name or kill all:
/async-kill code-reviewer-security
/async-kill all
Async-Only Agents
Certain agents are enforced to always run asynchronously. If the orchestrator tries to dispatch them synchronously, the system automatically promotes the call to async. These agents are:
code-reviewer-qualitycode-reviewer-guidelinescode-reviewer-security
This prevents your session from blocking on long-running reviews. See Running the Automated Code Review Loop for how reviews use async agents.
Note: Async-only agents cannot be used in chain mode (sequential steps with
{previous}placeholder). They must be dispatched as separate async tasks.
Scheduling Recurring Tasks with /cron
Use /cron to schedule tasks that run on a repeating interval or at a specific time each day.
Creating a Scheduled Task
Use natural language — the orchestrator parses your intent:
/cron run tests every 30 minutes
/cron check for new PRs every 2 hours
/cron summarize git log daily at 09:00
You can also schedule slash commands:
/cron run /dream every 4 hours
Listing Scheduled Tasks
/cron list
Output:
#1 | every 30m | run tests | last run: 14:30:00
#2 | every 2h | check for new PRs | last run: 13:00:00
#3 | at 09:00 | summarize git log | last run: never
To see cron tasks across all active pi sessions:
/cron list-all
Removing a Scheduled Task
/cron remove 2
You can remove multiple at once:
/cron remove 1 3
How Cron Tasks Execute
| Task Type | Behavior |
|---|---|
Starts with / |
Runs as a slash command in your session |
| Plain text prompt | Spawns a worker async agent with the prompt |
Note: Cron tasks are scoped to the pi process. They survive
/reload,/resume, and/newbut stop when you exit pi. The minimum interval is 10 seconds.
Schedule Types
| Type | Description | Example |
|---|---|---|
| Interval | Runs every N seconds/minutes/hours | /cron run tests every 15 minutes |
| Daily time | Runs once per day at a specific time | /cron deploy status at 08:30 |
Automatic Memory Dreaming
Pi includes a built-in background task that consolidates session memories on a timer. See Working with Project Memory for the full picture.
By default, dreaming runs every 3 hours as a fire-and-forget async agent and also triggers on session quit.
Toggle it:
/dream-auto off
/dream-auto on
Trigger a dream manually:
/dream
Configure the interval per-project in .pi/pi-config-settings.json:
{
"dream_interval_hours": 4
}
Valid range: 0.5–24 hours. You can also set it globally with the PI_DREAM_INTERVAL_HOURS environment variable. See Configuration and Environment Variables Reference for all settings.
Advanced Usage
Sync vs Async Decision
The orchestrator enforces a 30-second sync limit. Tasks estimated to take 30 seconds or longer must use async: true. The orchestrator handles this automatically, but understanding the rule helps:
| Duration | Mode | Orchestrator Blocks? |
|---|---|---|
| < 30s estimated | Sync (default) | Yes — waits for result |
| ≥ 30s estimated | Async required | No — returns immediately |
| Any code reviewer | Always async | No — auto-promoted |
For sync tasks, the orchestrator also enforces:
- Maximum 4 concurrent sync agents in parallel mode
- Maximum 8 parallel tasks total per subagent call
Parallel Async Dispatch
The orchestrator can spawn multiple async agents in a single turn. This is how the code review loop works — all three reviewers launch simultaneously:
Review the current changes — run all three reviewers in parallel
Each gets its own status entry and delivers results independently.
Using /status for a Unified View
The /status command gives you a snapshot of everything running:
/status
⏳ Async agents: 2 running
• Code Review Quality — 1m23s — Review changes on feat/issue-42
• Code Review Security — 1m23s — Review changes on feat/issue-42
⏰ Cron tasks: 1 active
• #1 every 30m — run tests (last: 14:30:00)
🌿 Git: feat/issue-42 ● 3 changed files (my-project)
See Using Slash Commands and Prompt Templates for details on /status and other commands.
Viewing Async Agents in the Web Dashboard
If you have the pidash web dashboard running, async agents appear there in real time — including live event streaming from each background agent. See Using the Web Dashboard and Diff Viewer for setup.
Troubleshooting
Async agent stuck as "running" forever
The poller checks if the agent's process is still alive. If the process died, the agent is automatically marked as failed. Zombie agents from previous sessions are cleaned up on session start. If you see a stuck agent, use /async-kill to terminate it.
Cron tasks disappeared after restarting pi
Cron tasks are tied to the pi process. When you exit pi and start a new session, previous crons are gone. Re-create them with /cron.
Async results not appearing in conversation
Fire-and-forget agents don't inject results — they only send a terminal notification. If a tracked agent's result is missing, check /async-status to see if it's still running or if it failed.
Debug logging for async agents
Set the PI_ASYNC_DEBUG environment variable to enable detailed logging:
PI_ASYNC_DEBUG=1 pi
Logs are written to the project temp directory under debug.log.