GitHub Actions jobs in Cloudflare containers
A container that starts in seconds and is billed by the ten milliseconds is the shape of a CI job. Here is what one costs, what fits, and how to send jobs there.

Cloudflare Containers became generally available in April 2026. A container there is a small virtual machine that starts in a few seconds, is billed for every ten milliseconds it runs, and costs nothing when it is not running. That is the shape of a CI job. This post shows what a GitHub Actions job costs there, what fits and what does not, and how to send jobs to it.
What you get
Each container runs in its own Firecracker microVM, with its own kernel. The largest size has 4 CPUs, 12 GiB of memory and a 20 GB disk. Cloudflare says a cold start is “often in the 1-3 second range”, depending on the image.
It needs Cloudflare’s Workers Paid plan, at $5 a month.
What a minute costs
The price has three parts: $0.000020 for a CPU each second, $0.0000025 for a GiB of memory each second, and $0.00000007 for a GB of disk each second. Memory and disk are charged for the size you chose. CPU is charged only for what the job uses.
For the largest container, a minute comes to:
| What | A minute |
|---|---|
| Memory, 12 GiB | $0.0018 |
| Disk, 20 GB | $0.0001 |
| CPU, all 4 busy | $0.0048 |
| In all, all 4 CPUs busy | $0.0067 |
| In all, 1 CPU busy on average | $0.0031 |
GitHub’s own 4-core runner is $0.012 a minute. So a job that keeps four CPUs busy costs a little over half as much in a container, and a job that mostly waits (on a network, on a database, on one slow test) costs about a quarter.
The plan’s $5 already holds some of this each month: 375 CPU-minutes, 25 GiB-hours of memory and 200 GB-hours of disk. The Worker that starts the containers is billed as a Worker, on top.
A spot machine on AWS is cheaper still, at about $0.0014 a minute for 4 CPUs. What Cloudflare gives for the difference is a fast start, no AWS account, and nothing to pay between jobs.
What does not fit
- Large jobs. Four CPUs and 12 GiB is the most a container has.
- Arm, Windows, GPUs. An image has to run on linux/amd64, and no size has a GPU.
- Some Docker set-ups. Docker runs inside a container, but Cloudflare’s containers do not support iptables, so the containers a job starts share one network. Two services cannot listen on the same port.
- Very long jobs. Cloudflare restarts its hosts from time to time and does not promise how long a container runs.
Doing it yourself
A container is started by a Worker, so you need one that receives GitHub’s webhook when a job is queued, asks GitHub for a runner registration that is good for one job, starts a container with it, and puts the container to sleep when the job ends. You also need an image with GitHub’s runner in it, and something that notices containers whose job never arrived.
With SuperCI
SuperCI is that Worker, already written, and open source. One command opens its dashboard:
npx @superci/cli dashboard- Sign in with Cloudflare. The dashboard puts a control plane in your account, a Worker, and shows what that creates first.
- Connect GitHub. The dashboard makes a GitHub App that is yours.
- Add Cloudflare as a runner provider.
- Change one line in a workflow:
jobs:
test:
runs-on: superciEach job then gets a container of its own, with 4 CPUs and 12 GB, gone when the job ends.
For the jobs that do not fit, add AWS or Modal as well and put the providers in order. A job goes to the first one that can run its machine, so runs-on: superci-16cpu passes Cloudflare by and lands on AWS, while the small jobs keep starting in seconds. Runner providers has what each one runs, and Order and limits how jobs are placed.