Leads, lags and logic density: the hidden mechanics of your network
Activities get all the attention — they have names, owners, durations, colours. But a CPM schedule is really made of relationships, and the choices you make about them (type, lag, how many) determine whether the network is a working model or an elaborate prop. This is a tour of the machinery under the bars.
What a relationship actually is
Strip away the software and a relationship is a single inequality fed to the scheduling engine. A finish-to-start link from A to B with zero lag says: early start of B ≥ early finish of A. That is the whole thing. The forward pass walks the network applying every such inequality to compute the earliest dates each activity can achieve; the backward pass runs the same constraints in reverse from the completion date to compute the latest dates; total float is the gap between the two. Every number a schedule produces — every date, every float value, the critical path itself — is the solution to that system of inequalities.
This framing matters because it makes the quality argument mechanical rather than aesthetic. A missing relationship is a missing inequality: the engine is solving the wrong system, and gets the wrong float. A lag changes the constant in the inequality. A lead changes its sign in a way that, as we shall see, quietly breaks the assumptions the whole method rests on. Logic is not documentation. Logic is the model.
The four types, and when each is legitimate
Every relationship in P6 or Microsoft Project is one of four types, depending on which end of the predecessor constrains which end of the successor.
Finish-to-start is the default for a reason: it maps onto how humans describe work ("then"), it statuses cleanly, and it propagates delay without surprises. The DCMA expectation that at least 90% of relationships are FS is not bureaucratic conservatism — it reflects the fact that FS is the only type whose meaning survives contact with progress updates undamaged.
Start-to-start is legitimate for genuinely parallel work where one crew follows another through the same scope: the second fix genuinely can begin once the first fix has established a working front. The honest version pairs an SS with an FF so the successor cannot finish before its driver does; an SS on its own leaves the successor's finish dangling — delay to the tail of the predecessor never reaches the successor at all.
Finish-to-finish suits trailing activities — testing that tracks installation, snagging that tracks completion. The same pairing discipline applies in mirror image.
Start-to-finish says the successor cannot finish until the predecessor starts, which makes time appear to flow backwards through the link. There are textbook cases — the old shift-handover example, where the day shift cannot finish until the night shift arrives — but in twenty-odd years of looking at real programmes we have seen perhaps a handful of SF links that were intentional and zero that were necessary. Nearly all are the residue of someone wiring a relationship backwards in a hurry. Treat every SF as a defect until its author explains it, in writing, convincingly.
Leads: borrowing time from a future that may not happen
A lead is a negative lag — FS−5d says the successor may start five days before the predecessor finishes. The intent is always overlap ("start the plastering before the last partitions are done"), and the intent is fine. The implementation is the problem, for three reasons that compound.
First, it breaks forward-pass intuition. CPM's core promise is that an activity's early dates are driven by completed prerequisites. A lead makes the successor's start depend on a forecast of the predecessor's finish — a date that has not happened and may move. When the predecessor slips, the overlapped successor has often already started in real life, and the model now describes a physical impossibility: work consuming a prerequisite that does not yet exist. Float values around the lead become genuinely misleading rather than merely imprecise.
Second, leads hide resource conflicts. The overlap window is precisely where two crews occupy the same workface, share the same access, or compete for the same crane — and because the overlap exists only as a number on a relationship, no resource histogram will ever show the clash.
Third — and this is the one that costs real money — leads corrupt as-built reconstruction. A forensic analyst rebuilding what drove what through a delay window needs the logic to describe dependency direction truthfully. A network full of FS−10d links forces the analyst to guess what the planner meant, and opposing experts will happily guess differently. The DCMA position is zero leads, and unlike some of the assessment's thresholds, this one deserves to be taken literally. The fix is always the same: split the predecessor at the point where the successor genuinely can begin, and join the pieces with clean FS logic. It costs you one extra activity and buys you a model that means what it says.
Lags: the durations nobody owns
A positive lag is more defensible — concrete genuinely cures, paint genuinely dries — but it shares one structural vice with the lead: it is a duration that is not an activity. A lag has no resources, no owner, no percent-complete, no entry on any lookahead, and no bar on any Gantt chart. The work or wait it represents is real; its representation is invisible. Nobody statuses a lag, so when reality diverges from the assumption — the cure takes longer in winter, the approval takes three weeks instead of two — the model never finds out.
And then there is the calendar question, which is nastier than most planners realise.
Our working rule: a lag representing a physical process with a defensible duration (cure, settlement, regulatory cooling-off) may stay, briefly, and ideally becomes a named activity anyway. A lag representing work becomes an activity, always. A lag representing "roughly the gap we want" gets deleted and replaced with real logic. The DCMA tripwire — lags on no more than 5% of relationships — is generous; disciplined programmes run far leaner.
Logic density: the one-number health check
Divide total relationships by total activities and you get logic density — the average number of links per activity. It is a crude number, and like most crude numbers it is wonderfully hard to game. Since nearly every activity needs at least one predecessor and one successor, a fully wired network cannot sit much below 2.0 (each link is shared between two activities, but parallel paths, multiple drivers and convergence points push the count up).
Below about 1.5, the arithmetic is unforgiving: a large fraction of activities must be missing a predecessor, a successor, or both. Whatever it looks like, the file is a bar chart with logic sprinkled on top — the same pathology as sin number one seen from orbit.
Above about 4, you have the opposite disease: over-constrained spaghetti. Some of those links are redundant — an A→C relationship that duplicates an existing A→B→C path adds no information, but it adds maintenance burden, and when B's logic changes the redundant link silently takes over and produces dates nobody can explain. Dense networks also tend to accumulate contradictory drivers, so every update becomes an archaeology project. A network nobody can maintain will, with certainty, stop being maintained — which is how over-engineered schedules end up as badly statused as lazy ones.
Around 2 is the sweet spot reported by most practitioners: enough redundancy-free logic for honest float, little enough that a human can still reason about why any given activity sits where it does.
Putting it together
| Type | Legitimate use | Abuse pattern |
|---|---|---|
| FS | The default — sequential work, clean handovers | FS with a lead (negative lag) to fake overlap; split the activity instead |
| SS | Crews following each other through a workface; pair with FF | Long SS+lag chains replacing real planned activities; unpaired SS leaving finishes dangling |
| FF | Trailing work — testing tracks installation; pair with SS | FF+lag as a stealth duration extension nobody statuses |
| SF | Vanishingly rare (shift handover curiosities) | Almost any appearance — usually a relationship wired backwards in a hurry |
Relationships are where schedule quality is won or lost, because they are the part of the model that nobody reviews by eye. Activities get challenged in planning meetings; logic gets challenged only by the engine — or, much later and much more expensively, by the other side's expert. The structural checks in the DCMA assessment — zero leads, lags under 5%, at least 90% FS — are blunt instruments, but they are pointed at exactly the right place: the inequalities the dates are made of. The float those relationships produce, and what it really means, is a story of its own — which is where we go next.
Key takeaways
- A relationship is an inequality in the CPM solver. Wrong logic means the engine solves the wrong system — the dates are answers to a question nobody asked.
- FS should dominate (≥90%); pair SS with FF so successor finishes never dangle; treat every SF as a defect until proven intentional.
- Leads (negative lags) break forward-pass intuition, hide resource clashes and corrupt as-built analysis. The zero-tolerance rule deserves to be taken literally.
- Lags are unowned, unstatusable, invisible durations — and they follow a calendar set in a P6 schedule option that can silently change the answer. Document it.
- Logic density ≈2 links per activity is healthy; below 1.5 you have a bar chart, above 4 you have spaghetti no one will maintain.
See every lead, lag and open end in your network
Drop a P6 XER or MS Project file in your browser and get relationship types, lags, logic density and every offending link listed in seconds. Nothing is uploaded.