Skip to main content

Use Startup Waves

Use waves to make startup order explicit without serializing everything.

FlowLayer does not have a manual wave field. Waves are derived from dependsOn using topological planning. See Waves for the model details.

Build waves from dependencies

{
"services": {
"db": {
"cmd": ["docker", "compose", "up", "postgres"],
"port": 5432,
"ready": {
"type": "tcp"
}
},
"api": {
"cmd": ["pnpm", "--dir", "services/api", "dev"],
"dependsOn": ["db"],
"ready": {
"type": "http",
"url": "http://127.0.0.1:3000/health"
}
},
"web": {
"cmd": ["pnpm", "--dir", "web", "dev"],
"dependsOn": ["api"],
"ready": {
"type": "tcp",
"port": 5173
}
}
}
}

Expected graph-derived order:

  • wave 0: db
  • wave 1: api
  • wave 2: web

Group independent services in the same wave

If two services do not depend on each other, keep them independent so they start in parallel:

{
"services": {
"db": {
"cmd": ["docker", "compose", "up", "postgres"],
"ready": {
"type": "tcp",
"port": 5432
}
},
"api": {
"cmd": ["pnpm", "--dir", "services/api", "dev"],
"dependsOn": ["db"]
},
"worker": {
"cmd": ["pnpm", "--dir", "services/worker", "dev"],
"dependsOn": ["db"]
},
"web": {
"cmd": ["pnpm", "--dir", "web", "dev"],
"dependsOn": ["api"]
}
}
}

Typical plan:

  • wave 0: db
  • wave 1: api, worker
  • wave 2: web

Avoid unnecessary dependencies

Over-declaring dependsOn reduces parallelism and slows startup.

Bad example for local dev:

  • web depends on worker even when web traffic does not require worker startup.

Prefer only hard requirements:

  • web depends on api
  • worker depends on db (or api only if truly required)

Detect and fix cycles

A cycle is rejected before any service starts.

Cycle example:

{
"services": {
"api": {
"cmd": "api",
"dependsOn": ["worker"]
},
"worker": {
"cmd": "worker",
"dependsOn": ["api"]
}
}
}

Planning fails with an error shaped like:

dependency cycle detected among services: [api worker]

Fix it by removing the false dependency edge or introducing a real prerequisite service that both depend on.

Operational tip

Use waves for dependency control, then use readiness probes for correctness at each edge. The combination gives deterministic startup and fewer race conditions.

Continue with Add Readiness Checks for practical probe patterns.