Critical path method (CPM) and PERT calculator
Find the critical path, float and project duration from tasks and predecessors, or add PERT estimates for the chance of finishing on time, with a Gantt chart.
A clear answer. Here’s how.
The forward pass gives each task its earliest start ES (the latest earliest finish of its predecessors, or 0) and earliest finish EF = ES + duration; the project duration is the largest EF. The backward pass starts from that duration: a task’s latest finish LF is the smallest latest start of the tasks that follow it (the project duration for a last task) and LS = LF − duration. Total float is LS − ES: how far a task can slip without delaying the project. Free float is the earliest start of the following tasks minus EF: how far it can slip without delaying any of them. Tasks with zero total float are critical, and a critical path is a chain of critical tasks in which each starts the moment the one before finishes; all of them are listed (up to 50, with the full count). Durations are read as exact decimals and added as whole numbers, so float is never lost to rounding. Loops, unknown predecessors and repeated ids are reported by name. In PERT mode each task has an expected time (optimistic + 4 × likely + pessimistic) / 6 and a variance ((pessimistic − optimistic) / 6)². The variance of the project is the sum along the critical path (the one with the largest variance if there are several) and the chance of finishing by a target time uses a normal approximation: Φ((target − expected duration) / standard deviation). That approximation ignores other paths that are nearly critical, so the chance is usually a little optimistic, and the tasks are assumed independent. The tool uses finish-to-start links only; it has no calendars, lags, resource limits or costs.
How this is checked
5 reference checks passed These 5 cases were run when this page was built, on 20 October 2026, and all reproduce within the stated tolerance. The same cases are part of the automated tests that run on every change to Toolmoz. Engine version 1.
See the checks and where each expected answer comes from
Case 1
- Inputs
- Method cpm
- Expected, and what Toolmoz gave
- Project duration expected 38, Toolmoz 38Critical tasks expected 4, Toolmoz 4Critical paths expected 1, Toolmoz 1Tasks with float expected 2, Toolmoz 2Largest total float expected 21, Toolmoz 21Critical path expected B → D → E → F, Toolmoz B → D → E → F
- Where the expected answer comes from
- The six-activity network from the University of Melbourne IFORS tutorial (durations and predecessors as published; the passes are worked here by hand and confirmed by an independent Python script that enumerates every path). Forward pass: Training 0-6, Purchasing 0-9, Production 9-17, Quality control 9-16, Assembling 16-26, Transporting 26-38, so the project takes 38 days. Backward pass: Transporting LF 38, Assembling LF 26, Production LF 38 (LS 30), Quality control LF 16, Purchasing LF min(30, 9) = 9 (LS 0), Training LF 9 (LS 3). Total float: Training 3, Production 21 and the rest 0. The critical path is Purchasing, Quality control, Assembling, Transporting: 9 + 7 + 10 + 12 = 38
- Allowed difference
- ±1e-9
Case 2
- Inputs
- Method cpmTasks (CPM) A,Start,3, B,Left,4,A C,Right,4,A D,Finish,2,B C E,Side job,1,A
- Expected, and what Toolmoz gave
- Project duration expected 9, Toolmoz 9Critical tasks expected 4, Toolmoz 4Critical paths expected 2, Toolmoz 2Tasks with float expected 1, Toolmoz 1Largest total float expected 5, Toolmoz 5
- Where the expected answer comes from
- Hand calculation: A runs 0-3, then B and C both run 3-7, then D runs 7-9, so the duration is 9. A to B to D and A to C to D both total 3 + 4 + 2 = 9, so there are two critical paths. E (1 day, after A) can start at 3 and finish by 9 at the latest, so its total float is 9 - 3 - 1 = 5 and it is the only task with float (confirmed by a path-enumeration Python script)
- Allowed difference
- ±1e-9
Case 3
- Inputs
- Method cpmTasks (CPM) A,One,3, B,Two,2,A C,Three,4,A D,Four,1,B E,Five,6,C D
- Expected, and what Toolmoz gave
- Project duration expected 13, Toolmoz 13Critical path expected A → C → E, Toolmoz A → C → ETasks with float expected 2, Toolmoz 2Largest total float expected 1, Toolmoz 1
- Where the expected answer comes from
- Hand calculation: A 0-3, B 3-5, C 3-7, D 5-6, E starts at max(7, 6) = 7 and ends at 13. Backward: E LF 13 (LS 7), D LF 7 (LS 6), C LF 7 (LS 3), B LF 6 (LS 4), A LF min(4, 3) = 3. Total float: B = 4 - 3 = 1 and D = 6 - 5 = 1, the other three are 0, so the critical path is A, C, E (3 + 4 + 6 = 13). Free float of B is 5 - 5 = 0 although its total float is 1 (confirmed by a path-enumeration Python script)
- Allowed difference
- ±1e-9
Case 4
- Inputs
- Method pertTarget finish time (PERT) 20
- Expected, and what Toolmoz gave
- Project duration expected 19.5, Toolmoz 19.5Critical path expected A → C → E → G, Toolmoz A → C → E → GStandard deviation of the project duration expected 1.2801909579781015, Toolmoz 1.2801909579781015Chance of finishing by the target time expected 65.1941240228, Toolmoz 65.19412402282722
- Where the expected answer comes from
- The seven-task table on the Wikipedia PERT page (optimistic, likely, pessimistic and predecessors as published). Expected times (o + 4m + p) / 6 are A 4, B 5.333, C 5.167, D 6.333, E 5.167, F 4.5 and G 5.167, and the page names the critical path a, c, e, g (it quotes 19.51 from times rounded to two decimals; exactly, 4 + 31/6 + 31/6 + 31/6 = 19.5). Variances ((p - o) / 6)^2 along it are 4/9, 1/4, 1/4 and 25/36, which add to 1.63889, so the standard deviation is 1.28019. Chance of finishing by 20 = Phi((20 - 19.5) / 1.28019) = Phi(0.390567) = 0.651941 (Python math.erf, independent of the tool)
- Allowed difference
- ±0.000001 absolute
Case 5
- Inputs
- Method pertTarget finish time (PERT) 17
- Expected, and what Toolmoz gave
- Chance of finishing by the target time expected 2.5419654035, Toolmoz 2.5419654034749963Time to finish with 95% confidence expected 21.60572674, Toolmoz 21.605726740420756
- Where the expected answer comes from
- Same Wikipedia PERT table. Phi((17 - 19.5) / 1.28019) = Phi(-1.952834) = 0.0254197 (Python math.erf). With 95% confidence the duration is 19.5 + 1.644854 x 1.28019 = 21.60573
- Allowed difference
- ±0.000001 absolute
What this shows: the engine reproduces independently worked values for these cases. It does not prove every possible input is right. To test an answer you were given, see how to check a number; to see what is and is not checked across Toolmoz, see the accuracy ledger.
See a worked example
Worked example
A fixed demonstration, separate from the values you enter above.
- Method
- CPM: one duration for each task
- Tasks (CPM)
id,name,duration,predecessors A,Training,6, B,Purchasing,9, C,Production,8,A B D,Quality control,7,A B E,Assembling,10,D F,Transporting,12,E
- Time unit (labels only)
- days
Example result
| ID | Task | Duration | Predecessors | Earliest start | Earliest finish | Latest start | Latest finish | Total float | Free float | Critical |
|---|---|---|---|---|---|---|---|---|---|---|
| A | Training | 6 | 0 | 6 | 3 | 9 | 3 | 3 | No | |
| B | Purchasing | 9 | 0 | 9 | 0 | 9 | 0 | 0 | Yes | |
| C | Production | 8 | A B | 9 | 17 | 30 | 38 | 21 | 21 | No |
| D | Quality control | 7 | A B | 9 | 16 | 9 | 16 | 0 | 0 | Yes |
| E | Assembling | 10 | D | 16 | 26 | 16 | 26 | 0 | 0 | Yes |
Critical tasks have no total float: a delay to any of them delays the project. Free float is how long a task can slip without delaying the next task.