CPM Calculation
Syncify calculates schedule dates with a calendar-aware Critical Path Method (CPM) engine. Each recalculation schedules remaining work through the activity network, calculates late dates and float, derives Level of Effort and WBS Summary activities, and refreshes relationship driving analysis.
This guide is the reference for that calculation model. For how source schedules map into it, see P6 Compatibility and Microsoft Project Compatibility.
Core terminology
- Status Date: the dividing point between historical progress and remaining work.
- Activity calendar: the working and nonworking time used for an activity’s duration, lag, and float arithmetic.
- Original Duration: the original planned duration, retained for comparison.
- Remaining Duration: the working time still required to complete an activity.
- Actual Duration: working time already consumed.
- Total Duration: the calculated working-time span between the activity’s displayed start and finish.
- Actual Start and Actual Finish: historical progress dates.
- Early Start and Early Finish: the earliest remaining-work window allowed by logic, constraints, the Status Date, duration, and calendar.
- Restart and Reend: the start and finish of the remaining-work window. For an incomplete activity, these normally match Early Start and Early Finish.
- Late Start and Late Finish: the latest remaining-work window allowed without exceeding the controlling project or successor late date.
- Total Float: working time from Early Finish to Late Finish on the activity calendar.
- Free Float: the minimum relationship gap to an immediate successor.
- Driving relationship: a relationship whose calculated gap is zero or negative.
- Displayed Start: Actual Start when present; otherwise Early Start.
- Displayed Finish: Actual Finish when present; otherwise Early Finish.
Actual dates and early dates answer different questions: actual dates describe historical execution, while early dates describe the calculated remaining-work network.
Time and calendar rules
All calculation is performed at one-minute resolution.
Schedule timestamps are timezone-agnostic. A date and time belong to the scheduled project’s timezone and are never converted to the timezone of the person viewing the schedule.
Each activity calendar contains:
- a weekly work pattern
- one or more work periods within each working day
- dated exceptions that replace the normal work pattern
- minutes-per-day, week, month, and year conversion values
Durations count only working minutes. Nonworking nights, weekends, breaks, and exceptions do not consume duration.
Activity starts use left-edge working-time rules: a work-period finish is not a valid start, so a start landing at the end of a shift moves to the next working period.
Activity finishes use right-edge rules: a work-period finish is valid. When two timestamps are equivalent in working time — such as a Friday shift finish and the following Monday shift start with no work between them — the earlier finish boundary is preferred for a calculated finish.
Calculated and noncalculated rows
Normal network calculation includes:
- Task Dependent activities
- Start Milestones
- Finish Milestones
Special calculation applies to:
- Level of Effort activities
- WBS Summary activities
Structural WBS rows organize the hierarchy and are not activities.
Activity status
The calculation uses three activity states:
- Not Started: no historical dates; the entire planned duration remains to be scheduled.
- Started: Actual Start is historical, and Remaining Duration is scheduled after the Status Date.
- Completed: Actual Start and Actual Finish are historical; no remaining duration is scheduled.
Status — not Physical Percent Complete — controls which calculation rules apply.
Physical Percent Complete is a manual progress field. It does not calculate Remaining Duration, and setting it to 100 percent does not complete a Started activity.
Network construction
The engine builds a directed network from calculated activities and valid relationships.
Every relationship must be one of:
- Finish-to-Start
- Start-to-Start
- Finish-to-Finish
- Start-to-Finish
Relationships to WBS Summary activities do not participate in normal network calculation. Level of Effort relationships are handled by the Level of Effort pass.
The network is topologically sorted so every predecessor is processed before its successors. A circular relationship path stops calculation and is reported as a circular dependency.
Relationship formulas
Let P be the predecessor, S the successor, and L the relationship lag. Lag is working time on the predecessor calendar.
Forward relationship deadlines:
FS: successor Early Start >= predecessor Early Finish + L
SS: successor Early Start >= predecessor Early Start + L
FF: successor Early Finish >= predecessor Early Finish + L
SF: successor Early Finish >= predecessor Early Start + LFor a Started predecessor, the start endpoint is its remaining-work Early Start, not its historical Actual Start.
Positive lag moves the relationship deadline later; negative lag moves it earlier.
When a Start-to-Start relationship has positive lag on a predecessor that started before the Status Date, working time elapsed between Actual Start and the Status Date consumes that lag. The relationship remains anchored on the predecessor’s remaining Early Start:
remaining SS lag = max(0, original lag - elapsed working time)A future Actual Start does not consume lag.
Completed retained-logic points do not replay historical lag from their calculated zero-duration point, but a later valid historical relationship deadline can still control.
Forward pass
The forward pass processes normal network activities in predecessor order.
Not Started activities
The initial Early Start is the latest of:
- the Status Date
- incoming start-side relationship deadlines
- Start On or After and equivalent start floors
The start is then moved to the next valid activity-calendar start.
The duration-based finish is:
duration finish = Early Start + planned durationIncoming FF and SF relationships and finish-floor constraints can require a later finish. The final Early Finish is the latest applicable finish candidate.
If a finish-side driver controls later than the duration-based finish, Early Start is recalculated backward from the controlling Early Finish so the activity keeps its duration.
Restart and Reend are set to Early Start and Early Finish.
Started activities
Actual Start remains historical. The remaining-work anchor begins at the Status Date, subject to the selected out-of-sequence calculation mode and retained incoming logic.
Remaining work is scheduled as:
duration finish = remaining-work anchor + Remaining DurationFinish-side relationship deadlines and finish constraints can move Early Finish later. When that happens, the engine derives Early Start backward from the final Early Finish to preserve Remaining Duration.
Early Start, Early Finish, Restart, and Reend all describe the remaining-work window. Start constraints are historical once the activity has started; finish constraints can still control remaining work.
Completed activities
Actual Start and Actual Finish are preserved.
Under Retained Logic, a Completed normal activity becomes a zero-duration remaining-work network point:
- Early Start equals Early Finish.
- The point comes from live retained drivers when available.
- Otherwise it falls back to the Status Date, then to historical dates.
- Restart and Reend are cleared.
- Total Float and Free Float are blank.
Outside Retained Logic, Completed normal activities have blank early and late remaining-work dates. Their actual dates can still provide historical relationship anchors where the selected calculation mode requires them.
Out-of-sequence calculation modes
The calculation mode controls how relationships interact with progressed activities.
Retained Logic
- Remaining logic into Started activities is honored: a Started activity’s remaining work cannot proceed until retained predecessor logic allows it.
- Completed activities can form zero-duration logic points in chains that carry live remaining work.
- Completed chains that lead to remaining work participate in the backward pass.
- A historical Completed predecessor with no live remaining-work driver does not by itself postpone remaining work.
Progress Override
- Relationships into Started and Completed successors are ignored.
- Started remaining work resumes from the Status Date.
- A Completed predecessor releases a Not Started successor from the Status Date.
- Relationships between remaining Not Started activities continue to operate normally.
Actual Dates
- Actual dates provide the historical anchors for completed work.
- Relationships into Completed successors participate in late-date and relationship analysis but do not reschedule completed early dates.
- Remaining logic into incomplete activities is retained.
- Started work is scheduled from the later applicable remaining-work anchor.
Retained Duration
Retained Duration preserves imported or manually entered Actual Duration and Remaining Duration as separate quantities. Microsoft Project imports use this mode.
- Remaining logic into incomplete activities is retained, as in Actual Dates mode.
- A Started activity resumes after its Actual Duration has elapsed from Actual Start, skipping any explicit Suspend-to-Resume gap. Following Microsoft Project’s default behavior, remaining work before the Status Date moves forward to the Status Date, including when Actual Duration is zero. An explicit later Resume date remains a split-work boundary.
- Not Started activities recalculate from the Status Date, relationships, and constraints; imported early dates are not fixed floors.
- A finish-side driver can move the remaining-work window later, but cannot pull it before that resume anchor.
- Start-side relationships from a Started predecessor use its historical Actual Start.
- Total Duration and Target Duration equal Actual Duration plus Remaining Duration. Recalculation does not replace them with the calendar span from Actual Start through Early Finish.
Suspend and Resume are retained split-work boundaries. Restart and Reend hold the calculated remaining-work window. Changing Duration Percent moves Restart and Reend without creating or changing a split.
Constraints
Primary and secondary constraints are combined: the latest lower bound and the earliest upper bound control.
- As Soon As Possible: no additional date bound.
- Start On or After: floors Early Start.
- Finish On or After: floors Early Finish.
- Start On or Before: caps Late Start.
- Finish On or Before: caps Late Finish.
- Start On: floors Early Start and caps Late Start at the same calendar-normalized date.
- Finish On: floors Early Finish and caps Late Finish at the same calendar-normalized date.
- Mandatory Start: hard-sets Early Start and Late Start, then calculates the finish from duration.
- Mandatory Finish: hard-sets Early Finish and Late Finish, then calculates the start from duration.
- As Late As Possible: moves the early window as late as immediate successor logic allows, after the normal backward pass.
Start On and Finish On remain logic-sensitive: they can produce negative float rather than overriding the network. Mandatory constraints override the corresponding network endpoint.
Milestone duration is always zero for calculation.
Project late-date anchor
The backward pass needs a terminal late finish.
If the schedule has a valid Must Finish By date, that date is the terminal late finish. Otherwise, the terminal late finish is the latest remaining-work logic finish among incomplete normal network activities.
Completed activities are excluded from this anchor so historical actual dates beyond the Status Date do not stretch the remaining network. If the entire network is complete, the latest completed logic point is used as a fallback.
Backward pass
The backward pass processes normal network activities in reverse order.
For each incomplete activity, the engine starts with the project late-date anchor and applies the earliest allowable bound from its successors:
FS: predecessor Late Finish <= successor Late Start - L
FF: predecessor Late Finish <= successor Late Finish - L
SS: predecessor Late Start <= successor Late Start - L
SF: predecessor Late Start <= successor Late Finish - LFor FS and FF, the controlling predecessor Late Finish is obtained directly. For SS and SF, the controlling predecessor Late Start is obtained first, then Late Finish is calculated by adding the predecessor’s applicable duration.
Not Started activities use planned duration in the backward pass, Started activities use Remaining Duration, and milestones use zero.
Finish upper-bound constraints cap Late Finish. Start upper-bound constraints cap Late Start and then recalculate Late Finish from duration. Mandatory constraints hard-set the corresponding endpoint.
Under Retained Logic, Completed activities pass the applicable successor late endpoint backward as a zero-duration point. Completed activities keep blank Total Float and Free Float.
Total float
Total Float is finish float, measured on the activity calendar:
Total Float = working-time variance(Early Finish, Late Finish)- Positive: the activity can finish later without exceeding its calculated late finish.
- Zero: Early Finish and Late Finish are equivalent in working time.
- Negative: the early finish is already later than the permitted late finish.
Completed activities have blank Total Float.
The schedule view identifies an activity as critical when Total Float is zero or negative.
Free float
For each outgoing relationship, the engine calculates the working-time gap between the predecessor-side relationship deadline and the relevant successor early endpoint:
FS free float = variance(P.Early Finish + L, S.Early Start)
SS free float = variance(P.Early Start + L, S.Early Start)
FF free float = variance(P.Early Finish + L, S.Early Finish)
SF free float = variance(P.Early Start + L, S.Early Finish)The predecessor calendar measures the gap.
Activity Free Float is the smallest valid relationship gap across immediate forward successors. Free Float may be negative when a successor early endpoint is already earlier than the relationship deadline.
- If an activity has no applicable forward successor, Free Float falls back to Total Float.
- A Started activity with zero Remaining Duration receives zero Free Float.
- Completed activities have blank Free Float.
- In Actual Dates mode, a remaining activity whose only applicable successors are Completed uses the project late-date anchor for Free Float.
Relationship driving analysis
Each relationship receives its own Free Float and driving flag after activity dates settle.
A relationship is driving when its deadline-to-successor gap, measured on the successor calendar, is zero or negative.
An activity’s Free Float and a relationship’s Free Float can differ when predecessor and successor calendars differ, because the activity value is measured on the predecessor calendar.
Driving-path traversal follows driving predecessors backward from the selected activity. Artificial As Late As Possible chains without a genuine upstream driver are not treated as originating driving paths.
Level of Effort calculation
A Level of Effort activity is not a normal duration-driven network activity. Its span is derived from its relationships with normal network activities.
Each relationship is interpreted by the endpoint it touches on the Level of Effort activity:
- relationships touching its start contribute start candidates
- relationships touching its finish contribute finish candidates
- relationship direction determines whether lag is added or subtracted
- lag uses the relationship predecessor’s calendar
The early span uses the earliest valid start-side candidate and the latest valid finish-side candidate, with these fallbacks:
- start and finish drivers present: use both
- start driver only: finish equals start
- finish driver only: start equals the Status Date
- no drivers: start and finish equal the Status Date
Endpoints are normalized on the Level of Effort calendar. A finish falling in nonworking time is represented by the preceding equivalent work finish when appropriate.
Status reconciliation
Before the remaining window is calculated, Level of Effort status is reconciled with its driven span:
- when both a start driver and a finish driver exist and both driven endpoints fall before the Status Date, the activity becomes Completed and its actual dates come from the driven span
- otherwise, when a start driver places the driven start before the Status Date, the activity becomes Started and Actual Start comes from the driven span
- otherwise, the activity becomes Not Started and calculated actual dates are cleared
- a Completed Level of Effort activity that already has both actual dates keeps those historical dates
- a Started Level of Effort activity with an Actual Start but no start-side driver keeps its existing progress state
For a Started Level of Effort activity, Early Start is the later of the Status Date and the calculated span start. Its historical Actual Start remains separate.
Late dates
Late Start and Late Finish are calculated independently:
- start-touching relationships bound Late Start
- finish-touching relationships bound Late Finish
- an already actualized successor endpoint does not impose a remaining late bound
- valid finish-side supports use the latest relationship support, capped by the project late-date anchor
- when only finish-side late support exists, Late Start equals Late Finish
- when a start-side relationship is suppressed by an actualized successor, a Started Level of Effort activity can retain its Actual Start as Late Start
If no finish-side late support exists, Late Finish uses the project late-date anchor. If neither start-side nor finish-side support exists, Late Start uses Early Start.
Durations and float
Level of Effort durations are derived after its dates settle:
- Total Duration is the activity-calendar span from Actual Start for Started work, otherwise from Early Start, through Early Finish.
- Remaining Duration is the activity-calendar span from Early Start through Early Finish.
- Total Float is the working-time variance from Early Finish to Late Finish.
- Restart and Reend equal Early Start and Early Finish for incomplete work.
Completed Level of Effort activities keep their actual window as their early and late window, have zero Remaining Duration, and have blank Total Float and Free Float.
Level of Effort Free Float is calculated after all Level of Effort endpoints settle, using the greatest valid supported relationship gap. Positive gaps are reported as zero; a violated finish relationship can produce negative Free Float. If no supported relationship gap exists, Free Float falls back to Total Float.
WBS Summary calculation
A WBS Summary activity derives its window from calculated activities within its assigned structural WBS and all descendant WBS branches:
- Early Start: earliest displayed activity start
- Early Finish: latest displayed activity finish
- Late Start: equal to Early Start
- Late Finish: equal to Early Finish
Its status is:
- Not Started when no contained activity has progress
- Completed when every contained activity is complete
- Started otherwise
For a Started WBS Summary, Actual Start is the earliest contained actual or early start and Actual Finish is blank. For a Completed WBS Summary, Actual Start and Actual Finish are the earliest and latest completed historical endpoints.
WBS Summary Total Float and Free Float are blank. Its durations are derived from its summary window and assigned calendar.
If its WBS contains no calculated activities, the WBS Summary has blank dates and zero durations.
Duration reconciliation
After dates and special activity windows are calculated, duration fields are reconciled.
For normal activities:
- Original Duration is preserved.
- Remaining Duration remains the scheduling input.
- Total Duration becomes the working-time span from Actual Start when present, otherwise Early Start, to Actual Finish when present, otherwise Early Finish.
- Actual Duration is zero for Not Started activities.
- Actual Duration for Started activities is working time from Actual Start to the Status Date.
- Actual Duration for Completed activities is working time from Actual Start to Actual Finish.
If a Started activity already has positive Actual Duration but the calendar span to the Status Date calculates as zero, the existing positive Actual Duration is retained.
Level of Effort and WBS Summary durations follow their separately derived windows.
Calculation sequence
One recalculation runs these stages in order:
- Resolve task calendars, constraints, calculation mode, and valid relationships.
- Build and topologically sort the normal activity network.
- Calculate early dates in the forward pass.
- Calculate late dates and Total Float in the backward pass.
- Reposition As Late As Possible activities.
- Calculate normal activity Free Float.
- Calculate Level of Effort dates, durations, and float.
- Reconcile calculated durations.
- Calculate WBS Summary activities.
- Refresh relationship Free Float and driving flags.
- Write calculated fields back to the schedule.
Calculation boundaries
The CPM engine does not currently model:
- resource leveling or resource-capacity constraints
- resource or assignment calendars controlling activity dates
- resource-driven duration
- suspend and resume split intervals
- Expected Finish
- cross-project or external relationships
- recurring activity generation
- risk-adjusted or probabilistic duration
- cost, earned-value, or cash-flow calculations
- multiple float-path numbering
Results should not be assumed to match a source schedule that depends on these. The engine’s results are fully defined by activity status, activity type, activity calendar, duration, relationships, constraints, Status Date, Must Finish By date, and the selected out-of-sequence mode.