← Blog
Schedule Quality·22 Jan 2026·11 min read

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.

The four relationship types FS — finish to start A B B starts when A finishes. The default. ~90%+ of links. SS — start to start A B B starts when A starts (often + lag). Parallel work. FF — finish to finish A B B can't finish until A finishes. Trailing work. SF — start to finish A B B can't finish until A starts. Almost always an error.
Fig 1. Each type constrains a different pair of ends. FS is unambiguous and dominant; SS and FF have genuine uses for overlapping work; SF inverts the intuitive flow of time and is treated by most reviewers as a defect until proven otherwise.

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.

The lag-calendar trap. A lag of 10 days is 10 days on some calendar — but whose? The predecessor's? The successor's? A 24-hour calendar? In P6 this is a project-level schedule option ("Calendar for scheduling relationship lag"), and changing it re-times every lagged relationship in the programme at a stroke. Two parties opening the same XER with different option settings can calculate different completion dates from identical data — a genuinely horrible discovery to make mid-dispute. If you must use lags, document the lag calendar setting in the basis of schedule, and check it whenever a file changes hands.
One FS+10d lag, three answers — it depends on the lag calendar (indicative) Pour slab → FS+10d → strike formwork. Same data, three schedule-option settings: 5-day week calendar 10d lag = 14 elapsed starts 14 Jul 6-day week calendar 10d = 12 elapsed starts 12 Jul 24-hour calendar 10d = 10 elapsed starts 10 Jul Indicative dates. The lag itself never appears on the Gantt — only its consequences do, and they move when the option does.
Fig 2. The same FS+10d relationship scheduled under three lag-calendar settings (indicative). Four days of difference on a single link, from a setting most users have never opened.

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.

Logic density — relationships ÷ activities SPARSE HEALTHY SPAGHETTI ≈ 2.0 sweet spot 1.0 1.5 2.0 3.0 4.0 5.0 < 1.5 — open ends everywhere; float is fiction; a bar chart in disguise > 4 — redundant and contradictory links; unmaintainable; dates nobody can explain Zone boundaries are practitioner rules of thumb, not contractual thresholds — read alongside the DCMA logic check.
Fig 3. The logic density spectrum. Both ends fail for the same underlying reason: the network no longer reflects how the work actually depends on itself.

Putting it together

TypeLegitimate useAbuse pattern
FSThe default — sequential work, clean handoversFS with a lead (negative lag) to fake overlap; split the activity instead
SSCrews following each other through a workface; pair with FFLong SS+lag chains replacing real planned activities; unpaired SS leaving finishes dangling
FFTrailing work — testing tracks installation; pair with SSFF+lag as a stealth duration extension nobody statuses
SFVanishingly 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

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.

← PreviousThe five scheduling sins the DCMA check catches most