CircleCI

Performance-first SaaS CI. Per-second billing, fast hosted runners, Orbs registry for reusable config, automatic test splitting by timing, contexts for shared secrets, runners for self-hosted hardware.

Overview

CircleCI: performance-first SaaS CI

CircleCI launched in 2011, doing public cloud-native CI before that was common. It has long led on build performance: fast hosted runners, generous parallelism, automatic test splitting by timing, per-second billing. Its 2026 share is ~7-10% per JetBrains DevEcosystem: smaller than the big three (GHA, Jenkins, GitLab CI) but a real player, especially in the JS/Node and Rails ecosystems.

Where CircleCI wins

  • Build speed — Hosted runners are consistently fast in benchmarks: ~10-20s cold start vs GHA's ~30s. 2-vCPU default; 4/8/16/32-vCPU with linear cost scaling
  • Automatic test splitting by timing — The killer feature: timing data per test balances wall time across parallel containers. A 30-min suite on 8 parallels finishes in ~4-5 min; GHA matrix sharding is manual
  • Per-second billing — Materially cheaper for short jobs like lint and typecheck
  • Mature parallelism — parallelism: 8 + circleci tests split is a one-line idiom; GHA needs matrix + manual shard logic
  • Orbs — Well-curated, high quality, smaller in count than the GHA marketplace

Where CircleCI loses

  • Smaller marketplace — ~600 orbs vs GHA's ~25,000 actions; thinner coverage for niche integrations
  • No native git integration — Webhook-driven from GitHub/GitLab/Bitbucket; PR comments and status checks work but are one step removed
  • Cost at scale — Generous free tier; mid-tier ($30/user) and enterprise ($59/user+) get expensive, comparable to GitLab Premium for a less integrated stack
  • Smaller community — Fewer Stack Overflow answers and blog posts; for non-standard problems you're more on your own

When to pick it

  • Build-time-sensitive JS / Ruby / Python shops with 10+ minute suites, where auto-split separates productive PR review from frustrating waits — On GitHub with GHA available: the separate-CI integration tax is real, GHA's marketplace is broader, cost is lower for most workloads
  • Existing CircleCI that works: migrating to GHA is a multi-quarter project — Cost-conscious teams: premium pricing rarely beats GHA Pro per engineer
  • Multi-SCM orgs (GitHub + GitLab + Bitbucket): CircleCI is SCM-agnostic

Three load-bearing concepts

  • Orbs — Versioned reusable config: circleci/node@5.2 imports the Node orb at semver 5.2. Private orbs for org-internal reuse. GHA composite actions + reusable workflows in one model
  • Test splitting by timing — parallelism: N + circleci tests split --split-by=timing balances wall time across N containers, improving as timing data accumulates
  • Contexts — Environment-scoped secret stores: context: aws-prod gives a job the AWS_* keys in that context. Project- or org-scoped, role-protected. GHA Environments + secrets

Key concepts

.circleci/config.yml structure
Lives at .circleci/config.yml. Single root, version 2.1+ (current standard): Note executors: section defines reusable executor blocks (avoid copy-paste). commands: define reusable step sequences. orbs: import third-party reusable config.
Orbs — versioned reusable config
Orbs are CircleCI's reuse primitive — packages exporting commands, jobs, and/or executors. Imported via orbs: in config.yml. Versioned by semver. Using a public orb: Authoring a private orb (org-internal): Orb source lives in a separate repo with structure: Each commands/setup-stack.yml: Publish via: Consumed by other repos: Equivalent of GHA composite actions + reusable workflows in one model. The 25k vs 600 marketplace size difference is real but the quality of well-maintained orbs (circleci/* and major-vendor orbs) is high.
Test splitting by timing
CircleCI's killer feature for parallelizing slow test suites. How it works: 1. parallelism: 8 spawns 8 containers running this job. 2. circleci tests glob enumerates all test files matching the pattern. 3. circleci tests split --split-by=timing reads timing data from previous runs (uploaded via store_test_results) and outputs this container's slice. The split balances total runtime per container, not file count. 4. First run (no timing data): falls back to filename-based split. 5. Subsequent runs: uses timing data; gradually balances wall time perfectly. Equivalent in GHA: matrix: { shard: [1,2,3,4,5,6,7,8] } with custom shard logic per test runner. Functional but more code; no automatic timing balance. split-by options: timing (default; balances by historical timing), filesize (balances by file size), name (alphabetical). Timing is the right answer for any non-trivial suite. Notes: - store_test_results must run on every job for timing data to accumulate. Don't skip it. - A flaky test that randomly takes 30s vs 5s pollutes timing data. Quarantine flake. - For very large parallelism (>16), per-container overhead can dominate. Sweet spot: 4-12 parallel.
Workflows — DAG, filters, approval gates
Orchestration layer. Workflows define which jobs run, in what order, with what filters. Filters control which branches/tags trigger which jobs. approval type pauses until a designated user clicks; equivalent of GHA Environments + required reviewers. Scheduled workflows: Note: scheduled workflows have been deprecated in v2.1; new pattern is scheduled pipelines via the API. Old syntax still works in 2026. Multiple workflows in one config.yml: useful for separating PR-validation from nightly-batch from on-demand deploys. Each can have its own jobs/filters.
Contexts and OIDC
Contexts are CircleCI's environment-scoped secret store. Create at org or project level: Use in a job: Reference contexts in workflow: Contexts have role-based access control: which projects can use them, which users can edit. OIDC to AWS works similarly to GHA. CircleCI mints a JWT per job; AWS IAM trust policy validates: The aws-cli orb's setup-and-assume-role command handles the JWT exchange: By 2026 OIDC is the default; long-lived AWS keys in contexts are deprecated practice.
Recipe: monorepo with path-based filters
CircleCI's path-filtering orb runs jobs only when specific paths changed: The filter job: 1. Diffs against base-revision. 2. Matches changed paths against the mapping. 3. Sets pipeline parameters (run-payments, run-search) to true if any matching path changed. 4. Triggers a continue-pipeline using continue-config.yml with those parameters set. continue-config.yml: Behavior: PR touches services/payments/* → only test-payments runs. PR touches packages/shared/* → both test-payments and test-search run (because shared is mapped to both). Equivalent of GitLab CI dynamic child pipelines or GHA paths-filter + jobs-conditional. Slightly more verbose than GHA's dorny/paths-filter; slightly less powerful than GitLab's dynamic generation.
Recipe: Docker layer cache + remote Docker
Building Docker images in CircleCI requires care. Two approaches: Setup remote Docker (paid, faster): setup_remote_docker provisions a separate VM for Docker. docker_layer_caching: true caches layers across builds — comparable speed to GHA + buildx + type=gha. Use machine executor (free, slower cold-start): machine executor cold-starts in ~30s vs docker executor's ~10s, but supports Docker natively without needing setup_remote_docker. Modern alternative: kaniko (rootless, no Docker daemon needed): kaniko caches layers in a separate registry repo (not local disk). Works with any executor. Slower than DLC but cheaper.
Recipe: dynamic resource class for variable workloads
Different jobs need different compute. CircleCI's resource classes scale linearly: - small: 1 vCPU, 2GB - medium: 2 vCPU, 4GB (default) - large: 4 vCPU, 8GB - xlarge: 8 vCPU, 16GB - 2xlarge: 16 vCPU, 32GB Pick per job: Pricing scales linearly: large = 4x small. The 60% time savings on a CPU-bound build often justifies 4x cost for that single job. Equivalent in GHA: larger runners (4-vCPU, 8-vCPU, 16-vCPU) priced 2x/4x/8x respectively. Comparable.

When to use it

  • JS/Node/Ruby/Python repos with slow test suites where auto-test-splitting matters
  • Existing CircleCI investment; migration cost not justified
  • Multi-SCM environments where SCM-agnostic CI is required
  • Build-time-sensitive teams that can't tolerate GHA's 30s cold start

Interview questions

  • When do you pick CircleCI over GitHub Actions in 2026?
  • Walk through a high-quality CircleCI config for a Node monorepo.
  • Test splitting by timing — how does it work and when does it fail?
  • Migration from CircleCI to GitHub Actions — what changes?
  • Quick-fire interview answers — CircleCI essentials.

Sign up free to read the full topic

More DevOps topics

Start free on Cariara · Coding problems · System design studio