quickstart →

Fastest GitHub Actions runners: disk I/O.

fio inside the job workspace of 93 runners from 9 providers, 2 to 12 vCPU. These are the disk's limits. A build goes through the Linux page cache and often never reaches them.

Fastest QD1 read, x64 at 4 vCPU 105,050 Namespace 4x16 (4 vCPU) · reads/s
Fastest QD1 read, arm64 at 4 vCPU 24,052 Blacksmith 4 vCPU · reads/s
GitHub at 4 vCPU 7,240 x64 QD1 reads/s on GitHub 4-core
Fastest synced writes, x64 at 4 vCPU 29,746 Namespace 4x8 · writes/s
tmpfs, for scale 1.2M QD1 reads/s on RunsOn r8a.2xlarge · tmpfs: the workspace in RAM

Latency per provider

Each provider's best disk, RunsOn once per storage (the Storage pill). QD1 is one 4k read at a time: what a database or a cold read pays. Most build steps batch their I/O through the page cache. tmpfs is RAM, not a disk: add it to see the gap on the same scale.

QD1 random readx64 · 4k, one request in flight · IOPS, higher is better
  1. Namespace8 vCPU8x16 · VM disk108,543, p99 10 µs, ×1.00
  2. Blacksmith2 vCPUVM disk77,996, p99 15 µs, ×0.72
  3. Avrea8 vCPUVM disk52,121, p99 21 µs, ×0.48
  4. StarSling8 vCPUVM disk51,989, p99 22 µs, ×0.48
  5. Warpbuild8 vCPUVM disk36,868, p99 33 µs, ×0.34
  6. RunsOn2 vCPUi7i.large · local NVMe12,510, p99 285 µs, ×0.12
  7. Ubicloud8 vCPUstandard · VM disk9,638, p99 317 µs, ×0.09
  8. GitHub8 vCPUVM disk7,559, p99 239 µs, ×0.07
  9. RunsOn4 vCPUm8a.xlarge · EBS gp31,817, p99 741 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,773, p99 684 µs, ×0.02

Fastest x64 QD1 read: Namespace (108,543), ahead of Blacksmith (77,996).tmpfs for scale: 1,153,982 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 · 4k + fdatasync · IOPS, higher is better
  1. Namespace2 vCPU2x8 · VM disk32,331, p99 14 µs, ×1.00
  2. StarSling4 vCPUVM disk24,197, p99 42 µs, ×0.75
  3. Blacksmith2 vCPUVM disk · nobarrier19,119, p99 26 µs, ×0.59
  4. RunsOn2 vCPUi7i.large · local NVMe12,861, p99 33 µs, ×0.40
  5. Avrea2 vCPUVM disk · nobarrier12,808, p99 27 µs, ×0.40
  6. GitHub4 vCPUnetwork disk · nobarrier4,122, p99 317 µs, ×0.13
  7. Ubicloud8 vCPUpremium · VM disk · nobarrier2,822, p99 1,991 µs, ×0.09
  8. Warpbuild8 vCPUVM disk2,743, p99 105 µs, ×0.08
  9. AWS CodeBuild2 vCPUsmall · EBS571, p99 1,004 µs, ×0.02
  10. RunsOn2 vCPUm8azn.large · EBS gp3 · nobarrier542, p99 963 µs, ×0.02

Fastest x64 synced writes: Namespace (32,331), ahead of StarSling (24,197).volatile and nobarrier mounts make each flush cheaper by making it less durable.

QD1 random readx64 at 2 vCPU · 4k, one request in flight · IOPS, higher is better
  1. Namespace2 vCPU2x8 · VM disk104,659, p99 10 µs, ×1.00
  2. Blacksmith2 vCPUVM disk77,996, p99 15 µs, ×0.75
  3. Avrea2 vCPUVM disk51,909, p99 16 µs, ×0.50
  4. Warpbuild2 vCPUVM disk18,761, p99 61 µs, ×0.18
  5. RunsOn2 vCPUi7i.large · local NVMe12,510, p99 285 µs, ×0.12
  6. GitHub2 vCPUVM disk6,868, p99 272 µs, ×0.07
  7. Ubicloud2 vCPUstandard · VM disk6,767, p99 1,942 µs, ×0.06
  8. RunsOn2 vCPUc8a.large · EBS gp31,809, p99 766 µs, ×0.02
  9. AWS CodeBuild2 vCPUsmall · EBS1,761, p99 791 µs, ×0.02

Fastest x64 2 vCPU QD1 read: Namespace (104,659), ahead of Blacksmith (77,996).tmpfs for scale: 1,153,982 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 at 2 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace2 vCPU2x8 · VM disk32,331, p99 14 µs, ×1.00
  2. Blacksmith2 vCPUVM disk · nobarrier19,119, p99 26 µs, ×0.59
  3. RunsOn2 vCPUi7i.large · local NVMe12,861, p99 33 µs, ×0.40
  4. Avrea2 vCPUVM disk · nobarrier12,808, p99 27 µs, ×0.40
  5. GitHub2 vCPUVM disk · nobarrier3,862, p99 212 µs, ×0.12
  6. Warpbuild2 vCPUVM disk2,127, p99 68 µs, ×0.07
  7. Ubicloud2 vCPUpremium · VM disk · nobarrier1,491, p99 2,572 µs, ×0.05
  8. AWS CodeBuild2 vCPUsmall · EBS571, p99 1,004 µs, ×0.02
  9. RunsOn2 vCPUm8azn.large · EBS gp3 · nobarrier542, p99 963 µs, ×0.02

Fastest x64 2 vCPU synced writes: Namespace (32,331), ahead of Blacksmith (19,119).volatile and nobarrier mounts make each flush cheaper by making it less durable.

QD1 random readx64 at 4 vCPU · 4k, one request in flight · IOPS, higher is better
  1. Namespace4 vCPU4x16 · VM disk105,050, p99 11 µs, ×1.00
  2. Blacksmith4 vCPUVM disk70,716, p99 16 µs, ×0.67
  3. Avrea4 vCPUVM disk49,914, p99 21 µs, ×0.48
  4. StarSling4 vCPUVM disk30,430, p99 31 µs, ×0.29
  5. Warpbuild4 vCPUVM disk30,147, p99 43 µs, ×0.29
  6. RunsOn4 vCPUi7i.xlarge · local NVMe11,000, p99 261 µs, ×0.10
  7. Ubicloud4 vCPUstandard · VM disk8,984, p99 528 µs, ×0.09
  8. GitHub4 vCPUnetwork disk7,240, p99 261 µs, ×0.07
  9. RunsOn4 vCPUm8a.xlarge · EBS gp31,817, p99 741 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,773, p99 684 µs, ×0.02

Fastest x64 4 vCPU QD1 read: Namespace (105,050), ahead of Blacksmith (70,716).tmpfs for scale: 1,153,982 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace4 vCPU4x8 · VM disk29,746, p99 14 µs, ×1.00
  2. StarSling4 vCPUVM disk24,197, p99 42 µs, ×0.81
  3. Blacksmith4 vCPUVM disk · nobarrier17,586, p99 24 µs, ×0.59
  4. RunsOn4 vCPUi7i.xlarge · local NVMe12,590, p99 33 µs, ×0.42
  5. Avrea4 vCPUVM disk · nobarrier12,385, p99 29 µs, ×0.42
  6. GitHub4 vCPUnetwork disk · nobarrier4,122, p99 317 µs, ×0.14
  7. Warpbuild4 vCPUVM disk2,395, p99 100 µs, ×0.08
  8. Ubicloud4 vCPUstandard · VM disk · nobarrier1,826, p99 2,769 µs, ×0.06
  9. AWS CodeBuild4 vCPUmedium · EBS566, p99 938 µs, ×0.02
  10. RunsOn4 vCPUm8azn.xlarge · EBS gp3 · nobarrier541, p99 1,012 µs, ×0.02

Fastest x64 4 vCPU synced writes: Namespace (29,746), ahead of StarSling (24,197).volatile and nobarrier mounts make each flush cheaper by making it less durable.

QD1 random readx64 at 8 vCPU · 4k, one request in flight · IOPS, higher is better
  1. Namespace8 vCPU8x16 · VM disk108,543, p99 10 µs, ×1.00
  2. Blacksmith8 vCPUVM disk55,275, p99 19 µs, ×0.51
  3. Avrea8 vCPUVM disk52,121, p99 21 µs, ×0.48
  4. StarSling8 vCPUVM disk51,989, p99 22 µs, ×0.48
  5. Warpbuild8 vCPUVM disk36,868, p99 33 µs, ×0.34
  6. RunsOn8 vCPUi7i.2xlarge · local NVMe12,054, p99 301 µs, ×0.11
  7. Ubicloud8 vCPUstandard · VM disk9,638, p99 317 µs, ×0.09
  8. GitHub8 vCPUVM disk7,559, p99 239 µs, ×0.07
  9. RunsOn8 vCPUc8a.2xlarge · EBS gp31,807, p99 815 µs, ×0.02
  10. AWS CodeBuild8 vCPUlarge · EBS1,757, p99 692 µs, ×0.02

Fastest x64 8 vCPU QD1 read: Namespace (108,543), ahead of Blacksmith (55,275).tmpfs for scale: 1,153,982 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace8 vCPU8x16 · VM disk30,266, p99 14 µs, ×1.00
  2. StarSling8 vCPUVM disk17,805, p99 36 µs, ×0.59
  3. Blacksmith8 vCPUVM disk · nobarrier13,820, p99 27 µs, ×0.46
  4. RunsOn8 vCPUi7i.2xlarge · local NVMe11,609, p99 38 µs, ×0.38
  5. Avrea8 vCPUVM disk · nobarrier11,323, p99 44 µs, ×0.37
  6. GitHub8 vCPUVM disk · nobarrier3,710, p99 261 µs, ×0.12
  7. Ubicloud8 vCPUpremium · VM disk · nobarrier2,822, p99 1,991 µs, ×0.09
  8. Warpbuild8 vCPUVM disk2,743, p99 105 µs, ×0.09
  9. AWS CodeBuild8 vCPUlarge · EBS565, p99 971 µs, ×0.02
  10. RunsOn8 vCPUc8a.2xlarge · EBS gp3 · nobarrier540, p99 1,004 µs, ×0.02

Fastest x64 8 vCPU synced writes: Namespace (30,266), ahead of StarSling (17,805).volatile and nobarrier mounts make each flush cheaper by making it less durable.

QD1 random readarm64 · 4k, one request in flight · IOPS, higher is better
  1. Warpbuild6 vCPUxfast (Apple M4 Pro) · VM disk30,673, p99 40 µs, ×1.00
  2. Blacksmith8 vCPUVM disk24,892, p99 37 µs, ×0.81
  3. Avrea8 vCPUVM disk21,268, p99 56 µs, ×0.69
  4. Namespace2 vCPUApple silicon 2x8 · VM disk19,829, p99 78 µs, ×0.65
  5. RunsOn2 vCPUm9gd.large · local NVMe13,533, p99 81 µs, ×0.44
  6. Ubicloud8 vCPUstandard · VM disk9,282, p99 408 µs, ×0.30
  7. GitHub2 vCPUVM disk7,692, p99 216 µs, ×0.25
  8. Warpbuild4 vCPUEBS1,828, p99 848 µs, ×0.06
  9. RunsOn4 vCPUm9g.xlarge · EBS gp31,822, p99 856 µs, ×0.06

Fastest arm64 QD1 read: Warpbuild (30,673), ahead of Blacksmith (24,892).tmpfs for scale: 673,423 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 · 4k + fdatasync · IOPS, higher is better
  1. RunsOn8 vCPUm9gd.2xlarge · local NVMe17,416, p99 20 µs, ×1.00
  2. Warpbuild6 vCPUxfast (Apple M4 Pro) · VM disk · nobarrier9,790, p99 57 µs, ×0.56
  3. Blacksmith8 vCPUVM disk · nobarrier7,745, p99 60 µs, ×0.44
  4. Ubicloud8 vCPUstandard · VM disk · nobarrier4,597, p99 946 µs, ×0.26
  5. Namespace8 vCPU8x16 · VM disk4,157, p99 167 µs, ×0.24
  6. Avrea2 vCPUVM disk3,909, p99 120 µs, ×0.22
  7. GitHub2 vCPUVM disk · nobarrier3,110, p99 610 µs, ×0.18
  8. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 971 µs, ×0.03
  9. Warpbuild8 vCPUEBS · nobarrier539, p99 979 µs, ×0.03

Fastest arm64 synced writes: RunsOn m9gd.2xlarge · NVMe (17,416), ahead of Warpbuild (9,790).volatile and nobarrier mounts make each flush cheaper by making it less durable.

QD1 random readarm64 at 2 vCPU · 4k, one request in flight · IOPS, higher is better
  1. Blacksmith2 vCPUVM disk23,950, p99 40 µs, ×1.00
  2. Avrea2 vCPUVM disk21,118, p99 60 µs, ×0.88
  3. Namespace2 vCPUApple silicon 2x8 · VM disk19,829, p99 78 µs, ×0.83
  4. RunsOn2 vCPUm9gd.large · local NVMe13,533, p99 81 µs, ×0.57
  5. GitHub2 vCPUVM disk7,692, p99 216 µs, ×0.32
  6. Ubicloud2 vCPUstandard · VM disk7,228, p99 514 µs, ×0.30
  7. RunsOn2 vCPUm9g.large · EBS gp31,789, p99 791 µs, ×0.07
  8. Warpbuild2 vCPUEBS1,777, p99 905 µs, ×0.07

Fastest arm64 2 vCPU QD1 read: Blacksmith (23,950), ahead of Avrea (21,118).tmpfs for scale: 673,423 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 2 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn2 vCPUm9gd.large · local NVMe7,267, p99 49 µs, ×1.00
  2. Blacksmith2 vCPUVM disk · nobarrier7,080, p99 71 µs, ×0.97
  3. Ubicloud2 vCPUstandard · VM disk · nobarrier4,024, p99 1,155 µs, ×0.55
  4. Avrea2 vCPUVM disk3,909, p99 120 µs, ×0.54
  5. Namespace2 vCPU2x8 · VM disk3,695, p99 196 µs, ×0.51
  6. GitHub2 vCPUVM disk · nobarrier3,110, p99 610 µs, ×0.43
  7. RunsOn2 vCPUm9g.large · EBS gp3 · nobarrier542, p99 971 µs, ×0.07
  8. Warpbuild2 vCPUEBS · nobarrier538, p99 987 µs, ×0.07

RunsOn m9gd.large · NVMe and Blacksmith lead arm64 2 vCPU synced writes, within 5% (7,267 and 7,080).volatile and nobarrier mounts make each flush cheaper by making it less durable.

QD1 random readarm64 at 4 vCPU · 4k, one request in flight · IOPS, higher is better
  1. Blacksmith4 vCPUVM disk24,052, p99 41 µs, ×1.00
  2. Avrea4 vCPUVM disk19,330, p99 58 µs, ×0.80
  3. Namespace4 vCPUApple silicon 4x16 · VM disk18,972, p99 90 µs, ×0.79
  4. RunsOn4 vCPUm9gd.xlarge · local NVMe13,382, p99 106 µs, ×0.56
  5. Ubicloud4 vCPUstandard · VM disk8,334, p99 498 µs, ×0.35
  6. GitHub4 vCPUnetwork disk5,324, p99 247 µs, ×0.22
  7. Warpbuild4 vCPUEBS1,828, p99 848 µs, ×0.08
  8. RunsOn4 vCPUm9g.xlarge · EBS gp31,822, p99 856 µs, ×0.08

Fastest arm64 4 vCPU QD1 read: Blacksmith (24,052), ahead of Avrea (19,330).tmpfs for scale: 673,423 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn4 vCPUm9gd.xlarge · local NVMe14,858, p99 24 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier7,023, p99 78 µs, ×0.47
  3. Avrea4 vCPUVM disk3,889, p99 55 µs, ×0.26
  4. Namespace4 vCPU4x16 · VM disk3,821, p99 183 µs, ×0.26
  5. Ubicloud4 vCPUstandard · VM disk · nobarrier3,471, p99 1,073 µs, ×0.23
  6. GitHub4 vCPUnetwork disk · nobarrier2,755, p99 301 µs, ×0.19
  7. RunsOn4 vCPUm9g.xlarge · EBS gp3 · nobarrier543, p99 1,045 µs, ×0.04
  8. Warpbuild4 vCPUEBS · nobarrier539, p99 987 µs, ×0.04

Fastest arm64 4 vCPU synced writes: RunsOn m9gd.xlarge · NVMe (14,858), ahead of Blacksmith (7,023).volatile and nobarrier mounts make each flush cheaper by making it less durable.

QD1 random readarm64 at 8 vCPU · 4k, one request in flight · IOPS, higher is better
  1. Blacksmith8 vCPUVM disk24,892, p99 37 µs, ×1.00
  2. Avrea8 vCPUVM disk21,268, p99 56 µs, ×0.85
  3. Namespace8 vCPU8x32 · VM disk16,930, p99 89 µs, ×0.68
  4. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,423, p99 84 µs, ×0.54
  5. Ubicloud8 vCPUstandard · VM disk9,282, p99 408 µs, ×0.37
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp31,812, p99 848 µs, ×0.07
  7. Warpbuild8 vCPUEBS1,781, p99 823 µs, ×0.07

Fastest arm64 8 vCPU QD1 read: Blacksmith (24,892), ahead of Avrea (21,268).tmpfs for scale: 673,423 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn8 vCPUm9gd.2xlarge · local NVMe17,416, p99 20 µs, ×1.00
  2. Blacksmith8 vCPUVM disk · nobarrier7,745, p99 60 µs, ×0.44
  3. Ubicloud8 vCPUstandard · VM disk · nobarrier4,597, p99 946 µs, ×0.26
  4. Namespace8 vCPU8x16 · VM disk4,157, p99 167 µs, ×0.24
  5. Avrea8 vCPUVM disk3,810, p99 56 µs, ×0.22
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 971 µs, ×0.03
  7. Warpbuild8 vCPUEBS · nobarrier539, p99 979 µs, ×0.03

Fastest arm64 8 vCPU synced writes: RunsOn m9gd.2xlarge · NVMe (17,416), ahead of Blacksmith (7,745).volatile and nobarrier mounts make each flush cheaper by making it less durable.

What the numbers say

Extremes on x64, and RAM against disk.

  • On x64, one small read at a time (4k, QD1) comes back 108,543 times a second on Namespace 8x16 and 1,511 on RunsOn m8a.2xlarge · EBS gp3, 72× apart; p99 latency is 10 µs against 930 µs.
  • Synced 4k writes on x64 run from 487 per second on RunsOn m8i.2xlarge · EBS gp3 (workspace mounted nobarrier) to 32,331 on Namespace 2x8.
  • r8a.large with tmpfs ($0.0009/min at spot) answers 1,107,000 QD1 reads and 428,125 synced writes per second: 90× and 33× the best local NVMe at 2 vCPU (i7i.large, $0.0010) and 612× and 791× default EBS gp3 (c8a.large, $0.0008); its workspace is 14 GiB, from RAM. (EC2 storage suite) What that does to real builds.
More findings23: EBS, arm64, NVMe vs EBS, provisioned gp3, tmpfs, storage classes
  • Every EBS-backed workspace (3 AWS CodeBuild x64 runners, 25 RunsOn configurations and 3 Warpbuild configurations) answers between 1,511 and 1,828 QD1 reads and 487 to 571 synced writes per second, whoever runs it and whatever throughput it is provisioned for: each request is a round trip to network storage.
  • On arm64, one small read at a time (4k, QD1) comes back 30,673 times a second on Warpbuild xfast (Apple M4 Pro) 6 vCPU and 1,647 on RunsOn c8g.2xlarge · EBS gp3, 19× apart; p99 latency is 40 µs against 856 µs.
  • Synced 4k writes on arm64 run from 537 per second on RunsOn c8g.large · EBS gp3 (workspace mounted nobarrier) to 17,416 on RunsOn m9gd.2xlarge · local NVMe.
  • Same Xeon 6975P-C CPU, different disk: m8id.2xlarge on local NVMe answers 11,083 QD1 reads and 7,472 synced writes per second, m8i.2xlarge on EBS gp3 1,580 and 487.
  • Same Xeon 6975P-C CPU, different disk: m8id.large on local NVMe answers 11,044 QD1 reads and 5,548 synced writes per second, m8i-flex.large on EBS gp3 1,767 and 528.
  • Same Xeon 6975P-C CPU, different disk: m8id.xlarge on local NVMe answers 10,931 QD1 reads and 8,007 synced writes per second, m8i-flex.xlarge on EBS gp3 1,751 and 524.
  • Same Neoverse-V3 CPU, different disk: m9gd.2xlarge on local NVMe answers 13,423 QD1 reads and 17,416 synced writes per second, m9g.2xlarge on EBS gp3 1,812 and 543.
  • Same Neoverse-V3 CPU, different disk: m9gd.xlarge on local NVMe answers 13,382 QD1 reads and 14,858 synced writes per second, m9g.xlarge on EBS gp3 1,822 and 543.
  • Same Neoverse-V3 CPU, different disk: m9gd.large on local NVMe answers 13,533 QD1 reads and 7,267 synced writes per second, m9g.large on EBS gp3 1,789 and 542.
  • Provisioning gp3 at 1000 MiB/s on m8a.2xlarge takes sequential reads from 401 MiB/s to 1,001 MiB/s (2.5×); QD1 reads go (1,587 → 1,776 IOPS).
  • Provisioning gp3 at 1000 MiB/s on m8azn.xlarge takes sequential reads from 401 MiB/s to 1,001 MiB/s (2.5×); QD1 reads barely move (1,769 → 1,769 IOPS): it buys bandwidth, not latency.
  • tmpfs on m8a.2xlarge is not a disk at all: 1,135,113 QD1 reads and 428,937 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs on m9g.2xlarge is not a disk at all: 660,139 QD1 reads and 300,362 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs on m9g.xlarge is not a disk at all: 673,423 QD1 reads and 303,569 synced writes per second, from RAM. The workspace is 14 GiB, sized by memory.
  • tmpfs on r8a.2xlarge is not a disk at all: 1,153,982 QD1 reads and 430,608 synced writes per second, from RAM. The workspace is 59 GiB, sized by memory.
  • tmpfs on r8a.xlarge is not a disk at all: 1,136,849 QD1 reads and 433,605 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs on r9g.large is not a disk at all: 633,186 QD1 reads and 296,835 synced writes per second, from RAM. The workspace is 14 GiB, sized by memory.
  • tmpfs on r9g.xlarge is not a disk at all: 655,713 QD1 reads and 302,278 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs: 633k–1.2M QD1 reads and 297k–434k synced writes per second across 8 runners (8 RunsOn configurations).
  • VM disk: 4.4k–109k QD1 reads and 691–32k synced writes per second across 43 runners from 7 providers (6 Avrea runners, 6 Blacksmith runners, 3 GitHub runners, 12 Namespace runners, 2 StarSling x64 runners, 9 Ubicloud runners and 5 Warpbuild runners).
  • local NVMe: 11k–14k QD1 reads and 5.5k–17k synced writes per second across 9 runners (9 RunsOn configurations).
  • network disk: 5.3k–7.2k QD1 reads and 2.8k–4.1k synced writes per second across 2 runners (2 GitHub runners).
  • EBS: 1.5k–1.8k QD1 reads and 487–571 synced writes per second across 31 runners from 3 providers (3 AWS CodeBuild x64 runners, 25 RunsOn configurations and 3 Warpbuild configurations).

Reading these numbers

fio measures what a disk can do. Whether a job gets there depends on the job.

What each column says about a job

  • QD1 reads and synced writes: databases, SQLite-backed tests and anything that flushes each write. Every flush waits for the storage, and a network disk pays a round trip each time.
  • Random writes at depth and sequential throughput: docker build layers, package installs and cache archives. They batch their writes and run into the disk's ceiling, not its latency.
  • None of them: compile jobs. A compiler waits for the CPU, and it reads its files back from the page cache.

Every runner

Each provider's best disk first; its other machines sit behind +N more. Bars are log scale.

One request at a time 4k, 32 in flight Sequential, 1M
Runner QD1 read ↑p99 ↓Sync write ↑Read ↑Write ↑Read ↑Write ↑
x6457 runners, 9 providers
Namespace 8x16 8 vCPU 16 GB VM disk EPYC · model hidden 108,543 10 µs 30,266 1,118,292 585,767 5.0 GiB/s 3.3 GiB/s
8x32 8 vCPU 32 GB VM disk EPYC · model hidden 104,251 10 µs 28,934 1,096,275 576,011 5.0 GiB/s 3.4 GiB/s
4x16 4 vCPU 16 GB VM disk EPYC · model hidden 105,050 11 µs 28,491 1,199,883 559,921 5.0 GiB/s 3.3 GiB/s
4x8 4 vCPU 8 GB VM disk EPYC · model hidden 104,646 11 µs 29,746 1,156,765 575,099 5.0 GiB/s 3.2 GiB/s
2x8 2 vCPU 8 GB VM disk EPYC · model hidden 104,659 10 µs 32,331 947,665 605,345 5.0 GiB/s 3.3 GiB/s
Blacksmith 2 vCPU 8 GB VM disk EPYC · model hidden nobarrier 77,996 15 µs 19,119 783,458 174,903 5.6 GiB/s 2.3 GiB/s
8 vCPU 8 vCPU 32 GB VM disk EPYC · model hidden nobarrier 55,275 19 µs 13,820 420,352 215,561 5.9 GiB/s 2.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC · model hidden nobarrier 70,716 16 µs 17,586 709,498 217,634 6.3 GiB/s 1.6 GiB/s
Avrea 8 vCPU 32 GB VM disk EPYC 4585PX nobarrier 52,121 21 µs 11,323 356,044 203,674 16.2 GiB/s 11.3 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC 4585PX nobarrier 49,914 21 µs 12,385 430,622 172,216 15.6 GiB/s 10.3 GiB/s
2 vCPU 2 vCPU 8 GB VM disk EPYC 4585PX nobarrier 51,909 16 µs 12,808 583,528 283,518 15.9 GiB/s 10.3 GiB/s
StarSling 8 vCPU 32 GB VM disk EPYC · model hidden 51,989 22 µs 17,805 296,735 59,965 5.2 GiB/s 4.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Xeon · model hidden 30,430 31 µs 24,197 342,062 67,571 3.9 GiB/s 3.9 GiB/s
Warpbuild 8 vCPU 32 GB VM disk Ryzen 9 9950X 36,868 33 µs 2,743 170,167 59,456 4.4 GiB/s 3.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 9950X 30,147 43 µs 2,395 187,737 71,139 4.6 GiB/s 3.4 GiB/s
2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 9950X 18,761 61 µs 2,127 128,905 60,913 4.1 GiB/s 2.8 GiB/s
RunsOn i7i.large 2 vCPU 16 GB local NVMe Xeon 8559C 12,510 285 µs 12,861 75,023 41,231 503 MiB/s 395 MiB/s
m8azn.3xlarge 12 vCPU 48 GB EBS gp3 EPYC 9R05 nobarrier 1,783 840 µs 538 2,997 2,994 401 MiB/s 401 MiB/s
c8a.2xlarge 8 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,807 815 µs 540 2,995 2,991 401 MiB/s 401 MiB/s
m8a.2xlarge 8 vCPU 32 GB EBS gp3 EPYC 9R45 nobarrier 1,511 930 µs 540 2,995 2,992 401 MiB/s 401 MiB/s
m8a.2xlarge 8 vCPU 32 GB gp3 1000 MiB/s EPYC 9R45 nobarrier 1,776 807 µs 540 15,994 15,992 1,001 MiB/s 1,001 MiB/s
r8a.2xlarge 8 vCPU 64 GB tmpfs EPYC 9R45 1,153,982 <1 µs 430,608 4,315,373 3,831,509 18.4 GiB/s 10.0 GiB/s
m8a.2xlarge 8 vCPU 32 GB tmpfs EPYC 9R45 1,135,113 <1 µs 428,937 4,232,110 3,822,441 18.5 GiB/s 9.9 GiB/s
m8azn.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R05 nobarrier 1,769 840 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
m8azn.xlarge 4 vCPU 16 GB gp3 1000 MiB/s EPYC 9R05 nobarrier 1,769 823 µs 541 15,994 15,992 1,001 MiB/s 1,001 MiB/s
m8i.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,580 1,073 µs 487 2,993 2,993 401 MiB/s 401 MiB/s
m8i-flex.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,774 954 µs 515 2,992 2,995 401 MiB/s 401 MiB/s
m8id.2xlarge 8 vCPU 32 GB local NVMe Xeon 6975P-C 11,083 247 µs 7,472 134,257 67,076 905 MiB/s 432 MiB/s
m8a.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,817 741 µs 540 2,994 2,991 401 MiB/s 401 MiB/s
c8a.xlarge 4 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,790 897 µs 540 2,994 2,991 401 MiB/s 401 MiB/s
r8a.xlarge 4 vCPU 32 GB tmpfs EPYC 9R45 1,136,849 <1 µs 433,605 4,276,584 3,830,517 17.6 GiB/s 9.8 GiB/s
i7i.2xlarge 8 vCPU 64 GB local NVMe Xeon 8559C 12,054 301 µs 11,609 300,467 165,110 2.0 GiB/s 1.5 GiB/s
m8azn.large 2 vCPU 8 GB EBS gp3 EPYC 9R05 nobarrier 1,807 750 µs 542 2,994 2,992 401 MiB/s 401 MiB/s
m8id.xlarge 4 vCPU 16 GB local NVMe Xeon 6975P-C 10,931 224 µs 8,007 67,090 33,527 451 MiB/s 216 MiB/s
m8i-flex.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,751 897 µs 524 2,993 2,993 401 MiB/s 401 MiB/s
m8i.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,675 905 µs 519 2,993 2,993 401 MiB/s 401 MiB/s
m8a.large 2 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,780 864 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
i7i.xlarge 4 vCPU 32 GB local NVMe Xeon 8559C 11,000 261 µs 12,590 150,053 82,487 1,010 MiB/s 788 MiB/s
r8a.large 2 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,778 807 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
r8a.large 2 vCPU 16 GB tmpfs EPYC 9R45 1,107,000 <1 µs 428,125 2,145,313 1,939,655 18.6 GiB/s 10.1 GiB/s
c8a.large 2 vCPU 4 GB EBS gp3 EPYC 9R45 nobarrier 1,809 766 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
m8id.large 2 vCPU 8 GB local NVMe Xeon 6975P-C 11,044 189 µs 5,548 33,541 16,753 226 MiB/s 108 MiB/s
m8i.large 2 vCPU 8 GB EBS gp3 Xeon 6975P-C nobarrier 1,648 971 µs 535 2,993 2,993 401 MiB/s 401 MiB/s
m8i-flex.large 2 vCPU 8 GB EBS gp3 Xeon 6975P-C nobarrier 1,767 897 µs 528 2,993 2,993 401 MiB/s 401 MiB/s
t8i.medium 2 vCPU 4 GB EBS gp3 Xeon 6975P-C nobarrier 1,736 864 µs 523 2,999 2,997 401 MiB/s 401 MiB/s
Ubicloud standard 8 vCPU 32 GB VM disk Ryzen 9 7950X3D nobarrier 9,638 317 µs 1,921 211,320 27,403 2.2 GiB/s 923 MiB/s
premium 8 vCPU 8 vCPU 32 GB VM disk Ryzen 9 7950X3D nobarrier 8,023 684 µs 2,822 274,211 18,713 2.9 GiB/s 1.4 GiB/s
standard 4 vCPU 4 vCPU 16 GB VM disk EPYC 9454P nobarrier 8,984 528 µs 1,826 188,948 26,731 2.5 GiB/s 546 MiB/s
premium 4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 7950X3D nobarrier 7,801 725 µs 1,414 258,030 23,853 2.2 GiB/s 909 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 7950X3D nobarrier 6,767 1,942 µs 691 125,230 18,447 2.2 GiB/s 626 MiB/s
premium 2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 7950X3D nobarrier 4,375 2,376 µs 1,491 97,077 23,536 2.6 GiB/s 1,003 MiB/s
GitHub 8 vCPU 32 GB VM disk EPYC 9V45 nobarrier 7,559 239 µs 3,710 38,975 18,962 784 MiB/s 545 MiB/s
4-core 4 vCPU 16 GB network disk EPYC 7763 nobarrier 7,240 261 µs 4,122 19,574 10,264 394 MiB/s 250 MiB/s
2-core 2 vCPU 8 GB VM disk EPYC 9V74 nobarrier 6,868 272 µs 3,862 9,375 8,843 199 MiB/s 199 MiB/s
AWS CodeBuild medium 4 vCPU 8 GB EBS Xeon 8488C 1,773 684 µs 566 2,988 2,974 252 MiB/s 251 MiB/s
large 8 vCPU 16 GB EBS Xeon 8488C 1,757 692 µs 565 2,988 2,977 248 MiB/s 251 MiB/s
small 2 vCPU 3 GB EBS Xeon 8488C 1,761 791 µs 571 2,989 2,971 250 MiB/s 251 MiB/s
arm6436 runners, 7 providers
Warpbuild xfast (Apple M4 Pro) 6 vCPU 14 GB VM disk nobarrier 30,673 40 µs 9,790 376,960 4,902 11.7 GiB/s 10.7 GiB/s
xfast (Apple M4 Pro) 12 vCPU 12 vCPU 28 GB VM disk nobarrier 30,102 32 µs 9,580 384,762 5,949 11.5 GiB/s 11.1 GiB/s
8 vCPU 8 vCPU 32 GB EBS Neoverse-V2 nobarrier 1,781 823 µs 539 4,994 4,993 401 MiB/s 401 MiB/s
4 vCPU 4 vCPU 16 GB EBS Neoverse-V2 nobarrier 1,828 848 µs 539 4,194 4,193 302 MiB/s 302 MiB/s
2 vCPU 2 vCPU 8 GB EBS Neoverse-V2 nobarrier 1,777 905 µs 538 4,194 4,194 302 MiB/s 301 MiB/s
Blacksmith 8 vCPU 32 GB VM disk Ampere-1a nobarrier 24,892 37 µs 7,745 232,575 28,043 1.8 GiB/s 781 MiB/s
4 vCPU 4 vCPU 16 GB VM disk Ampere-1a nobarrier 24,052 41 µs 7,023 153,065 25,189 1.6 GiB/s 831 MiB/s
2 vCPU 2 vCPU 6 GB VM disk Ampere-1a nobarrier 23,950 40 µs 7,080 83,941 27,059 1.7 GiB/s 857 MiB/s
Avrea 8 vCPU 32 GB VM disk Apple M5 Max · as stated by the provider 21,268 56 µs 3,810 143,275 12,897 47.5 GiB/s 16.6 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Apple M5 Max · as stated by the provider 19,330 58 µs 3,889 146,545 13,257 57.6 GiB/s 16.0 GiB/s
2 vCPU 2 vCPU 8 GB VM disk Apple M5 Max · as stated by the provider 21,118 60 µs 3,909 150,825 18,394 34.1 GiB/s 14.8 GiB/s
Namespace Apple silicon 2x8 2 vCPU 8 GB VM disk CPU not reported 19,829 78 µs 3,562 137,299 13,480 27.4 GiB/s 11.5 GiB/s
Apple silicon 4x16 4 vCPU 16 GB VM disk CPU not reported 18,972 90 µs 3,454 145,281 19,665 32.4 GiB/s 12.0 GiB/s
8x16 8 vCPU 16 GB VM disk Ampere-1a 16,609 95 µs 4,157 183,519 43,083 926 MiB/s 700 MiB/s
8x32 8 vCPU 32 GB VM disk Ampere-1a 16,930 89 µs 4,047 185,101 28,671 936 MiB/s 769 MiB/s
4x8 4 vCPU 8 GB VM disk Ampere-1a 16,654 94 µs 3,795 143,772 34,657 950 MiB/s 672 MiB/s
4x16 4 vCPU 16 GB VM disk Ampere-1a 16,425 96 µs 3,821 144,416 37,408 928 MiB/s 732 MiB/s
2x8 2 vCPU 8 GB VM disk Ampere-1a 15,879 103 µs 3,695 72,899 25,776 924 MiB/s 676 MiB/s
RunsOn m9gd.large 2 vCPU 8 GB local NVMe Neoverse-V3 13,533 81 µs 7,267 43,609 21,782 293 MiB/s 141 MiB/s
m9gd.2xlarge 8 vCPU 32 GB local NVMe Neoverse-V3 13,423 84 µs 17,416 174,573 87,208 1.1 GiB/s 561 MiB/s
m9g.2xlarge 8 vCPU 32 GB EBS gp3 Neoverse-V3 nobarrier 1,812 848 µs 543 2,995 2,991 401 MiB/s 401 MiB/s
m9g.2xlarge 8 vCPU 32 GB tmpfs Neoverse-V3 660,139 <1 µs 300,362 2,636,493 2,502,932 13.5 GiB/s 9.1 GiB/s
c8g.2xlarge 8 vCPU 16 GB EBS gp3 Neoverse-V2 nobarrier 1,647 856 µs 539 2,994 2,993 401 MiB/s 401 MiB/s
m9gd.xlarge 4 vCPU 16 GB local NVMe Neoverse-V3 13,382 106 µs 14,858 87,221 43,588 585 MiB/s 281 MiB/s
m9g.xlarge 4 vCPU 16 GB EBS gp3 Neoverse-V3 nobarrier 1,822 856 µs 543 2,994 2,992 401 MiB/s 401 MiB/s
m9g.xlarge 4 vCPU 16 GB tmpfs Neoverse-V3 673,423 <1 µs 303,569 2,708,309 2,522,498 14.7 GiB/s 9.7 GiB/s
r9g.xlarge 4 vCPU 32 GB tmpfs Neoverse-V3 655,713 <1 µs 302,278 2,646,544 2,504,416 14.2 GiB/s 8.9 GiB/s
c8g.xlarge 4 vCPU 8 GB EBS gp3 Neoverse-V2 nobarrier 1,779 864 µs 538 2,992 2,994 401 MiB/s 401 MiB/s
m9g.large 2 vCPU 8 GB EBS gp3 Neoverse-V3 nobarrier 1,789 791 µs 542 2,993 2,994 401 MiB/s 401 MiB/s
r9g.large 2 vCPU 16 GB tmpfs Neoverse-V3 633,186 <1 µs 296,835 1,273,179 1,238,543 14.1 GiB/s 9.2 GiB/s
c8g.large 2 vCPU 4 GB EBS gp3 Neoverse-V2 nobarrier 1,789 856 µs 537 2,994 2,992 401 MiB/s 401 MiB/s
Ubicloud standard 8 vCPU 32 GB VM disk Neoverse-N1 nobarrier 9,282 408 µs 4,597 241,173 130,944 748 MiB/s 503 MiB/s
standard 4 vCPU 4 vCPU 16 GB VM disk Neoverse-N1 nobarrier 8,334 498 µs 3,471 159,875 35,176 742 MiB/s 394 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk Neoverse-N1 nobarrier 7,228 514 µs 4,024 108,266 55,189 776 MiB/s 451 MiB/s
GitHub 2 vCPU 8 GB VM disk Neoverse-N2 nobarrier 7,692 216 µs 3,110 9,376 6,334 199 MiB/s 164 MiB/s
4-core 4 vCPU 16 GB network disk Neoverse-N2 nobarrier 5,324 247 µs 2,755 19,575 12,458 394 MiB/s 320 MiB/s
  • IOPS are 4k blocks, medians of finished jobs
  • bold best disk measured on the arch (tmpfs is RAM, left out)
  • volatile, nobarrier: cheaper, less durable flushes

Pick the disk per job on RunsOn

How it's measured

Methodology

fio runs inside the job, in GITHUB_WORKSPACE: the disk a build writes to, on the filesystem the provider mounted there. Every runner is compared, whatever its shape.

fio settingsblock sizes, queue depths, mounts
  • QD1 random read: 4k blocks, one request in flight; IOPS and p99 latency.
  • Sync write: 4k writes, each followed by fdatasync.
  • Random read and write: 4k blocks, 4 jobs with 32 requests in flight each.
  • Sequential read and write: 1M blocks, 32 requests in flight.
  • The workspace filesystem, its size and its mount options come from the job's own mount table.
  • Earlier versions of this page used a different harness and other fio settings on 2 vCPU runners; those numbers are gone rather than mixed in.