GitLab CI Scheduled Pipelines
GitLab CI/CD supports scheduled pipeline triggers configured through a project's Schedules UI (CI/CD > Schedules), using standard cron syntax under the hood to define when a pipeline runs automatically without a push or merge request event.
Syntax Notes
Standard 5-field cron syntax (minute, hour, day-of-month, month, day-of-week), entered directly in the Schedules UI's 'Interval Pattern' field, with a separate timezone dropdown — the schedule always runs against whatever timezone is selected there, not necessarily UTC or the runner's local time.
Examples
job:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'job:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- when: on_success0 2 * * *Gotchas
- Creating a schedule alone doesn't limit which jobs run — every job in .gitlab-ci.yml still executes on a scheduled pipeline unless it has an explicit rules: condition checking $CI_PIPELINE_SOURCE == "schedule".
- Scheduled pipelines run against the branch or ref configured in the schedule, not necessarily the default branch — a schedule left pointed at an outdated branch keeps running against stale code indefinitely.
- GitLab may skip or delay scheduled pipelines under heavy runner load — GitLab's own docs are explicit that schedule times are a target, not a guarantee, the same caveat that applies to GitHub Actions' cron schedules.
Best Practices
- Always gate schedule-only logic behind an explicit if: '$CI_PIPELINE_SOURCE == "schedule"' rule rather than assuming a job won't run outside the schedule.
- Double-check the schedule's target branch after creating it, and again after any branch renaming or restructuring — a schedule silently pointing at a stale or deleted branch is a common source of 'why didn't this run' confusion.
- Set the schedule's timezone explicitly rather than assuming UTC, especially for anything tied to business hours or a specific region's off-peak window.
Frequently Asked Questions
- Do I need cron syntax knowledge to schedule a GitLab pipeline?
- Yes — the Schedules UI's Interval Pattern field expects standard 5-field cron syntax directly (e.g. 0 2 * * * for nightly at 2 AM), with a separate dropdown for timezone.
- Why did every job run on my scheduled pipeline, not just the one I wanted?
- By default, all jobs in .gitlab-ci.yml run on any pipeline trigger, including scheduled ones. Add a rules: condition checking $CI_PIPELINE_SOURCE == "schedule" to jobs that should only run on the schedule, or use when: never to exclude jobs from it.
- Is a GitLab scheduled pipeline guaranteed to run at the exact time?
- No — GitLab documents scheduled pipeline times as approximate, and heavy runner load can delay or occasionally skip a scheduled trigger, the same caveat that applies to GitHub Actions' cron schedules.
Related Tools
Platform Guides
Cron syntax for Linux, Kubernetes, AWS, and more
Celery Beat Schedule Guide
Schedule periodic tasks in Celery with Beat: the crontab() schedule helper, beat_schedule dict syntax, common pitfalls, and Django integration.
Rails Cron Jobs with Whenever
Schedule background jobs in Ruby on Rails with the whenever gem: schedule.rb syntax, writing a crontab automatically, and common deployment gotchas.