Measure queue time and run time separately. Queue time is how long a job waits for a runner. Run time is how long the scanner works. If most of the delay is queueing, speeding up the scanner changes nothing, and the fix is runner capacity or job ordering.
Why the split matters
A developer pushes a commit, sees a pending security check for a long while, and concludes the scanner is slow. The security team then spends a quarter tuning the scanner. Later someone notices the job started late, not that it ran long. The tuning bought almost nothing.
One total duration number cannot tell these two stories apart. Two numbers can.
Where to find the numbers
Most CI systems record when a job was created, when it started and when it finished. Queue time is start minus created. Run time is finished minus start. If your platform exposes only the first and last, check whether job timestamps are available through its API.
GitLab's pipeline efficiency documentation notes that overall pipeline duration depends on the repository, the number of stages and jobs, the dependencies between jobs and the critical path, along with the availability of runners and the resources they have. GitHub documents that a job can wait in the queue for a long period before being cancelled automatically. Both point to the same lesson: wait and work come from different causes.
Reading the two together
| Pattern | Likely cause | First thing to try |
|---|---|---|
| Long queue, short run | Not enough runners at peak times | Add capacity or schedule heavy jobs off peak |
| Short queue, long run | Slow scan, cold cache, large input | Cache vulnerability data, narrow scope |
| Both long | Shared overload | Separate the security job onto its own runner pool |
| Both short but total long | Chain of dependent jobs | Check the critical path and run jobs in parallel |
The last row catches teams who put the scan at the end of a long chain. The scan itself is quick, but it cannot start until everything before it has finished.
Steps
- Add queue time and run time as separate fields in your security job records.
- Chart both by hour of day and day of week. Peaks in queue time usually line up with working hours in your busiest timezone.
- Look at the critical path of a typical pipeline. If the security job sits on it, ask whether it can start earlier, for example in parallel with tests.
- Check whether the security job requests a bigger runner than it needs, which can lengthen the wait.
- After any change, compare the same measures for a few weeks before declaring success.
A note on fairness
Do not give the security team blame for queueing it does not control, and do not let platform teams dismiss real scan slowness either. The point of splitting the metric is to route the problem to the right owner with evidence.
Try it yourself
Click through it at your own pace, or open it full screen. Notice how a monitoring view separates what ran from when it ran.
Quick check
Is queue time a security metric?
It is a pipeline metric that affects security, because long waits push people toward bypassing checks. Track it alongside scan results.
Should security jobs get priority runners?
Only if data shows security jobs are queued longer than comparable jobs. Prioritise by evidence, not by default.
How Safeguard fits
Safeguard's gates and policies run on the results of dependency and SBOM scans, and you can start with a free scan at gold.safeguard.sh/scan to see a baseline before changing your pipeline.
Sources
- GitLab Docs, Pipeline efficiency: https://docs.gitlab.com/ci/pipelines/pipeline_efficiency/
- GitHub Docs, Actions limits (job queue time): https://docs.github.com/en/actions/reference/limits
Last reviewed: 19 October 2026.