Blog / CPM fundamentals

Schedule Constraints: When to Use Them and What They Break

A constraint is a date you impose on an activity instead of letting logic calculate it. Some constraints are legitimate: a steel delivery that can't arrive before a certain week, a contract milestone the owner will hold you to. Others are a way of making the schedule say what someone wants it to say. This post sorts constraints into the ones that respect logic and the ones that override it, works through how a finish constraint creates negative float, and gives a short list of when to use them and when to take them out.

Two families of constraints

Every constraint does one of two things: it limits how early an activity can happen, or it limits how late. The important question is whether it still lets logic win.

Constraint (P6 name)MS Project equivalentAffectsOverrides logic?
Start On or AfterStart No Earlier ThanEarly startNo
Finish On or AfterFinish No Earlier ThanEarly finishNo
Start On or BeforeStart No Later ThanLate startNo in P6; depends on settings in MS Project
Finish On or BeforeFinish No Later ThanLate finishNo in P6; depends on settings in MS Project
Start OnMust Start OnEarly and late startPartially
Finish OnMust Finish OnEarly and late finishPartially
Mandatory Start(no direct equivalent)Early and late startYes
Mandatory Finish(no direct equivalent)Early and late finishYes
As Late As PossibleAs Late As PossibleUses float to schedule lateNo, but consumes float

The "on or after" constraints are the safe ones. They push early dates later when there's a real reason: a delivery date, a permit, a seasonal restriction. If the logic would put the activity later anyway, the constraint does nothing.

The "on or before" constraints work on the backward pass. They pull late dates earlier, which reduces total float and can make it negative. In P6 they don't move early dates at all; they just report how far behind you are.

The mandatory constraints are the dangerous ones. They fix the date regardless of logic, which means a successor can be scheduled to start before its predecessor finishes. The schedule stops being a network at that point. It's a bar chart with arrows drawn on it.

How MS Project differs

Microsoft Project has a project option that controls whether tasks always honor their constraint dates. With it on (the default), a Finish No Later Than or Must Finish On constraint wins over a link. If predecessors would push the task later than its constraint, MS Project schedules the task at the constraint date anyway and flags a scheduling conflict. The link is violated. With the option off, links win, the task moves later, and negative slack shows the gap.

MS Project also adds constraints without asking. If you type a start date into an auto-scheduled task, or drag its bar, it gets a Start No Earlier Than constraint at that date. Schedules built by dragging bars in MS Project often have a constraint on nearly every task, which means the logic isn't driving anything. If you import an MS Project file and every activity has a constraint, this is usually why. See Moving Schedules Between P6, MS Project, and Everything Else.

Worked example: a finish constraint and negative float

A building's final stretch. Durations are working days, 0-based convention (ES of the first activity = 0, EF = ES + duration). All FS, no lag.

IDActivityDurationPredecessors
AFinishes, upper floors40none
BElevator install and state inspection50none
CFire alarm acceptance test10A
DFinal building inspections8B, C
ETCO (milestone)0D

Unconstrained forward pass:

A: ES 0,  EF 40
B: ES 0,  EF 50
C: ES 40, EF 50
D: ES = max(50, 50) = 50, EF 58
E: ES 58, EF 58

Now the contract says TCO by day 54. Put a Finish On or Before constraint of 54 on E. The forward pass doesn't change, because this constraint only affects late dates. The backward pass starts from 54 instead of 58:

E: LF 54, LS 54     TF = 54 - 58 = -4
D: LF 54, LS 46     TF = 46 - 50 = -4
C: LF 46, LS 36     TF = 36 - 40 = -4
B: LF 46, LS -4     TF = -4 - 0  = -4
A: LF 36, LS -4     TF = -4 - 0  = -4

Every activity shows −4 days of total float. The schedule is honestly telling you the job is four days behind the contract date, and both paths into final inspections need recovery. That's what a finish constraint should do: measure the gap.

Now replace it with a Mandatory Finish of 54 on E. In P6, E is forced to finish on day 54. But D, its predecessor, still finishes on day 58. The schedule shows the TCO four days before the final inspections are done. Total float on E reads as zero, and anyone checking the milestone sees nothing wrong. The negative float is still there on the activities feeding it, but the milestone date, which is what most people report, is now false.

When constraints are the right tool

Use them sparingly, and only for dates that come from outside the schedule's own logic:

  • Contract milestones. Substantial completion, TCO, phase turnovers. Use a Finish On or Before so negative float shows when you're behind. Don't use a Mandatory Finish.
  • External delivery dates. Long-lead equipment, switchgear, elevator equipment, curtain wall units with a committed ship date. Use Start On or After on the delivery activity. Better still, model the procurement chain so the date comes from logic.
  • Owner-furnished items and access dates. The owner will turn over the site on a certain date, or owner-furnished equipment arrives on a certain date. Start On or After.
  • Seasonal restrictions. Roofing can't start before a certain date because of temperature, or a utility tie-in can only happen during a shutdown window. Start On or After.
  • Permits and approvals you can't model with a duration because you don't control them. Start On or After, with a note saying where the date came from.

For all of these, put the source of the date in the activity notes. "Per PO 1234 confirmed ship date" is defensible. A bare constraint with no explanation isn't.

When to take them out

  • Constraints that replace logic. If an activity has a Start On or After constraint because someone didn't know what its predecessor was, find the predecessor. See Open Ends and Dangling Logic.
  • Mandatory constraints of any kind in a schedule used for progress or delay analysis. They hide slips and break the network.
  • Constraints that are already in the past. A Start On or After of last March on an activity that hasn't started does nothing except confuse the next reader.
  • As Late As Possible on anything with successors. It consumes all the activity's free float and can push work into conflicts you didn't plan for. It's occasionally useful for things like delivery of material you don't want on site early, but understand that it removes slack.
  • Constraints created by dragging bars. If the constraint date matches a date someone once dragged to, it's not a real constraint.

The DCMA 14-Point Assessment counts hard constraints and expects them on no more than 5 percent of incomplete activities. Many owner specifications go further and require that every constraint be listed and justified in the narrative. See The DCMA 14-Point Assessment, Explained for Construction and What Owners Should Check in a Baseline Schedule Submittal.

Constraints and what-if analysis

A common use of a constraint is testing a question: what if the elevator inspection can't happen until day 60? Put a Start On or After on it and see what moves. That's fine as an experiment, but do it in a copy of the schedule, not the live update. In schedule.construction, what-if scenarios run against a copy so the live schedule isn't touched. Whatever tool you use, the risk is the same: a test constraint left in place becomes a permanent distortion.

A constraint review checklist

  1. List every constrained activity. Most CPM tools have a constraint column you can filter on.
  2. For each, record the constraint type, date, and the reason. If there's no reason, it's a candidate for removal.
  3. Replace any mandatory constraint with a Finish On or Before (for milestones) or Start On or After (for external dates).
  4. Remove constraints with dates in the past on incomplete activities, or confirm they still mean something.
  5. Check that contract milestones use a late-date constraint so negative float shows up.
  6. Re-run the schedule and compare the critical path before and after. Removing a constraint often reveals the real driving path.

Key takeaways

  • "On or after" constraints push early dates and respect logic. They're the safe ones.
  • "On or before" constraints pull late dates and create negative float. That's useful; it measures the gap.
  • Mandatory constraints override logic and can make a schedule state impossible things. Avoid them.
  • MS Project adds constraints when you type dates or drag bars. Check imported schedules for this.
  • Every constraint should have a documented reason that comes from outside the schedule.