Task dependencies in a Gantt chart: how they work
Learn what task dependencies are, the four dependency types, and how to set them in a Gantt chart so one late task never surprises you.
A Gantt chart without task dependencies is just a list of bars on a calendar. Task dependencies are what turn it into a schedule: they say which tasks must happen before others, so a delay in one place shows up everywhere it matters. This guide explains what task dependencies are, the four types you will meet, and how to use them on a small real project.
What is a task dependency?
A task dependency is a rule that links two tasks. The task that has to happen first is the predecessor. The task that waits for it is the successor.
If you are building a house, you cannot paint the walls until the plaster is dry. "Plaster walls" is the predecessor, "Paint walls" is the successor. On a Gantt chart this is drawn as an arrow from the end of the first bar to the start of the second.
Dependencies answer three practical questions:
- What can I start right now, and what is blocked?
- If this task slips by three days, what else moves?
- Which tasks decide the final delivery date?
Without them you are guessing at all three. With them, the chart tells you.
The four types of dependencies
Project management textbooks describe four relationships between a predecessor and a successor.
Finish-to-start (FS)
The successor cannot start until the predecessor finishes. This is the one you will use most of the time: write the copy, then design the page; build the feature, then test it.
Start-to-start (SS)
The successor cannot start until the predecessor starts. Both can then run in parallel. Example: once "Build the API" starts, "Write the API documentation" can start too, because the writer can follow along.
Finish-to-finish (FF)
The successor cannot finish until the predecessor finishes. Example: "Final testing" cannot be completed before "Last bug fixes" are completed, but testing can begin earlier.
Start-to-finish (SF)
The successor cannot finish until the predecessor starts. This is rare. A typical example is a night shift that cannot end until the morning shift begins.
In practice, the large majority of real plans can be expressed with simple "this must finish before that starts" links. If you are new to Gantt charts, start there and add the other types only when a real situation demands them. In ProGantt Flow, a dependency means that a task depends on other tasks that must finish first, and the chart shows these links as connected arrows.
An example: launching a landing page
Here is a small project with a realistic set of dependencies.
| Task | Duration | Depends on |
|---|---|---|
| Write the page copy | 3 days | none |
| Design the layout | 4 days | none |
| Build the page | 5 days | Write the page copy, Design the layout |
| Set up analytics | 1 day | none |
| Test on mobile and desktop | 2 days | Build the page |
| Publish | 1 day | Test on mobile and desktop, Set up analytics |
Notice a few things.
Some tasks run in parallel. Copy, design and analytics have no predecessors, so they can all start on day one, possibly with different people.
A task can have several predecessors. "Build the page" starts only when both the copy and the design are done. If the copy takes three days and the design takes four, the build starts after the design, because that is the later of the two.
Not every task matters equally. If "Set up analytics" slips by two days, nothing changes: it still finishes long before "Publish" needs it. If "Design the layout" slips by two days, the publish date moves by two days. Dependencies make that difference visible. The chain of tasks that sets the earliest possible end date is the critical path, and the longest chain in this example is Design, then Build, then Test, then Publish: 4 + 5 + 2 + 1 = 12 working days.
How to set dependencies well
List tasks first, link second
Write down all the tasks and their durations before you draw any arrows. It is much easier to ask "what must be done before this?" for each task once you can see the whole list. If you are still deciding how to break the work down, grouping related tasks into phases with subtasks keeps the list readable.
Link only real constraints
A dependency should describe something that is physically or logically required, not a preference. "Design before build" is real. "Alice does this before Bob does that because Alice is busy" is a resource question, not a dependency, and mixing the two makes the plan rigid and hard to read. Handle people's availability with resource assignment instead.
Avoid unnecessary chains
If every task depends on the previous one, your project becomes a single long line and every delay is fatal. Ask whether tasks really need to be sequential. Often you can run two tasks side by side and save days.
Watch for circular dependencies
If task A depends on B, B depends on C and C depends on A, nothing can ever start. This usually comes from linking tasks in a hurry. A dependency graph view, or a quick review of each task's predecessors, will reveal the loop.
Use milestones as checkpoints
A milestone such as "Client approval" or "Go live" is a point in time, not a block of work. Tying key tasks to milestones gives you clear dates to report on, and makes it obvious when a milestone is at risk because something upstream is late.
What happens when a task is late
This is where dependencies pay off. Suppose the design takes six days instead of four. Because "Build the page" depends on it, the build, the testing and the publish date all move two days later. On a chart with dependencies you see that immediately. On a spreadsheet you have to remember to change each date by hand, and it is easy to miss one.
After a delay, the useful questions are:
- Which tasks are directly affected?
- Is the delayed task on the critical path? If not, the end date may not change at all.
- Can I shorten a later task, add a person, or run two tasks in parallel to recover the time?
Letting an AI assistant manage dependencies
Writing a plan with a dozen tasks and a web of dependencies by hand is slow. If you use Claude, Cursor or VS Code, you can connect them to ProGantt Flow through MCP and describe the plan in plain language: tasks, durations and what depends on what. The assistant can create the plan in one step, read the dependency graph to find broken links or cycles, and tell you what moves when a task is delayed.
You still decide what the real constraints are: an assistant does not know that your client needs a week to approve a design unless you tell it. Treat it as a fast way to enter and check the plan, not as a replacement for your judgement. Setup steps and example prompts are in the connector docs.
A quick checklist
Before you share a plan, check that:
- Every task except the first ones has at least one predecessor, or a good reason not to.
- No task is linked only because of habit.
- Parallel work is really parallel.
- The final deliverable or milestone is reachable through the chain of dependencies.
- You know which tasks are on the critical path.
Try it on your own plan
Pick a project you are working on, list ten tasks, and for each one ask: "What has to be finished before this can start?" Then draw those links in a Gantt chart such as ProGantt Flow and look at the chain that decides your end date. Even a rough version will show you which delays you can absorb and which ones you cannot.