How do multi-project pipelines work in GitLab and how do they differ from parent-child pipelines?
Quick Answer
Multi-project pipelines trigger pipelines in other GitLab projects using the trigger keyword with a project path. Unlike parent-child pipelines (which run within the same project), multi-project pipelines cross project boundaries, enabling cross-repository orchestration for microservice deployments, shared library validation, and release coordination across independent services.
Detailed Answer
Think of multi-project pipelines like a supply chain across different factories. The car factory (project A) needs engines from the engine factory (project B) and transmissions from the transmission factory (project C). When the car factory starts a new production run (pipeline), it sends orders (triggers) to both the engine and transmission factories. Each factory runs its own manufacturing process independently, but the car factory waits for the parts to arrive (downstream pipelines to complete) before final assembly. Unlike parent-child pipelines (which are departments within the same factory), multi-project pipelines coordinate across completely separate facilities with their own managers, budgets, and processes.
Multi-project pipelines are created using the trigger keyword with a project path instead of an include. When a job specifies trigger: project: 'group/other-project', GitLab creates a new pipeline in the target project on the specified branch (defaulting to the target project's default branch). The trigger job in the source project can pass variables to the downstream pipeline and optionally wait for it to complete using strategy: depend. The downstream pipeline runs with the target project's .gitlab-ci.yml and its own Runners, variables, and permissions. This is fundamentally different from parent-child pipelines: parent-child pipelines run within the same project context, share the same project permissions, and appear nested in the UI. Multi-project pipelines run in separate projects, have independent permissions, and appear as linked pipelines in the UI with arrows showing the triggering relationship.
Internally, when GitLab processes a multi-project trigger job, it uses the CI_JOB_TOKEN of the triggering job to authenticate against the target project's pipeline creation API. This requires that the source project has been granted the trigger pipelines permission in the target project's CI/CD settings (Settings > CI/CD > Pipeline triggers or the newer CI/CD > Job token permissions). The downstream pipeline is created with a reference back to the upstream pipeline, enabling the linked visualization in the UI. Variables passed through the trigger are injected as pipeline-level variables in the downstream project, following the standard variable precedence rules. If strategy: depend is set, the upstream trigger job polls the downstream pipeline's status and mirrors it. The upstream pipeline's overall status then depends on the downstream pipeline, creating a cross-project dependency chain.
In production, multi-project pipelines are essential for microservice architectures where services live in separate repositories. Consider a ride-sharing platform with separate projects: rider-app, driver-app, matching-engine, payment-service, and api-gateway. When the shared-libraries project pushes a new version, its pipeline triggers downstream pipelines in all consuming services to verify backward compatibility. Similarly, when matching-engine is updated, its pipeline triggers integration tests in rider-app and driver-app because they depend on the matching engine's API. A release coordinator pipeline in a dedicated release-orchestrator project triggers deployments across all services in the correct order: first deploy matching-engine, then api-gateway, then rider-app and driver-app in parallel. This cross-project orchestration ensures that interdependent services are deployed together and validated as a system.
A key gotcha is the authentication and permission model. By default, CI_JOB_TOKEN can only trigger pipelines in projects that have explicitly allowed it. If you get a 403 error when triggering a downstream pipeline, check the target project's CI/CD settings to ensure the source project is in the allow list. Another common issue is variable collision: if you pass a variable like DEPLOY_ENV from the upstream pipeline, it might conflict with a variable of the same name defined in the downstream project's settings, and the precedence rules determine which wins. Unlike parent-child pipelines, multi-project pipelines cannot share artifacts directly; you need to use the GitLab API to download artifacts from the upstream pipeline or publish them to the package registry. Also, there is no nesting depth limit for multi-project pipelines (project A can trigger B which triggers C which triggers D), but long chains create fragile dependency graphs that are hard to debug.