Hosted continuous integration: pipelines defined in a file, parallel jobs, caching and machines of several sizes, including ones with more memory than a free runner.
Build me continuous integration on my own machines instead of paying CircleCI: pipelines from a file, parallel jobs, caching, and a big machine when the suite needs one. Read this first: the honest comparison is against a free tier plus a self-hosted runner, which is usually the right answer. Build this when you want the whole thing on your own hardware — a bare-metal box with real memory and fast disks will run a large suite several times faster than a hosted small instance, and it costs a fraction. STACK - Node 20+ with Fastify for the control plane - SQLite through better-sqlite3, WAL mode - Runners as agents that poll for work; jobs execute in containers - Docker or Podman on each runner - Caddy in front THE DATA MODEL - repos: id, name, remote_url, default_branch, webhook_secret, deploy_key_encrypted - pipelines: id, repo_id, commit_sha, ref, kind, actor, message, config_json, status, created_at, started_at, finished_at - jobs: id, pipeline_id, name, requires_json, image, resource_class, status, exit_code, started_at, finished_at, runner_id, attempt - steps: id, job_id, position, name, command, status, exit_code, started_at, finished_at, ms - logs: job_id, chunk_index, content_gzip — streamed in chunks and compressed, never one enormous column - artifacts: id, job_id, path, sha256, bytes, expires_at - caches: id, repo_id, key, path, sha256, bytes, created_at, last_used_at - runners: id, name, resource_class, labels_json, token_hash, last_seen_at, capacity, in_use - test_results: id, job_id, suite, name, status, duration_ms — parsed from JUnit XML, which every test framework can emit THE CONFIGURATION FILE - One YAML file in the repository defining jobs, their images, their steps and what they require - A directed graph, validated before anything runs: a cycle, a missing dependency or an unknown image is an error reported on the commit rather than a job that hangs - Matrix expansion for versions and platforms - Conditions on branch, tag, path changed and manual approval - The file is validated by the same code that runs it, and there is a command to check it locally before pushing. Debugging a pipeline by pushing commits is the most demoralising loop in software RUNNING A JOB - Fresh container per job from a declared image, with the repository checked out at the commit - Resource classes as data: small, large, and one with a lot of memory, each mapping to a runner label and a set of container limits - Steps run in order, output streamed and stored, and the first non-zero exit stops the job unless the step is marked as allowed to fail - A wall-clock timeout per job and per step, always - The workspace can be passed between jobs as an artifact, which is how a build job feeds a test job CACHING, WHICH IS MOST OF THE SPEED - A cache key template with checksums of lock files, and a list of fallback keys tried in order - Save and restore as explicit steps, with the size and the hit or miss printed — a silent cache miss is why a build got slow and nobody noticed - Content-addressed storage on the runner's local disk plus a shared store, with an eviction policy by last use - Docker layer caching where the runner allows it PARALLELISM - Split a test suite across N containers, balanced by the recorded timings of previous runs rather than by file count. This is the single biggest win and it needs the test_results table - Jobs that do not depend on each other run at once, bounded by runner capacity - Fail fast as an option: one failure cancels the rest of the pipeline FEEDBACK - Status posted back to the forge on every job, with a link - A pull-request comment summarising failures with the relevant log lines, not a link to a log to go and read - Flaky test detection: the same test failing and passing on the same commit, tracked over time and listed. A suite nobody trusts is a suite everybody ignores - Email or chat on a broken default branch, once, with the recovery message when it is fixed SECRETS - Encrypted at rest, injected as environment variables at run time, scoped per repository and per context - Never available to a job from a fork by default - Redacted from every log by value match, including base64 and URL-encoded forms - Rotation supported, with the last use of each secret recorded OPERATIONS - .env: DATABASE_PATH, BASE_URL, ENCRYPTION_KEY, RUNNER_TOKEN_SALT, ARTIFACT_PATH, SESSION_SECRET - Migrations on boot, each once - Log and artifact retention with a stated policy and a sweeper, because this is what fills the disk - Disk watchdog that refuses new jobs rather than filling the volume - Nightly backup of the database; artifacts are reproducible - Health endpoint reporting queue depth, runner count and free disk WHAT MATTERS MOST The job graph, the container isolation and the timing-based test split. Build those first and run your real suite on it — if it is not faster than what you pay for now, on hardware that costs less, there is no reason to have built it. Give me the repository, the runner agent, migrations, .env.example, an example pipeline file, and a README with deploy steps for the control plane and for a runner.
What you lose
- Larger machines and higher parallelism than free tiers offer, which is what a big test suite needs
- Caching and artefact storage tuned for build speed
- Support when a build breaks in a way you cannot reproduce
If you would rather not build
- A self-hosted runner on a rented server
What it costs
read from their page 15 Aug 2026
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $15/mo | — | 15 Aug 2026 |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
Woodpecker CI
$0A small self-hosted CI engine driven by a pipeline file.
woodpecker-ci/woodpeckerfree · open source
act
$0Runs GitHub Actions workflows locally, which shortens the feedback loop.
nektos/actfree · open source
Why this verdict
our own opinion · changed only by a person
76/100
Verdict yes at 76. Included CI minutes cover most projects, and a self-hosted runner is cheaper than paid minutes above that. The fork rule is a security matter.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about CircleCI
answered from the record above
Is CircleCI free?
No — the plan we track is $15 a month. Performance from around $15/month billed monthly plus credits for compute.
Can you replace CircleCI by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 76 out of 100, build time one session. Read what you lose before you decide.
How much does CircleCI cost?
$15 a month on Performance — $180 a year. Recorded 10 Aug 2026.
What do you lose by replacing CircleCI?
Larger machines and higher parallelism than free tiers offer, which is what a big test suite needs; Caching and artefact storage tuned for build speed; Support when a build breaks in a way you cannot reproduce. If any of those carry weight for you, keep paying.
Is there an open-source alternative to CircleCI?
Yes: Woodpecker CI, act. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

