Build Servers That Switch Off: Your Own CI Runner on a KVM VPS
Hosted continuous integration is priced per minute, and a build that takes eight minutes on a shared runner often takes three on a machine with warm caches and a real disk. Once a team runs a few hundred builds a month, a small virtual machine that you own outright starts to look like the cheaper and faster option at the same time. This is how to size one, where to put it, and how to use billing by the hour for the peaks without paying for idle capacity.
What a build runner actually needs
Runners are unusual workloads. They are bursty, they are disk heavy, and they care far more about local cache than about network latency to your users. In rough order of importance:
- Disk, and disk that stays put. Dependency caches, container layers and build outputs are the difference between a three minute build and a ten minute one. A runner that throws its cache away every run is a slow runner.
- RAM. Node and Java toolchains are memory hungry, test suites run in parallel, and a container build holds layers in page cache. 8 GB is a comfortable floor for one runner doing real work.
- vCPU. Useful, but only to the point where your test suite actually parallelises. Measure before paying for cores.
- Predictability. A runner that is never queued behind someone else's job is worth more than a slightly faster one that is.
Picking a plan
Our six KVM plans map onto runner sizes fairly cleanly. All of them come with unmetered traffic, which matters more than people expect once a pipeline starts pulling base images on every run.
| Plan | RAM | vCPU | SSD | Good for |
|---|---|---|---|---|
| Pulse | 4 GB | 2 | 40 GB | A single lightweight repository, linting and unit tests |
| Core | 8 GB | 2 | 60 GB | One busy repository with container builds |
| Forge | 16 GB | 4 | 80 GB | Two or three concurrent jobs, integration tests with a database |
| Apex | 24 GB | 6 | 100 GB | A small team's whole pipeline, browser tests included |
| Titan | 32 GB | 8 | 120 GB | Monorepo builds and parallel matrix jobs |
Disk fills faster than anything else on a runner. If you keep container layers, you can add storage in 50 GB units at €4 per unit per month, up to three units, so a Core can carry 210 GB in total. Full prices for every plan and city are in our price by location breakdown, and the sizing calculator will compare two plans for you.
Where to put it
A runner does not need to sit near your users. It needs to sit near the things it talks to most, which is usually your code host, your container registry and your artefact storage. All five of our VPS cities are inside a 10 ms radius of the Frankfurt hub, so any of them is a reasonable home for a European team.
- Frankfurt if your registry and artefact storage are in Western Europe, which is the common case.
- Amsterdam if you already run production in Frankfurt and would rather your build path did not share a single site with it.
- Vienna or Warsaw if your team is in Central Europe and you want the shell to feel local when you SSH in to debug a failing job.
- Bucharest if the runner is a cost line rather than a latency question. It is our base price on every plan.
Using hourly billing for the peaks
The interesting part of running your own is that a second runner does not have to exist all month. Every plan can be taken by the hour as well as by the month, and the rate is simply the monthly price divided by 720, plus the location fee divided by 720.
A Forge in Vienna is €0.0389 an hour. A release week where you bring up a second runner for 30 hours of parallel jobs costs €1.17. A migration weekend on a Titan in Frankfurt, 20 hours at €0.1167, costs €2.33. Those are rounding errors against a per minute bill for the same work.
Three rules make this work rather than backfire:
- Deleting the server is what stops the charges. Powering it off does not, because the disk and the IPv4 address still exist and are still reserved for you. This is the single most common way people are surprised by an hourly bill.
- Keep the permanent runner on a monthly cycle. 720 hours of usage costs exactly one month, and a 31 day month is 744 hours, so an always on machine is cheaper on the monthly, quarterly or annual cycle. Hourly is for the machines that come and go.
- Keep credit topped up. Hourly servers draw from account credit, we warn you about a day before it runs out, and a server whose credit runs dry is suspended an hour later. Automatic top up exists precisely so a build farm does not stop on a Friday night.
Setting one up
Nothing here is exotic. A runner is a plain Linux box with a build toolchain and an agent that polls your code host.
- Choose an image. Debian 12 or 13 and Ubuntu 24.04 LTS are the safe defaults, and all three are in our image list along with AlmaLinux, Rocky, Fedora, openSUSE, Arch and FreeBSD. Match the runner to whatever your production containers are built on.
- Create an unprivileged user for the agent. The agent runs untrusted code by definition, because a pull request can change the build script.
- Install the container runtime and the agent, then register the runner against your project with a scoped token rather than an account wide one. Our piece on containers on a VPS covers the runtime side.
- Close the box down. A runner needs outbound access and almost no inbound access at all. Allow SSH from your own addresses and nothing else, which the walkthrough in setting up a firewall takes about ten minutes to do properly.
- Schedule a cache prune. Container layers and old workspaces will fill any disk you give them. A weekly prune job is less annoying than a full disk at the wrong moment.
The cases where a runner is the wrong answer
Being honest about this saves everyone time.
- You need Windows or macOS builds. Our VPS range is Linux and FreeBSD only. Windows Server images are available on bare metal, and macOS is not something we offer at all.
- Your builds are genuinely rare. Ten builds a month on free hosted minutes costs nothing, and a server you forget about costs more than that.
- You need dozens of parallel jobs on demand. One large machine will be busy and several small ones will be idle. At that scale the operational work of scheduling them starts to outweigh what you save.
- Nobody will own it. A self managed runner is a server. It needs patching, disk hygiene and someone who notices when it stops. Our notes on server security are the short version of that job.
Where to start
If you already know the shape of your pipeline, a Core or a Forge on a monthly cycle is the sensible first runner, with hourly machines for release weeks. Pick one on the VPS page, choose the city closest to your registry, and you will be registering the agent inside ten minutes. Our continuous integration use case page has the short version if you want to compare it against the rest of the range first.
Deploy what you just read about
Deploy your first server now.
No contracts, no minimums. Start on an Ion KVM VPS at €0.0063 an hour and move to a monthly bare-metal server the day you outgrow it.
KVM VPS billed hourly, capped monthly · Dedicated billed monthly · No setup fee
- Free IPv4 + IPv6
- Every VPS
- Unmetered traffic
- 1–10 Gbps
- DDoS mitigation
- 2.5 Tbps
- Root / IPMI access
- Included
- Setup fee
- €0.00
- Minimum term
- None