Openbook

The Critical Path Method, Explained for Software Teams

CPM without the PMP jargon: forward and backward passes, float, a worked release example, and when critical path thinking beats a Kanban board.

Project ManagementOpenbook Team14 min read

Your release has ten workstreams, and exactly one of them determines the launch date. The other nine could each slip by days without moving anything. Most software teams cannot name which one is which — so they treat every slip as an emergency, pad every estimate, and still get surprised when the date moves.

The Critical Path Method (CPM) is the sixty-year-old technique that answers this precisely. It came out of chemical-plant construction and defense projects in the late 1950s, got buried under enterprise project-management ceremony, and was then thrown out by agile teams along with the ceremony. That was overcorrection. The math takes ten minutes to learn, works on a whiteboard, and answers questions your Kanban board structurally cannot: What is the earliest this release can land? Which tasks can slip without consequence, and by how much? Where would adding a person actually help?

This guide teaches CPM with a worked software release you can follow line by line, then covers float, how to use CPM alongside sprints, what tooling to use, and — honestly — where the method breaks down.

The core idea in three sentences

Every project is a network of tasks connected by dependencies. The critical path is the longest chain of dependent tasks through that network — longest in duration, not in task count — and its length is the minimum possible project duration. Every task not on that chain has float: a measurable amount of slip it can absorb before it matters.

Two consequences follow immediately, and both are counterintuitive enough to be worth money:

  1. Speeding up a non-critical task does nothing. Finishing the docs three days early does not move a launch gated by QA. Effort spent accelerating off-path work is, from the schedule's point of view, wasted.
  2. A one-day slip on the critical path slips the whole project by one day. There is no buffer on the critical path by definition. This is why "it's just one day" is sometimes true and sometimes catastrophic, and why you need to know which tasks are which.

The worked example: a billing release

Here is a realistic release — shipping usage-based billing — broken into ten tasks with estimates in working days and explicit dependencies:

ID Task Duration Depends on
A Finalize pricing model 3d
B Design invoice templates 2d A
C Build billing engine 8d A
D Payment provider integration 6d A
E Build invoice UI 4d B
F Connect engine to provider 3d C, D
G Data migration script 5d C
H End-to-end QA 4d E, F, G
I Docs and support training 3d E
J Launch checklist and cutover 1d H, I

Ten tasks, 39 days of total work. If one person did everything serially: 39 days. With unlimited people: how fast? That is what the forward pass computes.

The forward pass: earliest start and finish

Walk the network left to right. Each task's earliest start (ES) is the latest earliest finish among its dependencies; its earliest finish (EF) is ES + duration. Day numbers below are "working days from kickoff":

  • A: ES 0 → EF 3
  • B: starts after A: ES 3 → EF 5
  • C: ES 3 → EF 11
  • D: ES 3 → EF 9
  • E: after B: ES 5 → EF 9
  • F: after C and D — C finishes later: ES 11 → EF 14
  • G: after C: ES 11 → EF 16
  • H: after E (9), F (14), G (16) — gated by G: ES 16 → EF 20
  • I: after E: ES 9 → EF 12
  • J: after H (20) and I (12): ES 20 → EF 21

Earliest possible launch: day 21. No amount of staffing changes that number without changing the network itself, because 21 days is the length of the longest dependency chain: A → C → G → H → J (3 + 8 + 5 + 4 + 1 = 21). That chain is the critical path.

The backward pass: latest start and float

Now walk right to left, asking: how late can each task finish without pushing launch past day 21? Each task's latest finish (LF) is the earliest latest start among the tasks that depend on it; latest start (LS) is LF − duration. Float = LS − ES (equivalently LF − EF).

ID ES EF LS LF Float Critical?
A 0 3 0 3 0 Yes
B 3 5 10 12 5 No
C 3 11 3 11 0 Yes
D 3 9 7 13 4 No
E 5 9 12 16 7 No
F 11 14 13 16 2 No
G 11 16 11 16 0 Yes
H 16 20 16 20 0 Yes
I 9 12 17 20 8 No
J 20 21 20 21 0 Yes

Ten minutes of arithmetic just bought you a set of managerial facts no standup would surface:

  • The payment integration (D) can slip four days before anyone should care. If the provider's sandbox goes down for a day, that is annoying, not an emergency. Without CPM, this slip triggers the same alarm as any other.
  • Docs (I) have eight days of float. The tech writer can be borrowed by another project for a week and this launch does not move.
  • The migration script (G) is critical, and almost nobody would have guessed it. It looks like a background chore, it is probably assigned to whoever was free, and every day it slips moves launch a day. It deserves your strongest available engineer and daily attention.
  • F has only two days of float — near-critical. If C slips even slightly while D holds, F joins the critical path. Near-critical tasks (float ≤ 2 days, say) deserve almost as much monitoring as critical ones.

That last point is the practical rhythm of CPM: the critical path is not a one-time computation but a live property. When G finishes in three days instead of five, recompute — the path may reroute through F, and your attention should reroute with it.

What float is for

Float is not permission to slack; it is a management resource you can spend deliberately:

  • Sequencing people: The engineer assigned to D (4 days of float) is your swing capacity. If C struggles, moving them to help C spends D's float to protect the critical path — a trade you can now make with numbers instead of vibes.
  • Scheduling around life: The designer on B wants Thursday and Friday off. B has five days of float. Approve it without a second thought — and without the reflexive "let me see if we can absorb it" that teams perform when nobody knows what absorbs what.
  • Absorbing discovery: When QA (H) finds a bug in the invoice UI (E), E's owner has seven days of float to fix it in before the fix itself threatens launch.

One caution: float is shared along a chain, not owned per task. B and E sit on the same side branch; if B spends five days of slip, E's float is gone too. This is why teams that "know we have slack" still get surprised — the slack was counted twice.

Why software teams dropped CPM, and why that went too far

The objections are real, so state them fairly. Software estimates are noisy — a task estimated at 8 days can take 3 or 15, and a critical path computed from fiction is fiction with extra columns. Software dependencies are softer than construction dependencies — you can often start the UI against a mocked API, where you cannot pour a floor before the foundation. And knowledge work discovers tasks mid-flight that no upfront network anticipated.

All true. None of it makes the method useless; it changes where the method applies:

Use CPM when the work is date-driven and dependency-shaped: releases with external commitments (a conference, a contract, a regulatory deadline), migrations with hard cutover windows, launches coordinating engineering + marketing + legal + support, hardware-adjacent work with lead times. In these cases, the question "what actually determines the date?" has a factual answer, and guessing at it instead is negligence with better branding.

Skip CPM for continuous flow: an ops queue, a stream of independent features, bug triage. No meaningful dependency network means no meaningful path — flow metrics and WIP limits are the right instruments there, and a board beats a timeline. The honest tradeoff between the two views is its own topic; see Gantt Charts Are Not Dead for when timelines beat boards, and use both when both questions matter.

As for estimate noise: CPM degrades gracefully if you let it. You do not need precise estimates — you need honest rough ones, because the critical path is often robust to noise. In our example, C could be 6 or 10 days instead of 8 and the path A→C→G→H→J does not change; only the launch date shifts. What breaks the analysis is a missing dependency, not a wrong duration. Spend your care on the arrows, not the numbers.

Dependency types, lag, and lead

Everything above used the simplest dependency: finish-to-start (B cannot start until A finishes). Real plans occasionally need the other flavors, and knowing them prevents the common workaround of inventing fake tasks to model timing:

Type Meaning Software example
Finish-to-start (FS) B starts after A finishes QA starts after the feature is code-complete. The default; 90% of your arrows.
Start-to-start (SS) B can start once A has started Writing test cases can begin once development begins — you don't need the finished code to start on the spec's happy paths.
Finish-to-finish (FF) B can't finish until A finishes Documentation can be drafted anytime, but can't be finalized until the UI is final.
Start-to-finish (SF) B can't finish until A starts Legitimately rare. The old system's decommission can't complete until the new system is live. If you're using SF more than once per plan, re-examine the model.

Lag adds a mandatory wait to a dependency: "app-store review, submit + 3 days" is an FS arrow with 3 days of lag — no staffing decision can compress it, which is exactly why it belongs in the network rather than in someone's head. Compliance waiting periods, cache-warming windows, and customer-notice periods are all lag, and forgotten lag is one of the most common sources of a wrong critical path.

Lead is negative lag — a sanctioned overlap: "docs can start 2 days before UI freeze." Lead is fast-tracking, formalized. Model it explicitly rather than quietly starting early, because an explicit lead shows up in the passes and a quiet one silently invalidates them.

The practical guidance: default everything to FS, introduce SS/FF only where the FS version would force you to invent an artificial "first half of X" task, and audit every lag in the plan once — external waits have a habit of being longer than the optimistic number someone typed in ("app review is usually 24 hours").

Applying CPM inside an agile cadence

CPM and sprints answer different questions and coexist cleanly if you let each do its job: the network answers "when can the release land and what gates it?"; the sprint answers "what is the team doing for the next two weeks?" The practical fusion:

  1. Build the network at release planning, at milestone granularity. Ten to thirty nodes, not three hundred. "Billing engine ready" is a node; its constituent stories are not. Chains of stories within one team inside one sprint do not need CPM — that is what the sprint is for. Cross-team and cross-week dependencies are exactly what CPM is for. (Identifying those dependencies honestly is its own discipline — Managing Dependencies Before They Manage You covers the mapping and the cross-team contracts.)
  2. Feed the critical path into sprint prioritization. Critical-path items enter sprints first and never wait for "a good sprint to fit them in." Float-rich items are your backlog's flexible filler. In our example, a sprint planner who knows G is critical staffs it Monday morning with the strongest engineer, not Thursday with whoever finished early.
  3. Walk the path weekly, not the whole plan. The status question for a release is not "how are all ten tasks?" — it is "how are the five critical tasks, and did any near-critical task lose its float?" That is a five-minute check. When a critical task slips, you have exactly three levers, covered next.
  4. Recompute on every finish or slip. The path is dynamic. This is tedious by hand and trivial in tooling, which is the main reason to use tooling at all.

The three levers when the critical path slips

When launch is gated and the date is fixed, every response is a version of one of these:

  • Crash — add resources to critical tasks. Works when the task parallelizes (QA test suites, migration batches); fails famously when it does not (nine women, one month, one baby). Crash the cheapest-to-crash critical task, which is rarely the one currently late.
  • Fast-track — overlap tasks that were planned as sequential, accepting rework risk. Start QA (H) against the parts of the system that are done instead of waiting for all of E, F, G. Fast-tracking converts schedule risk into quality risk; say so out loud when you choose it.
  • De-scope — shorten the path by shrinking nodes. Ship with the migration covering the 95% of accounts on standard plans; handle the long tail post-launch. This changes the network itself, which is why it is usually the most powerful lever — and the one that requires a product decision rather than a heroic engineering one.

Presenting a slip as a three-option decision ("crash QA with two loaners for ~$X of opportunity cost, fast-track and accept rework risk, or de-scope the tail — recommend de-scope") is what separates escalation from confession. It also reuses everything above: you cannot price the options without knowing the path and the floats.

Tooling: whiteboard first, then software

Learn the method by hand once — the worked example above is a fine template — because hand-computing one network permanently changes how you read every plan afterward. After that, doing the passes manually on a live project is a waste of your time.

What to actually look for in tooling, in priority order: dependencies you can draw directly on a timeline; automatic critical-path highlighting that updates as tasks move; milestones as first-class objects; and import from wherever your task truth already lives, because a plan maintained by re-typing dies in two weeks. Openbook's Gantt room covers this set — drawn dependencies, built-in critical path highlighting, milestones, day/week/month zoom, and import from your existing boards, so the network stays wired to the tasks the team is really working. Whatever tool you pick, the operating rule is the same: the Gantt is the release's dependency truth, the board is the team's daily truth, and they must reference the same items or one of them is decorative.

A note on granularity, because it kills more CPM adoptions than any tooling gap: a 300-task Gantt maintained by one project manager is a full-time fiction. Keep the network at the milestone level, let boards carry the fine grain, and CPM stays a ten-minute weekly habit instead of a job description. If you find yourself scheduling individual code reviews on a timeline, zoom out. For how milestone-level planning connects to roadmap commitments, see Milestone Planning: Turning a Roadmap into Commitments.

The honest limits

Three failure modes to respect:

The path is only as real as the arrows. CPM's classic silent failure is the missing dependency — nobody wrote down that legal review gates the pricing page, so the computed path was wrong and the real one ran through a lawyer's vacation. The fix is social, not mathematical: build the network in a room with every function represented, and ask each task's owner one question — "what do you need in hand before you can start?" — rather than asking a PM to guess.

Deterministic dates from probabilistic work. A single-number duration hides a distribution. Where uncertainty is large and the date matters enormously, use ranges and check whether the path is stable across the pessimistic case (the near-critical F-branch in our example flips critical if C runs 20% long). You rarely need Monte Carlo machinery; you need to ask "what does the path look like if the risky task doubles?" once per plan.

The map can become the work. In heavyweight orgs, the plan file becomes an artifact that gets groomed, reviewed, and defended while reality drifts. The countermeasure is cadence and ownership: the network gets fifteen minutes weekly, it is updated from real task states, and it exists to answer two questions — what gates the date, and where is the float. The moment updating the plan takes longer than the decisions it informs, cut nodes.

Next steps

Take your nearest date-driven effort — a release, a migration, an event — and run the exercise this week: list 10–25 milestone-level tasks, draw the arrows by asking each owner what they need in hand to start, run the forward and backward passes, and mark the path and the floats. Budget an hour. Then change three behaviors: staff the critical tasks first, stop escalating slips on float-rich tasks, and walk the path — not the task list — in your weekly review.

When you outgrow the whiteboard, Openbook's Gantt room keeps the path computed live against your real boards, with milestones and drawn dependencies — one of 18 room types you can add to a space in a minute. Start free at openbook.work, and find out which of your ten workstreams is actually holding the date.

Keep reading

Project Management14 min read

Sprint Planning That Does Not Waste a Morning

Cut sprint planning from three hours to 45 minutes: prep checklists, capacity math, story slicing, commitment vs forecast, and a minute-by-minute agenda.

June 30, 2026

Put these ideas to work

Openbook gives your team one home for feeds, boards, docs, check-ins and more — free to start.