When predictive planning fits

A predictive plan decides most of the scope, schedule and cost before the work starts (see predictive, adaptive and hybrid). That is a strength, not a weakness, when:

  • Requirements are stable and well understood. Moving servers from one data center to another has been done many times; the steps are known.
  • The work is construction-like. Physical work has a natural order — power before racks, racks before servers — and redoing it is expensive.
  • Regulation or contracts demand it. A regulator may require a documented plan and sign-off; a supplier contract may fix delivery dates.
  • A date is fixed. A data center lease ends on a given day, a law takes effect, an event happens whether you are ready or not. Then you need to know early whether the plan fits.

The running example on this page is a predictive project at Kestrel Energy: moving the servers from an old data center, whose lease ends, to a new colocation facility.

The work breakdown structure

A work breakdown structure (WBS) is a hierarchical decomposition of the project's total scope into deliverables and smaller pieces of work, down to work packages that can be estimated, assigned and tracked. Two rules make a WBS useful:

  • Deliverable-oriented. Each element names an outcome ("network ready in new site"), not an activity or a department. Activities come later, when each work package is scheduled.
  • The 100% rule. The children of every element add up to exactly 100% of the parent: all of the work, and nothing outside the scope. Work that is not in the WBS is not in the project.
1   Data center move
1.1   Move plan
1.1.1   Inventory of servers and services
1.1.2   Migration plan and rollback plan
1.2   New site ready
1.2.1   Racks and power
1.2.2   Network and cabling
1.3   Servers in service at new site
1.3.1   New servers ordered and received
1.3.2   Servers installed and configured
1.3.3   Services migrated and tested
1.4   Operations ready
1.4.1   Operations staff trained
1.4.2   Monitoring and runbooks updated
1.5   Old site closed
1.5.1   Equipment disposed of securely
1.5.2   Lease handed back

Notice "Old site closed": it is easy to forget, and the 100% rule forces the question "what else is part of done?" Secure disposal of old disks is real work with real risk.

Estimating tasks

Each work package is broken into tasks that need an estimate of effort or duration. Common techniques:

  • Expert judgment. Ask the people who have done similar work — ideally the people who will do this work.
  • Analogous estimating. Base the estimate on a comparable past project, adjusted for differences.
  • Three-point estimating. Ask for an optimistic (o), most likely (m) and pessimistic (p) duration. The PERT (Program Evaluation and Review Technique) formula weights the most likely value: (o + 4m + p) / 6.

Tomasz Nowak estimates the network installation at 4 days if everything goes well, 5 days most likely, and 12 days if the supplier is late with the patch panels. The PERT estimate is (4 + 20 + 12) / 6 = 6 days. The long pessimistic tail pulls the estimate above the "most likely" 5 — which is exactly the point: estimates that ignore what can go wrong are systematically too low.

Estimating in agile teams works differently; see Estimation and Forecasting.

Dependencies

A task dependency is a logical relationship between two tasks that limits when one can start or finish relative to the other. There are four types, named after which end of the predecessor is linked to which end of the successor:

Type Meaning Example
Finish-to-start (FS) B cannot start until A finishes Install servers after the racks are ready
Start-to-start (SS) B cannot start until A starts Label cables once cabling has started
Finish-to-finish (FF) B cannot finish until A finishes Documentation is finished when testing is finished
Start-to-finish (SF) B cannot finish until A starts Old monitoring runs until new monitoring starts

Finish-to-start is by far the most common, and the example below uses only that type. Dependencies can also be external — the supplier's delivery date is outside the team's control and is often the biggest risk in the plan.

Gantt charts and milestones

A Gantt chart shows a schedule as horizontal bars against a timeline: one row per task, each bar running from the task's start to its finish, often with dependency arrows and milestones. Its strength is that anyone can read it at a glance; its weakness is that a neat chart looks more certain than the estimates behind it.

A milestone is a significant point or event in a project, with zero duration — "move plan approved", "go-live" — used to mark progress and as a checkpoint for decisions. Milestones are drawn as diamonds.

Gantt chart of the data center move over 30 working days. Task A, inventory and plan, days 0 to 5. Task B, order servers, days 5 to 15, with 4 days of float. Task C, racks and power, days 5 to 13. Task D, network and cabling, days 13 to 19. Task E, install servers, days 19 to 23. Task F, train staff, days 5 to 8, with 15 days of float. Task G, migrate and test, days 23 to 30. Tasks A, C, D, E and G are highlighted as the critical path. Milestones at day 5, plan approved, and day 30, go-live. A Inventory and plan B Order servers C Racks and power D Network and cabling E Install servers F Train staff G Migrate and test Milestones plan approved go-live 0 5 10 15 20 25 30 working days
Highlighted bars form the critical path (A, C, D, E, G); dashed lines show the float of B and F. Computed in the example below.

The critical path method

The critical path is the longest sequence of dependent tasks from the start of a project to its end. Its length is the shortest possible project duration, and any delay to a task on it delays the whole project.

Tasks off the critical path can slip a little without harm. Their total float (also called total slack) is the amount of time a task can be delayed without delaying the project end date: latest start minus earliest start. Tasks on the critical path have zero float.

The critical path method (CPM) finds both with two passes:

  1. Forward pass. Walk from start to end. A task's earliest start (ES) is the latest earliest finish (EF) of its predecessors; EF = ES + duration.
  2. Backward pass. Walk from end to start. A task's latest finish (LF) is the earliest latest start (LS) of its successors (or the project end); LS = LF − duration.
# Data center move at Kestrel Energy: duration in working days
# and the tasks that must finish before each task can start.
tasks = {
    "A": ("Inventory and plan the move", 5, []),
    "B": ("Order and receive servers", 10, ["A"]),
    "C": ("Prepare racks and power", 8, ["A"]),
    "D": ("Install network and cabling", 6, ["C"]),
    "E": ("Install servers in new racks", 4, ["B", "D"]),
    "F": ("Train operations staff", 3, ["A"]),
    "G": ("Migrate services and test", 7, ["E", "F"]),
}

# Forward pass: earliest start (ES) and earliest finish (EF).
# The dict is written so every task comes after its predecessors.
es, ef = {}, {}
for t, (name, dur, preds) in tasks.items():
    es[t] = max((ef[p] for p in preds), default=0)
    ef[t] = es[t] + dur

project_end = max(ef.values())

# Backward pass: latest finish (LF) and latest start (LS).
successors = {t: [s for s in tasks if t in tasks[s][2]] for t in tasks}
ls, lf = {}, {}
for t in reversed(list(tasks)):
    lf[t] = min((ls[s] for s in successors[t]), default=project_end)
    ls[t] = lf[t] - tasks[t][1]

print("Task  Dur  ES  EF  LS  LF  Float")
for t in tasks:
    total_float = ls[t] - es[t]
    print(f"{t:<4}  {tasks[t][1]:>3}  {es[t]:>2}  {ef[t]:>2}  "
          f"{ls[t]:>2}  {lf[t]:>2}  {total_float:>5}")

critical = [t for t in tasks if ls[t] == es[t]]
print("Project length:", project_end, "days")
print("Critical path:", " -> ".join(critical))
Task  Dur  ES  EF  LS  LF  Float
A       5   0   5   0   5      0
B      10   5  15   9  19      4
C       8   5  13   5  13      0
D       6  13  19  13  19      0
E       4  19  23  19  23      0
F       3   5   8  20  23     15
G       7  23  30  23  30      0
Project length: 30 days
Critical path: A -> C -> D -> E -> G

Reading the result: the move takes 30 working days. Ordering servers (B) can slip 4 days and training (F) 15 days without moving go-live. But if Tomasz's cabling (D) takes 8 days instead of 6, the whole move ends on day 32. That is where the project manager should focus attention, risk management and, if needed, extra people.

Schedule baseline and change control

Once the plan is approved, it is frozen as a schedule baseline: the approved version of the schedule, with its start and finish dates, against which actual progress is measured. Without a baseline you can say where you are, but not whether you are late. (In service management, a baseline is a measurement used as a starting point — the same idea applied to a metric.)

The baseline only changes through project change control: someone requests a change to scope, schedule or budget, its impact is assessed, and the sponsor or a project board approves or rejects it. Then the baseline is updated. Change control is the formal answer to scope creep.

Common mistakes

  • Planning too precisely too far ahead. Detailed, hour-level tasks for month nine are guesses dressed up as facts. Plan the near term in detail and later phases at a coarser level, refining as you go ("rolling wave planning").
  • Ignoring float. Float belongs to the project, not to the task owner. If every non-critical task uses up its float early ("there's slack, we'll start later"), several paths become critical at once and any surprise delays the end date.
  • Single-point estimates. One number hides the uncertainty. Three-point estimates and contingency make it visible.
  • Forgetting external dependencies. Supplier deliveries, change freezes and other teams' schedules are often on the real critical path.
  • Treating the plan as the goal. Following a plan that no longer matches reality is worse than updating it through change control.