Wave Planning Strategies
Wave planning is the process of organizing tasks into execution groups (waves) that balance parallelism, dependencies, and resource constraints. This guide covers advanced strategies for optimal wave planning.
Table of Contents
- Core Concepts
- Dependency Optimization
- Parallel vs Sequential Trade-offs
- Common Anti-patterns
- Best Practices
- Real-world Examples
Core Concepts
What is a Wave?
A wave is a group of tasks that can execute in parallel without violating dependency constraints. Orchex automatically organizes your manifest tasks into waves using topological sorting.
# Simple wave example
tasks:
- id: setup
prompt: "Initialize project structure"
# Wave 0: No dependencies
- id: implement
prompt: "Implement feature"
dependencies: [setup]
# Wave 1: Depends on setup
- id: test
prompt: "Write tests"
dependencies: [implement]
# Wave 2: Depends on implementWave Properties
- Wave Number: Sequential index (0, 1, 2, ...)
- Parallelism: All tasks in a wave can execute simultaneously
- Dependencies: No task depends on another task in the same wave
- Blocking: A wave must complete before the next wave starts
Dependency Optimization
Minimize Dependency Chains
Problem: Long dependency chains create sequential bottlenecks.
# ❌ Bad: Artificial linear chain
tasks:
- id: task1
prompt: "Do A"
- id: task2
prompt: "Do B" # Actually independent!
dependencies: [task1]
- id: task3
prompt: "Do C" # Actually independent!
dependencies: [task2]
- id: task4
prompt: "Do D"
dependencies: [task3]This creates 4 waves when only 1 is needed.
# ✅ Good: Parallel execution
tasks:
- id: task1
prompt: "Do A"
- id: task2
prompt: "Do B"
- id: task3
prompt: "Do C"
- id: task4
prompt: "Do D"
# All execute in Wave 0Declare Only True Dependencies
Principle: A dependency exists only if Task B requires Task A's output or side effects.
# ❌ Bad: False dependency
tasks:
- id: update-readme
prompt: "Update README with new features"
- id: add-tests
prompt: "Add unit tests"
dependencies: [update-readme] # Tests don't need README!
# ✅ Good: Independent tasks
tasks:
- id: update-readme
prompt: "Update README with new features"
- id: add-tests
prompt: "Add unit tests"
# Both execute in parallelUse Partial Dependencies
When multiple tasks share some dependencies, find the minimal set.
# ❌ Bad: Over-specification
tasks:
- id: models
prompt: "Create database models"
- id: api
prompt: "Create API endpoints"
dependencies: [models]
- id: tests
prompt: "Write API tests"
dependencies: [models, api] # models is redundant
- id: docs
prompt: "Document API"
dependencies: [models, api] # models is redundant
# ✅ Good: Minimal dependencies
tasks:
- id: models
prompt: "Create database models"
- id: api
prompt: "Create API endpoints"
dependencies: [models]
- id: tests
prompt: "Write API tests"
dependencies: [api] # Implies models
- id: docs
prompt: "Document API"
dependencies: [api] # Implies modelsDependency Graph Metrics
Critical Path Length: The longest chain of dependencies
- Target: Minimize this to reduce total execution time
- Formula:
max(wave_number) + 1
Average Wave Size: Tasks per wave
- Target: Maximize this for better parallelism
- Formula:
total_tasks / number_of_waves
Parallelism Ratio: Actual vs potential parallelism
- Target: Close to 1.0 for optimal planning
- Formula:
total_tasks / (critical_path_length * max_concurrent_tasks)
Parallel vs Sequential Trade-offs
When to Prefer Parallel Execution
Advantages:
- Faster total execution time
- Better resource utilization
- Independent failure domains
Use cases:
# ✅ Parallel: Independent features
tasks:
- id: feature-a
prompt: "Implement feature A"
- id: feature-b
prompt: "Implement feature B"
- id: feature-c
prompt: "Implement feature C"Advantages:
- Clearer context for each task
- Reduced file conflicts
- Easier debugging
When to Prefer Sequential Execution
Advantages:
- Consistent context across tasks
- Simpler reasoning about state
- Reduced merge conflicts
Use cases:
# ✅ Sequential: Building on previous work
tasks:
- id: design-schema
prompt: "Design database schema"
- id: implement-models
prompt: "Implement models based on schema"
dependencies: [design-schema]
- id: add-migrations
prompt: "Create migrations for models"
dependencies: [implement-models]Hybrid Strategies
Combine parallel and sequential for optimal results.
# ✅ Hybrid: Parallel features, sequential implementation
tasks:
# Wave 0: Setup (sequential foundation)
- id: setup-db
prompt: "Setup database structure"
# Wave 1: Parallel feature streams
- id: auth-models
prompt: "Create auth models"
dependencies: [setup-db]
- id: billing-models
prompt: "Create billing models"
dependencies: [setup-db]
- id: api-models
prompt: "Create API models"
dependencies: [setup-db]
# Wave 2: Parallel services
- id: auth-service
prompt: "Implement auth service"
dependencies: [auth-models]
- id: billing-service
prompt: "Implement billing service"
dependencies: [billing-models]
- id: api-service
prompt: "Implement API service"
dependencies: [api-models]
# Wave 3: Integration (needs all services)
- id: integration
prompt: "Integrate all services"
dependencies: [auth-service, billing-service, api-service]Resource Considerations
Memory Constraints: Too much parallelism can exhaust memory
# Consider: Will these tasks fit in memory simultaneously?
tasks:
- id: process-data-1
prompt: "Process large dataset 1" # 4GB RAM
- id: process-data-2
prompt: "Process large dataset 2" # 4GB RAM
- id: process-data-3
prompt: "Process large dataset 3" # 4GB RAM
# 12GB total - may exceed available memory!Solution: Add artificial dependencies to limit concurrency
tasks:
- id: process-data-1
prompt: "Process large dataset 1"
- id: process-data-2
prompt: "Process large dataset 2"
dependencies: [process-data-1] # Serialize to manage memory
- id: process-data-3
prompt: "Process large dataset 3"
dependencies: [process-data-2]API Rate Limits: Parallel tasks may hit rate limits
# If tasks make external API calls, consider rate limits
tasks:
- id: fetch-data-batch-1
prompt: "Fetch data from API (batch 1)"
- id: fetch-data-batch-2
prompt: "Fetch data from API (batch 2)"
# Both parallel may exceed rate limitCommon Anti-patterns
1. The Monolith Task
Problem: One giant task that should be split into waves.
# ❌ Anti-pattern
tasks:
- id: do-everything
prompt: |
1. Setup project structure
2. Implement all features
3. Write all tests
4. Update documentation
5. Add CI/CDSolution: Break into logical waves
# ✅ Better
tasks:
- id: setup
prompt: "Setup project structure"
- id: feature-1
prompt: "Implement feature 1"
dependencies: [setup]
- id: feature-2
prompt: "Implement feature 2"
dependencies: [setup]
- id: tests
prompt: "Write comprehensive tests"
dependencies: [feature-1, feature-2]
- id: docs
prompt: "Update documentation"
dependencies: [feature-1, feature-2]
- id: ci-cd
prompt: "Add CI/CD pipeline"
dependencies: [tests]2. The Dependency Web
Problem: Every task depends on every other task.
# ❌ Anti-pattern: Circular or over-connected dependencies
tasks:
- id: task-a
dependencies: [task-b, task-c, task-d]
- id: task-b
dependencies: [task-a, task-c, task-d]
- id: task-c
dependencies: [task-a, task-b, task-d]
- id: task-d
dependencies: [task-a, task-b, task-c]Solution: Identify true dependencies and create layers
# ✅ Better: Clear layering
tasks:
- id: foundation
prompt: "Create foundation"
- id: layer-1-a
prompt: "Build component A"
dependencies: [foundation]
- id: layer-1-b
prompt: "Build component B"
dependencies: [foundation]
- id: integration
prompt: "Integrate components"
dependencies: [layer-1-a, layer-1-b]Note on
orchex learnauto-resolution: When cycles arise from mutual file-ownership (stream A reads stream B's file AND stream B reads stream A's file),orchex learnautomatically drops these false dependencies — they represent context reads, not sequencing requirements. Cycles involving explicitdepsor content-pattern dependencies are preserved and reported as errors. Iforchex learnreports a cycle, restructure your plan to break the circular dependency chain.
3. The Premature Convergence
Problem: Forcing parallel work to converge too early.
# ❌ Anti-pattern
tasks:
- id: feature-a-step-1
prompt: "Start feature A"
- id: feature-b-step-1
prompt: "Start feature B"
- id: checkpoint # Unnecessary synchronization
prompt: "Review progress"
dependencies: [feature-a-step-1, feature-b-step-1]
- id: feature-a-step-2
prompt: "Continue feature A"
dependencies: [checkpoint]
- id: feature-b-step-2
prompt: "Continue feature B"
dependencies: [checkpoint]Solution: Let parallel work complete independently
# ✅ Better
tasks:
- id: feature-a-step-1
prompt: "Start feature A"
- id: feature-a-step-2
prompt: "Continue feature A"
dependencies: [feature-a-step-1]
- id: feature-a-step-3
prompt: "Complete feature A"
dependencies: [feature-a-step-2]
- id: feature-b-step-1
prompt: "Start feature B"
- id: feature-b-step-2
prompt: "Continue feature B"
dependencies: [feature-b-step-1]
- id: feature-b-step-3
prompt: "Complete feature B"
dependencies: [feature-b-step-2]
- id: final-integration # Only converge when necessary
prompt: "Integrate features A and B"
dependencies: [feature-a-step-3, feature-b-step-3]4. The Diamond Problem (Redundant Paths)
Problem: Multiple paths to the same dependency.
# ❌ Anti-pattern: Over-specification
tasks:
- id: base
prompt: "Create base"
- id: middle
prompt: "Build on base"
dependencies: [base]
- id: top
prompt: "Complete feature"
dependencies: [base, middle] # base is redundantSolution: Declare only direct dependencies
# ✅ Better
tasks:
- id: base
prompt: "Create base"
- id: middle
prompt: "Build on base"
dependencies: [base]
- id: top
prompt: "Complete feature"
dependencies: [middle] # Implies base5. The False Sequence
Problem: Adding dependencies for organizational purposes, not technical reasons.
# ❌ Anti-pattern: Grouping by category, not dependency
tasks:
- id: frontend-1
prompt: "Frontend task 1"
- id: frontend-2
prompt: "Frontend task 2"
dependencies: [frontend-1] # No actual dependency!
- id: frontend-3
prompt: "Frontend task 3"
dependencies: [frontend-2] # No actual dependency!
- id: backend-1
prompt: "Backend task 1"
dependencies: [frontend-3] # Why?Solution: Use task names for organization, dependencies for requirements
# ✅ Better
tasks:
- id: frontend-component-a
prompt: "Build frontend component A"
- id: frontend-component-b
prompt: "Build frontend component B"
- id: frontend-component-c
prompt: "Build frontend component C"
- id: backend-api
prompt: "Build backend API"
- id: backend-integration
prompt: "Integrate frontend with backend"
dependencies: [frontend-component-a, frontend-component-b,
frontend-component-c, backend-api]Best Practices
1. Design Waves Bottom-Up
Start with foundational tasks, then build up:
tasks:
# Wave 0: Foundation
- id: setup-project
prompt: "Initialize project structure"
- id: setup-config
prompt: "Setup configuration"
# Wave 1: Core components
- id: core-types
prompt: "Define core types"
dependencies: [setup-project]
- id: core-utils
prompt: "Create utility functions"
dependencies: [setup-project]
# Wave 2: Features
- id: feature-auth
prompt: "Implement authentication"
dependencies: [core-types, core-utils]
- id: feature-api
prompt: "Implement API layer"
dependencies: [core-types, core-utils]
# Wave 3: Testing & docs
- id: tests
prompt: "Add comprehensive tests"
dependencies: [feature-auth, feature-api]
- id: documentation
prompt: "Write documentation"
dependencies: [feature-auth, feature-api]2. Use Meaningful Task IDs
Good task IDs communicate purpose and relationships:
# ✅ Clear naming convention
tasks:
- id: db-schema-users
- id: db-schema-posts
- id: db-migrations-001
- id: api-users-routes
- id: api-posts-routes
- id: test-api-users
- id: test-api-posts3. Document Wave Strategy
Add comments explaining your wave design:
tasks:
# WAVE 0: Database Foundation
# These must complete first as all features depend on them
- id: db-schema
prompt: "Design complete database schema"
# WAVE 1: Parallel Feature Development
# Each feature is independent and can be developed simultaneously
- id: auth-feature
prompt: "Implement authentication feature"
dependencies: [db-schema]
- id: billing-feature
prompt: "Implement billing feature"
dependencies: [db-schema]
- id: analytics-feature
prompt: "Implement analytics feature"
dependencies: [db-schema]
# WAVE 2: Integration Layer
# Requires all features to be complete
- id: feature-integration
prompt: "Integrate all features"
dependencies: [auth-feature, billing-feature, analytics-feature]4. Validate Your Wave Plan
Before executing, check:
- Can any sequential tasks be made parallel?
- Are all dependencies truly necessary?
- Is the critical path minimized?
- Are wave sizes balanced?
- Will resource constraints be respected?
- Are task scopes reasonable?
5. Use Context Propagation Wisely
tasks:
- id: design-api
prompt: "Design RESTful API structure"
context: ["docs/api-requirements.md"]
- id: implement-api
prompt: "Implement the API design"
dependencies: [design-api]
# Context automatically includes design-api's output
- id: test-api
prompt: "Write API tests"
dependencies: [implement-api]
# Context includes both design and implementationReal-world Examples
Example 1: Full-Stack Feature
feature: "Add user profile management"
tasks:
# Wave 0: Database
- id: profile-schema
prompt: "Design user profile database schema"
context: ["src/db/schema.ts"]
# Wave 1: Implementation layers (parallel)
- id: profile-model
prompt: "Implement profile data model"
dependencies: [profile-schema]
outputs: ["src/models/profile.ts"]
- id: profile-api
prompt: "Create profile API endpoints"
dependencies: [profile-schema]
outputs: ["src/api/profile.ts"]
- id: profile-ui
prompt: "Build profile UI components"
dependencies: [profile-schema]
outputs: ["src/components/Profile.tsx"]
# Wave 2: Integration
- id: profile-integration
prompt: "Integrate model, API, and UI"
dependencies: [profile-model, profile-api, profile-ui]
# Wave 3: Quality (parallel)
- id: profile-tests
prompt: "Write comprehensive tests"
dependencies: [profile-integration]
- id: profile-docs
prompt: "Document profile feature"
dependencies: [profile-integration]Wave breakdown:
- Wave 0: 1 task (schema design)
- Wave 1: 3 tasks (parallel implementation)
- Wave 2: 1 task (integration)
- Wave 3: 2 tasks (parallel quality)
Total: 7 tasks in 4 waves = 1.75 tasks/wave average
Example 2: Refactoring Project
feature: "Refactor authentication system"
tasks:
# Wave 0: Analysis
- id: analyze-current-auth
prompt: "Analyze current authentication implementation"
context: ["src/auth/"]
# Wave 1: New implementation (parallel by component)
- id: auth-tokens
prompt: "Refactor token management"
dependencies: [analyze-current-auth]
outputs: ["src/auth/tokens.ts"]
- id: auth-sessions
prompt: "Refactor session handling"
dependencies: [analyze-current-auth]
outputs: ["src/auth/sessions.ts"]
- id: auth-middleware
prompt: "Refactor authentication middleware"
dependencies: [analyze-current-auth]
outputs: ["src/auth/middleware.ts"]
# Wave 2: Integration & migration
- id: auth-integration
prompt: "Integrate new auth components"
dependencies: [auth-tokens, auth-sessions, auth-middleware]
- id: auth-migration
prompt: "Create migration script for existing users"
dependencies: [auth-integration]
# Wave 3: Validation
- id: auth-tests
prompt: "Update and expand auth tests"
dependencies: [auth-migration]
- id: auth-cleanup
prompt: "Remove old auth code"
dependencies: [auth-tests]Example 3: Multi-service System
feature: "Build microservices architecture"
tasks:
# Wave 0: Shared foundation
- id: shared-types
prompt: "Define shared types and interfaces"
- id: shared-config
prompt: "Setup shared configuration"
# Wave 1: Individual services (fully parallel)
- id: user-service
prompt: "Implement user service"
dependencies: [shared-types, shared-config]
- id: order-service
prompt: "Implement order service"
dependencies: [shared-types, shared-config]
- id: payment-service
prompt: "Implement payment service"
dependencies: [shared-types, shared-config]
- id: notification-service
prompt: "Implement notification service"
dependencies: [shared-types, shared-config]
# Wave 2: Service communication
- id: api-gateway
prompt: "Setup API gateway"
dependencies: [user-service, order-service,
payment-service, notification-service]
- id: service-mesh
prompt: "Configure service mesh"
dependencies: [user-service, order-service,
payment-service, notification-service]
# Wave 3: Operations
- id: monitoring
prompt: "Setup monitoring and logging"
dependencies: [api-gateway, service-mesh]
- id: deployment
prompt: "Create deployment configurations"
dependencies: [api-gateway, service-mesh]Wave breakdown:
- Wave 0: 2 tasks (shared foundation)
- Wave 1: 4 tasks (parallel services)
- Wave 2: 2 tasks (parallel infrastructure)
- Wave 3: 2 tasks (parallel operations)
Parallelism ratio: 10 tasks / 4 waves = 2.5 tasks/wave
Conclusion
Effective wave planning is about finding the right balance between:
- Speed (maximum parallelism)
- Clarity (logical sequences)
- Resources (practical constraints)
- Maintainability (understandable structure)
Key takeaways:
- Minimize critical path length by maximizing parallelism
- Declare only true dependencies to avoid false sequences
- Balance wave sizes for consistent execution patterns
- Document your strategy for future maintainers
- Validate before executing to catch planning errors
When in doubt, prefer parallel execution unless there's a clear technical dependency. The Orchex planner will handle the complexity of orchestrating your tasks efficiently.