Script icon
Docker icon
If icon
SlackIncomingWebhook icon
Log icon
Return icon
Schedule icon

GitLab Runner Concurrent Job Capacity Sentinel

Audits self-hosted GitLab Runners for concurrency saturation and queue delays, delivering actionable scaling alerts to DevOps teams via Slack.

Categories
CoreInfrastructure

Modern software development teams depend on GitLab CI/CD pipelines for automated testing, container builds, and production Kubernetes deployments. High-velocity engineering teams frequently operate private, self-hosted GitLab Runners on AWS EC2, GCP Compute Engine, or dedicated bare-metal servers to leverage specialized hardware such as GPUs or to access internal VPC subnets. However, during morning commit surges or scheduled release trains, self-hosted runner executors reach concurrency limits. As a consequence, builds queue silently in pending states, developer pull request turnaround times spike, and time-to-market degrades. If a runner daemon crashes or Docker daemon socket exhaustion occurs, pipelines stall indefinitely without explicit failure alerts. This sentinel polls the GitLab REST API v4 every 10 minutes, verifies executor online states, counts active in-flight jobs, and dispatches incident notifications to DevOps teams on Slack before developer build queues back up.

How it works

  1. Scheduled triggering: Executes every 10 minutes via automated cron trigger (*/10 * * * *) or runs on-demand via manual execution.
  2. Runner status retrieval: Queries the GitLab REST API endpoint /runners/{runner_id} to verify connectivity and retrieve executor operational status.
  3. Active job enumeration: Calls /runners/{runner_id}/jobs?status=running to obtain the list of currently executing pipeline builds.
  4. Capacity threshold evaluation: Compares active in-flight jobs against max_concurrent_jobs_threshold and verifies that the runner is marked online.
  5. Conditional alerting: An io.kestra.plugin.core.flow.If flowable checks if the runner is saturated or offline and dispatches a Slack alert to #cicd-operations.
  6. Manifest export: Emits a structured JSON audit payload detailing active jobs and runner status for downstream autoscaling or capacity planning.

Architecture diagram

flowchart TD
  A[ten_minute_gitlab_audit Schedule Trigger] --> B[evaluate_gitlab_runner_capacity Python Script]
  B --> C[check_runner_saturation Flowable If]
  C -- Runner Saturated or Offline --> D[notify_slack_runner_saturation Webhook]
  C -- Capacity Nominal --> E[log_runner_capacity_status Log]
  D --> E
  E --> F[export_gitlab_manifest Return]

What you get

  • Proactive detection of bottlenecked CI/CD runners before developer pull requests encounter long queue delays.
  • Immediate alerting when a self-hosted runner daemon goes offline, uncontactable, or paused.
  • Contextual Slack alerts detailing active jobs, project repositories, and direct GitLab admin console links.
  • Structured JSON execution metrics to drive horizontal runner autoscaling automation.

Who it's for

  • DevOps and Platform Engineers managing private Kubernetes or VM-based GitLab Runner fleets.
  • Release Managers ensuring timely build, test, and container deployment cycles across engineering.
  • Engineering Managers monitoring CI/CD pipeline infrastructure health and developer productivity metrics.

Why orchestrate this with Kestra

GitLab CI pipelines queue silently when runners hit concurrency ceilings or underlying Docker daemons lock up. Kestra provides an independent, out-of-band control loop that interrogates the GitLab API, validates executor health, and coordinates alerting or auto-remediation workflows. With Kestra's containerized Python runner and native secret management, platform teams can manage fleet reliability without writing brittle custom daemons.

Use cases

  • Self-Hosted Runner Availability Watchdog: Detect when a private runner host encounters an unexpected kernel panic or Docker socket failure.
  • CI/CD Queue Bottleneck Prevention: Identify when concurrent job allocations approach hardware limits and trigger additional runner instances.
  • Multi-Project Shared Runner Governance: Monitor shared runner fleets across multiple teams to prevent noisy-neighbor build monopolization.

Inputs

Name Type Default Description
gitlab_api_endpoint STRING https://gitlab.com/api/v4 Base REST API v4 endpoint for GitLab SaaS or self-hosted GitLab instance.
gitlab_runner_id INT 123456 Numeric identifier of the target self-hosted or fleet GitLab Runner.
max_concurrent_jobs_threshold INT 10 Maximum allowable running jobs on the runner before declaring capacity saturation.
alert_on_saturation BOOL true Whether to dispatch automated Slack alerts when runner capacity is saturated or offline.

Expected outputs

  • {{ outputs.evaluate_gitlab_runner_capacity.vars.runner_description }}: Display name or description of the evaluated GitLab runner.
  • {{ outputs.evaluate_gitlab_runner_capacity.vars.active_jobs_count }}: Number of currently running CI/CD jobs on the runner.
  • {{ outputs.evaluate_gitlab_runner_capacity.vars.is_saturated }}: Boolean flag indicating whether the runner has breached capacity limits or gone offline.
  • {{ outputs.export_gitlab_manifest.value }}: Structured dictionary containing the consolidated runner health summary.

Prerequisites

  • Outbound HTTPS network access from Kestra execution workers to the GitLab API endpoint.
  • A GitLab Personal Access Token or Project Token with read_api scope.
  • A Slack Incoming Webhook URL configured in Kestra secrets.

Secrets

  • GITLAB_TOKEN: GitLab access token with permissions to read runner configurations and active jobs.
  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL used to dispatch CI/CD incident notifications.

Quick start

  1. Register GITLAB_TOKEN and SLACK_WEBHOOK_URL in your Kestra secret storage.
  2. Import this blueprint into your Kestra instance under the company.cicd namespace.
  3. Update gitlab_runner_id with your runner ID (found under GitLab Project Settings > CI/CD > Runners).
  4. Run a manual execution to verify runner discovery and validate the diagnostic output format.

Common pitfalls and troubleshooting

  • Token Permissions: Ensure the token possesses read_api or admin:read scope; standard repository tokens without API permissions will return 401 Unauthorized.
  • Self-Hosted TLS Certificates: For self-hosted GitLab installations with private CAs, ensure your Kestra worker environment trusts the internal CA root.
  • Runner Registration States: If a runner is marked paused in the GitLab UI, the sentinel flags it as saturated to prevent silent job accumulation.

How to extend

  • Automated Runner Autoscaling: Trigger an AWS Auto Scaling Group or Kubernetes HPA scale-out event when concurrent jobs exceed 80% capacity.
  • Docker Daemon Pruning: Dispatch an SSH or Ansible command to restart gitlab-runner and execute docker system prune if executor errors occur.
  • Fleet-Wide Matrix Scanning: Wrap the evaluation in an io.kestra.plugin.core.flow.ForEach loop to monitor all runners registered across the GitLab organization.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.