Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for GitLab CI/CD By James Joyner IV · · 11 min read

Architecting Parent-Child Pipelines in GitLab Without Hitting Limits

Parent-child pipelines split a monster .gitlab-ci.yml into focused units. Here's how to architect them, pass status with strategy:depend, and stay inside GitLab's nesting limits.

  • #gitlab-cicd
  • #ai
  • #child-pipelines
  • #architecture
  • #dag

When a .gitlab-ci.yml crosses a few hundred lines, it stops being a config file and starts being a liability — slow to reason about, easy to break, painful to review. Parent-child pipelines are GitLab’s answer: a parent pipeline triggers child pipelines, each owning a focused slice of the work. Done well, this is the cleanest way to scale a complex build. Done carelessly, you hit nesting limits, lose failure visibility, or create an orchestration mesh nobody understands. Here’s how I architect them.

Parent-child vs multi-project

First, get the distinction right. A child pipeline runs in the same project as the parent and is triggered from within its .gitlab-ci.yml. A multi-project pipeline triggers a pipeline in a different project. This guide is about child pipelines — splitting one project’s work — not cross-project orchestration. The trigger syntax looks similar, which causes confusion, but the use cases are different: children for decomposition, multi-project for cross-team handoff.

The basic trigger

A parent job triggers a child by pointing at another config file:

# .gitlab-ci.yml (parent)
trigger-backend:
  stage: build
  trigger:
    include: backend/.gitlab-ci.yml
    strategy: depend

strategy: depend is the keyword that matters. Without it, the parent job is marked successful as soon as the child starts, so a failing child doesn’t fail the parent — your pipeline goes green while a child is on fire. With strategy: depend, the parent job mirrors the child’s status, so a child failure correctly fails the whole pipeline. I treat strategy: depend as mandatory; omitting it is almost always a bug.

Decomposing a monorepo by component

The pattern that pays off most is one child pipeline per component, each with its own focused config:

# parent .gitlab-ci.yml
stages: [trigger]

backend:
  stage: trigger
  trigger:
    include: services/backend/.gitlab-ci.yml
    strategy: depend
  rules:
    - changes: ["services/backend/**/*"]

frontend:
  stage: trigger
  trigger:
    include: services/frontend/.gitlab-ci.yml
    strategy: depend
  rules:
    - changes: ["services/frontend/**/*"]

Now the backend team owns services/backend/.gitlab-ci.yml and the frontend team owns theirs, the parent stays tiny, and rules:changes ensures only the components that actually changed spin up a child. Each child is a clean, reviewable pipeline instead of a section buried in a 600-line file.

Mind the nesting limits

This is where people get burned. GitLab limits how deeply pipelines can nest — a child can trigger a grandchild, but only to a bounded depth, and there are caps on downstream pipelines per pipeline. If you build child-triggers-child-triggers-child chains, you’ll eventually hit a wall and the deepest triggers silently won’t run. Keep the hierarchy shallow: parent → children is ideal, parent → child → grandchild only when genuinely necessary. If you find yourself reaching for a fourth level, the design is probably wrong — flatten it, or reconsider whether some of those should be jobs rather than whole pipelines.

Dynamic children for generated work

When the set of children isn’t fixed — say, one child per changed service in a large monorepo — generate the child config in an earlier job and trigger it as an artifact:

generate:
  stage: build
  script: ./generate-children.sh > generated.yml
  artifacts:
    paths: [generated.yml]

run-generated:
  stage: deploy
  trigger:
    include:
      - artifact: generated.yml
        job: generate
    strategy: depend

This keeps the matrix of work data-driven instead of hand-maintained. Just keep the generator simple and its output validated — a broken generated YAML fails in a way that’s harder to debug than a static file.

Let AI plan the decomposition — and check the limits

When I’m splitting a big pipeline, I describe the current structure and have an LLM propose the child boundaries and flag limit risks:

Prompt: “I have a 500-line .gitlab-ci.yml building 6 services in one monorepo. Propose a parent-child architecture: which jobs become which child pipelines, where to use rules:changes so only changed services run, and confirm strategy:depend on every trigger. Then flag any nesting-depth or downstream-pipeline-limit risk in your design and how to stay within GitLab’s limits.”

The limits check is the part I rely on most:

Output (excerpt): “Proposed: one child per service (6 children), all triggered from a flat parent — nesting depth 2, well within limits. Each trigger uses strategy:depend so child failures fail the parent. Risk: if each service-child further triggers per-environment grandchildren, you reach depth 3 across 6 services, which is fine for depth but watch the total downstream-pipeline count per parent. Recommendation: keep environment fan-out as jobs inside each child, not as grandchildren…”

Validate the proposal against your real repo and GitLab’s current documented limits before you commit — the model reasons well about structure but doesn’t know your exact instance limits. For reusable versions, the parent/child and multi-project pipeline design prompt, the dynamic child pipeline generation prompt, and the broader GitLab CI/CD category are where I keep them.

The bottom line

Parent-child pipelines turn an unmaintainable mega-config into a set of focused, independently owned pipelines. Always use strategy: depend so child failures fail the parent — without it your pipeline lies about success. Decompose by component with rules:changes so only changed parts run, generate children dynamically when the work set is data-driven, and keep the hierarchy shallow to stay inside GitLab’s nesting and downstream-pipeline limits. Let AI plan the split and flag the limit risks, then verify against your real repo before you ship.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.