Runners that exist only while the job does.
Your Gitea queues a job. A fresh machine boots, joins your tailnet, runs it, and is destroyed. Nothing idles, nothing drifts, and you are billed for the minutes you used.
You provision a runner that sits idle most of the time
With self-hosted Gitea runners, you keep infrastructure online, maintain it, and pay for it — even when there's nothing to build.
Traditional self-hosted runner
Always on. Mostly idle.
You keep a machine online 24/7, but it only does real work for a few minutes each day.
Ephemeral runners
A fresh runner for every job.
A machine appears when a job is queued, runs it, and is gone. No idle time. No leftover infrastructure.
You pay for idle capacity
The runner sits unused most of the day, but you're still paying for the server, storage, and bandwidth.
No idle time, no wasted spend
You only pay for the minutes your jobs actually run.
Manual scaling
You have to anticipate demand, provision machines, and adjust capacity by hand — or risk slow builds.
No maintenance burden
Runners are fresh each time, with the latest base image and security updates. Nothing drifts, nothing to patch.
~23 hours of idle time
Let the job create the runner — and the runner disappear when it's done.
Connect it once. Then forget it.
Three steps, and no runner left running.
- 1
Connect your Gitea
An org-scoped token and a runner registration token. Your secrets never leave your Gitea.
gitea.yourcompany.devConnect your GiteaPaste your registration token Connect - 2
Map labels to machines
Decide what ubuntu-latest means and what build-heavy gets. Change it whenever you like.
Which labels do we cover?ubuntu-latest build-heavyMachine for this label 4 vCPU Bigger machines for the labels that need them. - 3
Push, and forget it
A job queues, a machine appears, runs it, and is destroyed. You see minutes, not machines.
This month Within cap- Jobs run
- 1,284
- Minutes billed
- 3,940
- Idle cost
- €0
Nothing ran idle. 1,284 jobs, 3,940 minutes billed, and no machine left running.
Everything a runner needs, and nothing to maintain.
You configure labels. We do the rest.
- gitea.yourcompany.devQueued: build-heavy
Spawned on demand
A queued job brings a machine up within seconds, and it is destroyed the moment the job ends.
- Boots when a job is queued
- Destroyed when it finishes
- No machine between runs
- Machine spawned
- Job completed
- Machine destroyed
One job, enforced by Gitea
Every worker registers as ephemeral, so Gitea revokes its credentials the moment a job is assigned. It cannot take a second one.
- Ephemeral registration, server-side
- Reaches one host on your tailnet
- Destroyed after every job
- This month €61€150 Your cap
Billed per minute
You pay for the minutes a job actually ran. Idle hours do not exist here, because idle machines do not.
- Per-minute billing
- A spend cap you set
- Nothing charged for idle
Not cheaper. Never idle.
A small always-on runner is a few euros a month. This is about the hours it does nothing, the jobs that queue behind each other, and the patching you never asked for.
A runner you keep online
One machine, always on
It works for minutes a day and waits for the rest. The waiting is the part you pay for and maintain.
- Machines you run
- One, always
- Parallel jobs (one box)
- One at a time
- Docker, buildx, the base image (and the drift)
- Yours
- A bigger machine
- A migration
With Runner Pool
A machine per queued job
Machines appear for the job and are destroyed after it. There is nothing between runs to pay for or to patch.
- A machine per queued job
- €49 / month
- Parallel jobs, as many as you allow
- Included
- Patching, drift and upkeep
- Included
Runner Pool costs €49 / month
plus €0.15 to €0.45 per hour of actual job time, billed per minute. Nothing for the hours you do not use.
Questions
What people ask before connecting an instance.
No. Your workflows keep the runs-on labels they already have. You decide which machine each label gets, and you can change that at any time without touching a workflow file.
That is the case it was built for. Workers join your tailnet and reach your Gitea there, so nothing has to be exposed and no ports have to be opened.
€49 a month per organisation, plus €0.15 to €0.45 per hour of actual job time depending on the machine, billed per minute. There are no idle hours to pay for, because there are no idle machines.
Not always, and we will not pretend otherwise. A small always-on box is a few euros a month and hard to beat on price alone. You come out ahead when your load is spiky, when jobs queue behind one another, or when you want a machine you would never rent full time.
Each worker joins your tailnet with an ephemeral, tagged key scoped to your Gitea host and port. It takes exactly one job — Gitea revokes its credentials once that job is assigned — and the machine is destroyed afterwards. It never sees another repository, another organisation, or another customer.
Three things, all scoped as narrowly as Gitea and Tailscale allow: an org-scoped API token so we can see which jobs are queued, an org-level runner registration token, and a Tailscale auth key. No admin token, and nothing that reaches past the organisation you connect.
You set a concurrency cap and a monthly spend cap. We stop spawning when a cap is reached rather than sending you a surprising invoice.
It's stored so we can reach you about early access, and used for nothing else. Ask us to delete it and we will.


