froog

FROOG PUSHBOX — GITHUB ACTIONS RUNNERS ON FULL VMS

Change one line in your workflow and every job runs in a fresh Linux virtual machine of its own, on hardware we operate. Billed per second of job time, at about a fifth of GitHub's price.

A fresh VM per jobBilled per secondSSH into failed jobsDocker and /dev/kvm

$0.0024a minute on 4 vCPU, billed per second. GitHub charges $0.012, five times as much.

.github/workflows/ci.yml
jobs:
  test:
    runs-on: ubuntu-latest
    runs-on: froog
    steps:
      - uses: actions/checkout@v4
      - run: make test

01 / Pricing

The same job for a fraction of the price

$0.0006 per vCPU per minute of job time, billed per second from your plan's usage. Booting the VM and setting up the runner are free. The $10 plan covers about 4,100 minutes on the 4 vCPU size, or 8,300 on 2 vCPU.

10,000 minutes a month on 4 vCPU

froog$24.00
GitHub-hosted1$120.00 -5×
LabelMachinefroog per minuteGitHub-hosted1
froog-small2 vCPU · 4 GB · 51 GB disk$0.0012$0.006 (2-core, 8 GB)
froog4 vCPU · 8 GB · 51 GB disk$0.0024$0.012 (4-core, 16 GB)
froog-large8 vCPU · 16 GB · 111 GB disk$0.0048$0.022 (8-core, 32 GB)
  1. GitHub's list prices for Linux x64 runners on private repositories after its January 2026 change, which include its $0.002 platform charge. GitHub's machines have more memory than froog's at each core count, and GitHub rounds every job up to a whole minute. Blacksmith, another runner service, lists $0.004 a minute for 2 vCPU and $0.008 for 4 vCPU.

02 / Setup

Three steps, no runners to look after

Each job gets its own ephemeral VM that takes that one job and is deleted when it ends. It is a whole machine with root, so Docker, services and nested virtualization work as they do on your laptop. froog ci lists your jobs and prints their logs.

  1. 1Sign in and choose a planPlans start at $10 a month with 7 days free. Open the dashboard
  2. 2Connect GitHubInstall the froog GitHub App on the repositories you pick, from the dashboard or with froog github connect
  3. 3Change runs-onUse froog, froog-small or froog-large, or let froog ci migrate rewrite your workflows. Jobs that keep ubuntu-latest stay on GitHub

03 / Options

Warm caches and failed jobs you can step into

Add options after the label with /, for example runs-on: froog-large/cache=deps/debug.

  • /cache=NAMEA disk that stays warm between jobs. The job starts from the cache named NAME, and when a job on the default branch succeeds its disk is saved back. Toolchains, ~/.cargo and Docker layers are already there next time. Pull request jobs read the cache but never write it, and pull requests from forks don't read it.
  • /from=NAMEStart every job from one of your saved snapshots, with your toolchain installed once instead of on every run.
  • /debugKeep a failed job's VM for 30 minutes and froog ssh into it, with every file and process exactly as the job left them.

actions/checkout deletes untracked files by default. To keep target/ or node_modules inside your checkout warm as well, give it clean: false:

.github/workflows/ci.yml
    runs-on: froog/cache=deps
    steps:
      - uses: actions/checkout@v4
        with:
          clean: false

Before a cache is saved, froog removes what the next jobs mustn't read: logins left by Docker, git, npm, cloud CLIs and SSH, the runner's step scripts and logs (where GitHub writes secrets), the token in your checkout and /tmp. Anything else your job writes stays, so keep secrets in environment variables or add a ~/.froog/cache-scrub script that removes them. A cache is saved as the snapshot cache-NAME (names up to 34 characters) and counts as a saved snapshot, and every plan includes some. A label with an unknown size or option never runs: froog refuses the job and says why.

04 / Insights

Know why a job is slow, failing or too big

Every job keeps what it used, its steps and its tests, so a slow or flaky job shows you why.

  • Caches beside the VMsactions/cache and the setup-* actions save to froog's own cache, scoped by branch like GitHub's, with no change to your workflow
  • Tools already there.NET, Go, Rust, Java, Node, Python, Docker and the CLIs ubuntu-latest has; setup-python, setup-node and setup-go find their versions installed
  • CPU and memoryEvery job keeps its average and peak CPU, its peak memory and any out-of-memory kills, with each step and how long it took
  • Test resultsfroog reads the JUnit XML your tests write and shows each failed test with its message, next to the job
  • Flaky testsA test that failed and passed on the same commit is flagged, with how often it happens
  • The right sizeAfter a few runs, each job gets advice when another size fits better: more memory after an out-of-memory kill, more vCPUs when it's CPU-bound, half the size when it mostly idles
  • Log searchEvery finished job's log, kept 30 days and searchable across all your jobs at once, by branch, job, step or errors only
  • AnalyticsPer repository and job: runs, failure rate, p50 and p90 time, queue wait, minutes and cost, in the dashboard, froog ci stats and the API
  • MonitorsAn email when a job on main fails, fails twice in a row, runs past 20 minutes, or dies with OutOfMemory in its log
  • Webhooksci.job.completed and ci.job.failed events with what the job used and its test totals, for Slack or your own alerts

05 / Security

Safe defaults for every repository

  • IsolationEvery job is its own KVM virtual machine, never a container shared with other jobs
  • Public repositoriesOff until you turn them on, and jobs from people you haven't listed are refused
  • SecretsJobs start without your froog environment. The runner registration token never leaves our servers
  • Clean upThe VM is deleted when GitHub says the job is done

06 / FAQ

Questions

What happens when I run more jobs than my plan allows at once?

Jobs wait in line. froog retries each waiting job every 15 seconds and starts it as soon as one of your running sandboxes or jobs ends. The $10 plan runs 2 at once, $20 runs 5, $50 runs 10 and $100 runs 25.

How long can a job run?

Up to 6 hours, GitHub's own limit for a job. Any CI machine still there 6 hours and 15 minutes after its job was queued is deleted.

Windows, macOS or Arm?

Not yet. Jobs run on x86-64 Linux. Keep windows-latest and macos-latest jobs on GitHub and move the Linux ones.

Private or public repositories?

Private repositories work as soon as you connect them. Jobs from public repositories are off until you turn them on with froog ci public on, and even then jobs started by people you haven't listed are refused, so a pull request from a stranger can't run on your account.

Is billing really per second?

Yes, and only for the job itself: from the moment GitHub starts the job on its VM until the job completes. Booting the VM, setting up the runner and saving a cache aren't billed. GitHub rounds every job up to a whole minute.

Which secrets does a job get?

Only what your workflow passes it from GitHub. Jobs start without your froog environment, variables or files, and the token that registers runners stays on our servers.

GET STARTED

One line to switch

Connect GitHub from the dashboard, then change runs-on to froog, or let froog ci migrate rewrite your workflows.

curl -fsSL https://froogcorp.com/install | sh