Lesson285 words

Job execution order, parallelism and multi-stage pipelines

Design and implement a strategy for job execution order

The asymmetry that decides most questions

Jobs in a stage run in parallel by default. Stages run sequentially by default, in the order they are defined.

Two different defaults, two different keywords to change them:

yaml
stages: - stage: Build - stage: IntegrationTest dependsOn: Build - stage: FunctionalTest dependsOn: Build # runs after Build... - stage: SecurityScan dependsOn: [] # no implicit predecessor; eligible to run concurrently

dependsOn: [] — an explicitly empty list — is how you opt a stage out of the implicit sequential chain. Omitting dependsOn entirely does the opposite: the stage waits for the previous one.

For jobs the reverse holds. Omitting dependsOn creates no job dependency, so the job is eligible to start; adding it imposes order. Actual concurrency still requires available agents and parallel-job capacity, and conditions or resource checks can delay execution.

Fan-out and fan-in

Loading Diagram...
Figure 1 — Mermaid diagram
yaml
- job: Publish dependsOn: [Lint, UnitTest, IntegrationTest] condition: succeeded()

A job listing several dependencies waits for all of them.

Matrix

yaml
strategy: matrix: linux: { imageName: ubuntu-latest } windows: { imageName: windows-latest } mac: { imageName: macOS-latest } maxParallel: 2

Two constraints worth memorising:

  • parallel and matrix are mutually exclusive — you cannot use both in one strategy block.
  • maxParallel is only valid with matrix.

Matrix multiplies one job definition into legs; maxParallel throttles how many legs run at once, which matters when your parallel-job allocation is finite.

Primary sources

Ready to study Designing and Implementing Microsoft DevOps Solutions (AZ-400)?

Practice tests, flashcards, and all study notes — free, no sign-up needed.

Start Studying — Free