Skip to content

Building Features with Parallel Agents

Your product manager just broke a single epic into five subtasks: new API endpoint, database migration, frontend form, email notifications, and end-to-end tests. Traditionally, you would work through them sequentially — each one blocking on the last. With Codex worktrees, you can spin up five parallel agents that work on all five simultaneously, each in its own isolated branch. You review the diffs, sync the results, and ship the entire feature in an afternoon.

  • A plan-then-parallelize workflow that decomposes features into independent workstreams
  • Prompts for local planning in the IDE extension followed by parallel execution in worktrees
  • Techniques for merging results from multiple worktrees into a single feature branch
  • A cloud delegation pattern for long-running implementation tasks

Before you spin up any parallel agents, you need a plan that decomposes the work into independent pieces. Use the IDE extension for this — it has your open files as context and responds quickly for planning tasks.

Codex will typically identify a dependency graph. For example, the database migration must land first, then the API endpoint and notification service changes can run in parallel, and the frontend depends on the API being defined. The plan lets you know which worktrees to start immediately and which to queue.

Step 2: Start with the Foundation in Local Mode

Section titled “Step 2: Start with the Foundation in Local Mode”

For tasks that other work depends on — like a database migration — use Local mode so the changes land directly in your working directory and subsequent worktrees can build on them.

Commit the migration to your feature branch. Now every worktree you create from this branch will include the new schema.

Now the independent pieces can run simultaneously. In the Codex App, create a new thread for each task, selecting Worktree mode and choosing your feature branch (with the migration already committed) as the starting point.

Thread 1: API Endpoint

Implement CRUD endpoints for notification preferences:
- GET /api/users/:userId/notification-preferences
- PUT /api/users/:userId/notification-preferences/:type
- Zod validation for all inputs
- Auth middleware (user can only access their own preferences)
- Default preferences created on first GET if none exist
- Unit tests for validation, integration tests for the full endpoint
Use the notification_preferences schema from src/lib/db/schema.ts.
Run tests after implementation.

Thread 2: Notification Service Update

Update the notification service to check user preferences before sending:
- Before sending any notification, query notification_preferences for the user
- If no preferences exist, use defaults (all channels enabled)
- If the user has disabled a channel for that notification type, skip it
- Add structured logging for skipped notifications
- Unit tests with mocked preferences
- Do not change the existing notification sending interface
Read the current notification service in src/services/notifications/ first.

Thread 3: Frontend Settings Page

Create a notification preferences settings page:
- Route: /settings/notifications
- Fetch current preferences from GET /api/users/:userId/notification-preferences
- Display a grid: notification types as rows, channels as columns
- Toggle switches for each combination
- Save changes with PUT on toggle
- Loading states and error handling
- Match the existing settings page styling in src/pages/settings/
Use React and follow our component patterns. Include tests.

All three threads run simultaneously in separate worktrees. You can watch their progress in the Codex App sidebar, switch between threads, and leave inline comments if you see something that needs correction.

As each thread completes, review the diff in the review pane. You have two strategies for getting the changes back together:

Strategy A: Create branches and merge via Git. Click Create branch here on each worktree thread. Push each branch and merge them into your feature branch one at a time, resolving any conflicts.

Strategy B: Sync to local sequentially. Use Sync with local on each worktree, choosing the Apply method to layer each set of changes onto your local checkout. This keeps your commit history cleaner since the changes arrive as patches rather than merge commits.

For tasks that take longer — running full test suites, building containers, or implementing complex business logic — delegate to cloud execution. The cloud agent has more resources, can run for longer, and supports best-of-N attempts.

In the Codex App, select the cloud icon below the composer and choose your cloud environment:

Implement Milestone 1 from the plan: the notification preferences API endpoints with full test coverage. Run the complete test suite after implementation and fix any failures.

Cloud tasks generate a diff you can review and turn into a PR directly, or pull locally for further iteration.

Worktrees share node_modules via the git worktree, but not always. If your project has workspace-level dependencies, worktrees should inherit them. But if each worktree runs npm install independently, you may hit lockfile conflicts. Set up your local environment’s setup script to use npm ci (which respects the lockfile) rather than npm install.

Parallel threads make conflicting architectural decisions. If Thread 1 decides the response format should be { data: [...] } and Thread 2 expects { preferences: [...] }, they will not integrate cleanly. This is why Step 1 matters — the plan should specify shared interfaces before parallel work begins.

Worktree cleanup deletes a thread you needed. Worktrees are eligible for cleanup after 4 days or when you exceed 10 total. Pin important threads or add the worktree to the sidebar to prevent automatic deletion. If a worktree was already cleaned up, Codex saves a snapshot you can restore from the thread view.

Cloud task uses the wrong branch. Cloud tasks default to the repository’s default branch. If your foundation migration is on a feature branch, the cloud agent will not see the new schema. Specify the branch explicitly in your cloud environment settings, or describe the schema in your prompt.