Serverless GitLab runners in your own cloud account
Jobs that need no Docker daemon can run as Scaleway Serverless Jobs in their own image, billed per second. Jobs that need one get a VM with GitLab's Docker executor, so services: and docker build work as on GitLab's runners; the VM ends itself when it is idle at minute 55 of its paid hour. Between pipelines nothing runs.
- Serverless Job starting
- job in a lane
- waiting 60 s for the next job, then gone
- job on a VM
Design: docs/SPEC.md. Operations: docs/RUNBOOK.md. Providers: docs/PROVIDERS.md. AI agents: AGENTS.md.
Example: ciburst-adopt-demo, a small project before and after adopting ciburst. Its second commit, Adopt ciburst, is the whole change, and its pipelines show which job ran on a VM and which in a lane.
Status: 1.0.0. The component is in the GitLab CI/CD Catalog: @1 is the newest 1.x release and runs the cli image of that release; @main runs the image edge.
How it works
- GitLab sends every job and pipeline event of each project to the dispatcher, a Scaleway Function.
- Each project routes its own jobs by name: a job in its
ignoreJobsruns on other runners and starts nothing; a job that a lane of itsciburst.jsonnames runs in that lane; every other job runs on the VM runner.ciburst check --suggestprints lanes for the jobs that need no Docker daemon. - A lane job starts a Serverless Job of its project's lane in the lane's image, which runs it and exits after 60 idle seconds; billed per second.
- When a pipeline starts and any of its jobs will need a VM, one VM boots right away if none has a free slot, so a Docker job in a later stage finds it ready (
warmStart, on by default; it costs one VM-hour, 0.03 EUR, when the pipeline ends before that job runs). - A pending VM job claims a free slot on a running VM. When every slot is busy it waits in a queue, and GitLab hands it to the first slot that frees; ciburst buys another VM only when the wait would pass
maxQueueS(default 90 s, about one VM boot), judged by how long the running jobs usually take. With no VM running, jobs that wait together share new VMs (two slots each, so five jobs start three VMs). - Each VM runs one
gitlab-runner runfor its slots, serving every project of the setup, and reports its state to the dispatcher. An idle VM ends at minute 55; a sweep every 30 minutes removes VMs that stopped reporting. - Setup, check and teardown run in your own pipeline on GitLab's hosted runners, from manual jobs of the CI/CD component.
Cost and limits
- VMs: about 0.03 EUR per Scaleway DEV1-M hour (VM, IPv4, disk), billed per started hour. A cold pipeline with five jobs costs about 0.09 EUR; pipelines within the same hour reuse the VMs.
- A cold job waits 60 to 100 s for its VM; on a running VM about 3 s.
- DEV1-M: 3 vCPU and 4 GB shared by two slots, plus 4 GB swap. A job without
image:runs inubuntu:24.04. - DEV1 vCPUs are shared: CPU-bound jobs (compiles, lint and typecheck, browser tests) take 1.3 to 4 times as long as on GitLab's small hosted runner, even on a DEV1-L of their own; network-bound and short jobs are on par.
- Lanes: 0.00001 EUR per vCPU-second and 0.000002 EUR per GB-second, so about 0.0017 EUR per minute at 2 vCPU and 4 GB (0.10 EUR per hour) and 0.0034 EUR per minute at 4 vCPU and 8 GB (0.20 EUR per hour). A run also bills its bootstrap and its idle
waitTimeoutS(60 s by default) before it exits. The first 200,000 vCPU-seconds and 400,000 GB-seconds of each month are free, about 28 hours at 2 vCPU and 4 GB. - A lane run starts in 5 to 12 s for small images, 19 to 28 s for Rust and Playwright images, 93 s at 6 vCPU. Installing missing
gitandcurladds 2 to 4 s on Alpine and about 21 s on Debian and Ubuntu slim images. - Lane speed: a Rust compile at 2 vCPU takes as long as on GitLab's small hosted runner, at 4 vCPU about half as long; a TypeScript check is within 12 %.
- The first setup takes 6 to 15 hosted-runner minutes while Scaleway compiles the dispatcher; later setups take under a minute.
linux/amd64only.- A job cache over 5 GiB is not saved (Scaleway's S3 copy limit); the job still passes and logs
Failed to create cache.
Compared per job-minute for a small runner (providers' price pages, 2026-10-25, 1 EUR = 1.1193 USD; sources in docs/SPEC.md section 16):
| Option | EUR per job-minute | Billing |
|---|---|---|
| GitLab.com hosted, small (2 vCPU, 8 GB) | 0.0089 after 400 free minutes a month | per minute |
| AWS CodeBuild GitLab runner, small | 0.0045 | per job, rounded up to minutes |
| Self-built on AWS spot, m6i.large | 0.0009, plus about 10 EUR a month for the manager | per second |
| RocketRunner small, one always-on VM | 9.46 EUR a month flat | per minute, capped |
| ciburst VM slot, half a DEV1-M, half the paid hour used | 0.00045 | per started hour |
| ciburst VMs, measured: the drill consumer's 3 pipelines on one DEV1-L per job | 0.0046 | per started hour, VMs busy about 20 % of it |
| ciburst lane, 2 vCPU | 0.0017, free up to about 1,700 minutes a month | per second |
A month of 3,000 job-minutes: GitLab 23.23 EUR, self-built AWS spot 12.95, RocketRunner 9.46, ciburst lanes 2.24, ciburst VM slots 1.36. A VM slot has 1.5 shared vCPU and 2 GB, GitLab's small runner 2 vCPU and 8 GB.
VMs reach their per-minute price only when pipelines keep them busy through their paid hours. A project with a few pipelines a day pays mostly for idle minutes until minute 55; its Docker-free jobs cost less in lanes, which bill per second and start inside the free tier.
Adopt
include:
- component: gitlab.com/ciburst/ciburst/ciburst@1Then a Scaleway key, a GitLab token, four CI/CD variables and one run of the manual job ciburst-setup: the steps.
Development
Rust 1.96.0 (rust-toolchain.toml). Before a commit: cargo fmt --all --check, cargo clippy --workspace --all-targets --all-features -- -D warnings, cargo test --workspace --all-features, cargo deny check, scripts/shellcheck.sh, scripts/check-pins.sh; scripts/test-linux.sh for Linux-only code, images/test/lane-bootstrap.sh after a change to the lane bootstrap. The site: cargo run -p ciburst-site -- public builds it from this README, AGENTS.md and docs/ (docs/SPEC.md section 11.5). New providers: docs/PROVIDERS.md. Contributions: CONTRIBUTING.md (Developer Certificate of Origin, git commit -s); conduct: CODE_OF_CONDUCT.md; vulnerabilities: SECURITY.md.
License
Apache-2.0, see LICENSE and NOTICE.