Your GitLab CI pipeline has a complex dependency graph with 40+ jobs. Some jobs are taking longer than expected due to incorrect artifact dependencies and sequential execution where parallelism is possible. How do you diagnose and optimize pipeline execution using DAG visualization, needs keyword, and resource classes?
Quick Answer
Use GitLab's pipeline graph visualization to identify the critical path, convert stage-based execution to DAG with needs keyword, eliminate unnecessary artifact downloads with dependencies keyword, use resource_group for deployment serialization, and implement parallel with test splitting.
Detailed Answer
Diagnosing Pipeline Bottlenecks
GitLab's pipeline visualization shows job dependencies and execution timeline. The critical path is the longest sequential chain of jobs—this is your pipeline's minimum possible duration. Jobs outside the critical path can be optimized but won't reduce total time. Use CI/CD Analytics to see median durations over time and identify regressions. The job log's Preparing executor time reveals runner acquisition delays separate from actual execution time.
DAG vs Stage-Based Execution
Default GitLab behavior: all jobs in stage N must complete before any job in stage N+1 starts. This is wasteful when jobs have no data dependencies. The needs keyword creates a DAG: a job starts as soon as its declared dependencies complete, regardless of stage. Example: SAST scanning (no build dependency) can start immediately, while deploy (depends on build + test) waits only for those specific jobs. Stage names become purely organizational.
Artifact Optimization
By default, all jobs in a stage download all artifacts from the previous stage—even if they don't need them. dependencies: [] prevents downloading any artifacts. dependencies: [job-name] downloads only from specified jobs. For DAG pipelines, needs implicitly sets dependencies. Large artifacts (Docker images, compiled binaries) add significant transfer time; use artifacts:expire_in aggressively and consider registry storage for images instead of CI artifacts.
Resource Groups for Deployment
resource_group ensures only one job with that group name runs at a time—essential for deployments where two simultaneous deploys would conflict. Unlike stages, resource_group works across pipelines: if pipeline A is deploying, pipeline B's deploy job queues until A finishes. This prevents race conditions without blocking the entire pipeline.
Pipeline Efficiency Metrics
Track: pipeline duration (wall clock), total job time (sum of all job durations), and efficiency ratio (total time / duration / concurrent jobs). A 30-minute pipeline with 60 minutes of total job time running 10 concurrent jobs has poor efficiency—most jobs are waiting. Aim for the critical path to be less than 20% of total job time, indicating good parallelization.