Strong cores. Nobody else on the box. A PHP test process runs on one thread, so clock speed beats core count. Raft runs on dedicated Zen 5 metal. Each job gets its own microVM, restored from a clean snapshot in about 250 ms. No noisy neighbours, no surprise throttling.
Laravel CI. 90% shorter.
A hosted runner rebuilt from the metal up for PHP test suites. Strong cores, databases tuned for tests, and coverage collectors we wrote ourselves. Billed per run, because we'd rather be fast than paid by the minute.
Same tests. Same commit. Raft finishes first.
Production Laravel suites, same commit on both sides. The top rows are whole jobs on our metal hosts, from checkout to coverage upload. The bottom rows are test runtime only. Both bars move at the same speed; the hatched part is time you get back.
Unedited output from both runners
── Suite A ───────────────────────────────────────────── ubuntu-latest Time: 18:42.959, Memory: 2.71 GB otterwise-raft Time: 01:47.215, Memory: 184.50 MB ── Suite B ───────────────────────────────────────────── ubuntu-latest Tests: 1 skipped, 2282 passed (8756 assertions) Duration: 400.66s PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 107758448 bytes) otterwise-raft Tests: 1 skipped, 2282 passed (8756 assertions) Duration: 279.61s ── Suite C ───────────────────────────────────────────── ubuntu-latest Tests: 1 deprecated, 1 incomplete, 7 skipped, 3392 passed (32076 assertions) Duration: 287.25s otterwise-raft Tests: 1 deprecated, 1 incomplete, 7 skipped, 3392 passed (32083 assertions) Duration: 87.50s ── Suite D ───────────────────────────────────────────── ubuntu-latest 159s otterwise-raft 59s
We didn't rent a bigger VM. We rebuilt the runner.
Five layers, each one tuned for how PHP test suites actually spend their time: single-threaded, database-heavy, booting the framework thousands of times, and collecting coverage on top.
Databases that forget on purpose. A test database doesn't need to survive a power cut. Engines tuned for migrations, factories and RefreshDatabase, warm before your first step.
Faster than PCOV, and sees more. Native PCOV can double a suite's runtime and only tracks lines. Our in-house collector costs usually less than 5%, and adds branch coverage on top, so you see every if your tests only ever took one way.
Pest type coverage in three seconds. Our own collector takes a medium repo from about a minute to about three seconds. Cheap enough to run on every push.
Boot the framework less. Suites that bootstrap Laravel or Symfony test after test pay for it thousands of times. Our PHPUnit booster removes the repeated work. Your tests don't change.
Coverage on every push. Not just nightly.
Most teams move --coverage to a nightly job because it's slow. On Raft it costs a few percent, adds branch coverage PCOV can't collect, and lands in OtterWise next to your type coverage on every pull request.
Baseline: the suite without coverage.
Your agent writes the fix in a minute. Then waits 18 for CI.
Coding agents work in laps: edit, push, wait for the checks, read what failed, push again. On a slow runner the waiting is most of every lap, and it's the one part a better model can't fix.
Suite A, our slowest suite, test runtime only. Assumes a minute of agent work before each push, and four pushes to get a pull request green.
21 tries an hour, not 3. An agent rarely lands it on the first push. At 1:47 a run, it gets seven times as many attempts before you check back.
Four agents, four clean machines. Every job boots its own microVM from a clean snapshot in about 250 ms. Nothing one agent leaves behind can fail another agent's run.
Proof it tested what it wrote. OtterWise comments coverage on the pull request and flags uncovered lines in the diff. Your agent reads them like any other review.
Per-minute billing pays runners to be slow.
Raft charges a flat price per run. 1:47 costs exactly what 18:42 would. The only way that works for us is making your suite faster, so that's the whole job.
Up to 30 minutes per job. Need longer? Tell us, though after the move you probably won't.
GitHub list prices for private repositories, per minute with each job rounded up. Before any minutes included in your GitHub plan. marks the first minute where Raft is cheaper.
One line. Nothing else moves.
Your workflow, secrets, caches and matrix stay exactly where they are. Change the runner label and push.
- Pest and PHPUnit, Laravel and Symfony
- Database engines tuned for Laravel's test patterns
- Line, branch and type coverage land in OtterWise, no extra step
- Each job runs in its own microVM. Your source never leaves the runner
Send us your slowest suite.
Early access for Laravel and Symfony teams. We run your workflow on Raft and send back the numbers.
raft /ræft/ noun — a group of otters floating together, holding paws so nobody drifts off.