Git, CI/CD & GitOpsXLVII · Pipeline DependenciesTopology
Fan-in and fan-out — parallelism at job boundaries
What you'll learn
- Identify fan-out, fan-in, and diamond shapes in a pipeline DAG
- Predict the wall-clock cost of each shape
- Design a DAG that maximises parallelism by minimising unintended fan-in
- Recognise that the fan-in point is the synchronisation that determines pipeline duration
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
Three DAG shapes recur in every pipeline: fan-out, fan-in, and diamond. They are the vocabulary for reading and writing DAGs.
Fan-out
Fan-out is one job whose completion enables many successors.
flowchart LR
B["build"] --> U["unit"]
B --> I["integration"]
B --> SC["scan"]
build runs first; the three start as soon as it
completes and a runner is free. Cost is
max(unit, integration, scan).
Fan-in
Fan-in is many predecessors whose completion enables one successor. The successor starts only when every predecessor has completed.
flowchart LR
U["unit"] --> PKG["package"]
I["integration"] --> PKG
C["contract"] --> PKG
package waits for all three. Wall-clock cost is
max(unit, integration, contract).
Diamond
Diamond is fan-out followed by fan-in.
flowchart LR
B["build"] --> U["unit"]
B --> I["integration"]
U --> DP["deploy"]
I --> DP
Cost is build + max(unit, integration) + deploy.
Parallelism at boundaries
Parallelism is bounded by the DAG, the runners, and
concurrency:.
concurrency:
group: ${ github.workflow }-${ github.ref }
cancel-in-progress: true
concurrency: for cross-run; DAG for within-run.
Designing DAGs
flowchart LR
B1["build"] --> T1["test-a"]
B1 --> T2["test-b"]
B1 --> T3["test-c"]
T1 --> D1["deploy"]
T2 --> D1
T3 --> D1
- Maximise parallelism early.
- Synchronise at boundaries.
- Serialise mutations with
needs:.
Production discipline
- Identify fan-in and slowest predecessor.
- Optimise slowest predecessor first.
- Avoid fan-in to jobs not needing all predecessors.
concurrency:for cross-run; DAG for within-run.
Cross-course references
- Ansible for Production Sysadmins - Part XXXVII applies fan-out/fan-in to AWX.
- Linux for Production Sysadmins - Part XXX uses diamond for systemd.
Quiz
Knowledge check · 4 questions
Q1. A diamond has build (2 min), two parallel test jobs (1 min and 8 min), and a deploy (2 min). What is the wall-clock cost?
Q2. A fan-in target's wall-clock start time is bounded by its slowest predecessor, not by the sum of its predecessors.
Q3. Name the three DAG shapes and identify which one is the synchronisation point that bounds the pipeline's wall-clock duration.
Q4. Identify the bottleneck in a diamond and recommend the optimisation.
Pipeline: build (2), unit (1), integration (8), scan (3), deploy (2). Diamond: build -> (unit, integration, scan) -> deploy. Total: 15 min.
Passing score: 75%. Answers are checked in this browser.