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, so a large gap here can be no gap on a build.

Fastest QD1 read, x64 at 4 vCPU 77,281 Namespace 4x8 (4 vCPU) · reads/s
Fastest QD1 read, arm64 at 4 vCPU 23,603 Blacksmith 4 vCPU · reads/s
GitHub at 4 vCPU 6,570 x64 QD1 reads/s on GitHub 4-core
Fastest synced writes, x64 at 4 vCPU 17,744 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. Blacksmith8 vCPUVM disk81,150, p99 13 µs, ×1.00
  2. Namespace8 vCPU8x32 · VM disk77,750, p99 12 µs, ×0.96
  3. StarSling8 vCPUVM disk59,308, p99 17 µs, ×0.73
  4. Avrea4 vCPUVM disk49,176, p99 15 µs, ×0.61
  5. Warpbuild2 vCPUVM disk28,166, p99 47 µs, ×0.35
  6. RunsOn2 vCPUi7i.large · local NVMe11,676, p99 334 µs, ×0.14
  7. Ubicloud8 vCPUpremium · VM disk10,785, p99 167 µs, ×0.13
  8. GitHub8 vCPUVM disk7,942, p99 177 µs, ×0.10
  9. RunsOn8 vCPUm8a.2xlarge · EBS gp31,814, p99 872 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,766, p99 717 µs, ×0.02

Blacksmith and Namespace lead x64 QD1 read, within 5% (81,150 and 77,750).tmpfs for scale: 1,151,439 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 · 4k + fdatasync · IOPS, higher is better
  1. Blacksmith2 vCPUVM disk · nobarrier18,654, p99 27 µs, ×1.00
  2. Namespace8 vCPU8x32 · VM disk17,821, p99 20 µs, ×0.96
  3. RunsOn2 vCPUi7i.large · local NVMe13,043, p99 34 µs, ×0.70
  4. Avrea8 vCPUVM disk8,780, p99 36 µs, ×0.47
  5. GitHub2 vCPUVM disk · nobarrier4,336, p99 210 µs, ×0.23
  6. StarSling8 vCPUVM disk3,295, p99 29 µs, ×0.18
  7. Ubicloud2 vCPUpremium · VM disk2,683, p99 1,188 µs, ×0.14
  8. Warpbuild8 vCPUVM disk2,133, p99 109 µs, ×0.11
  9. AWS CodeBuild2 vCPUsmall · EBS571, p99 963 µs, ×0.03
  10. RunsOn2 vCPUm8azn.large · EBS gp3 · nobarrier542, p99 995 µs, ×0.03

Blacksmith and Namespace lead x64 synced writes, within 5% (18,654 and 17,821).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. Blacksmith2 vCPUVM disk80,883, p99 19 µs, ×1.00
  2. Namespace2 vCPU2x8 · VM disk77,442, p99 13 µs, ×0.96
  3. Avrea2 vCPUVM disk44,537, p99 17 µs, ×0.55
  4. Warpbuild2 vCPUVM disk28,166, p99 47 µs, ×0.35
  5. RunsOn2 vCPUi7i.large · local NVMe11,676, p99 334 µs, ×0.14
  6. GitHub2 vCPUVM disk7,066, p99 222 µs, ×0.09
  7. Ubicloud2 vCPUstandard · VM disk6,445, p99 1,090 µs, ×0.08
  8. RunsOn2 vCPUc8a.large · EBS gp31,812, p99 741 µs, ×0.02
  9. AWS CodeBuild2 vCPUsmall · EBS1,760, p99 709 µs, ×0.02

Blacksmith and Namespace lead x64 2 vCPU QD1 read, within 5% (80,883 and 77,442).tmpfs for scale: 1,151,439 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 at 2 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Blacksmith2 vCPUVM disk · nobarrier18,654, p99 27 µs, ×1.00
  2. Namespace2 vCPU2x8 · VM disk17,813, p99 23 µs, ×0.95
  3. RunsOn2 vCPUi7i.large · local NVMe13,043, p99 34 µs, ×0.70
  4. Avrea2 vCPUVM disk8,263, p99 34 µs, ×0.44
  5. GitHub2 vCPUVM disk · nobarrier4,336, p99 210 µs, ×0.23
  6. Ubicloud2 vCPUpremium · VM disk2,683, p99 1,188 µs, ×0.14
  7. Warpbuild2 vCPUVM disk2,084, p99 117 µs, ×0.11
  8. AWS CodeBuild2 vCPUsmall · EBS571, p99 963 µs, ×0.03
  9. RunsOn2 vCPUm8azn.large · EBS gp3 · nobarrier542, p99 995 µs, ×0.03

Blacksmith and Namespace lead x64 2 vCPU synced writes, within 5% (18,654 and 17,813).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 vCPU4x8 · VM disk77,281, p99 13 µs, ×1.00
  2. Blacksmith4 vCPUVM disk67,769, p99 18 µs, ×0.88
  3. StarSling4 vCPUVM disk55,952, p99 18 µs, ×0.72
  4. Avrea4 vCPUVM disk49,176, p99 15 µs, ×0.64
  5. Warpbuild4 vCPUVM disk26,074, p99 57 µs, ×0.34
  6. RunsOn4 vCPUm8id.xlarge · local NVMe11,059, p99 206 µs, ×0.14
  7. Ubicloud4 vCPUstandard · VM disk9,177, p99 465 µs, ×0.12
  8. GitHub4 vCPUnetwork disk6,570, p99 297 µs, ×0.09
  9. RunsOn4 vCPUc8a.xlarge · EBS gp31,787, p99 750 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,766, p99 717 µs, ×0.02

Fastest x64 4 vCPU QD1 read: Namespace (77,281), ahead of Blacksmith (67,769).tmpfs for scale: 1,151,439 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace4 vCPU4x8 · VM disk17,744, p99 22 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier16,362, p99 28 µs, ×0.92
  3. RunsOn4 vCPUi7i.xlarge · local NVMe12,583, p99 35 µs, ×0.71
  4. Avrea4 vCPUVM disk8,723, p99 31 µs, ×0.49
  5. GitHub4 vCPUnetwork disk · nobarrier4,328, p99 297 µs, ×0.24
  6. StarSling4 vCPUVM disk3,010, p99 30 µs, ×0.17
  7. Warpbuild4 vCPUVM disk1,831, p99 118 µs, ×0.10
  8. Ubicloud4 vCPUstandard · VM disk1,533, p99 2,507 µs, ×0.09
  9. AWS CodeBuild4 vCPUmedium · EBS566, p99 995 µs, ×0.03
  10. RunsOn4 vCPUm8azn.xlarge · EBS gp3 · nobarrier541, p99 963 µs, ×0.03

Fastest x64 4 vCPU synced writes: Namespace (17,744), ahead of Blacksmith (16,362).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. Blacksmith8 vCPUVM disk81,150, p99 13 µs, ×1.00
  2. Namespace8 vCPU8x32 · VM disk77,750, p99 12 µs, ×0.96
  3. StarSling8 vCPUVM disk59,308, p99 17 µs, ×0.73
  4. Avrea8 vCPUVM disk46,088, p99 14 µs, ×0.57
  5. Warpbuild8 vCPUVM disk27,503, p99 48 µs, ×0.34
  6. RunsOn8 vCPUi7i.2xlarge · local NVMe11,608, p99 293 µs, ×0.14
  7. Ubicloud8 vCPUpremium · VM disk10,785, p99 167 µs, ×0.13
  8. GitHub8 vCPUVM disk7,942, p99 177 µs, ×0.10
  9. RunsOn8 vCPUm8a.2xlarge · EBS gp31,814, p99 872 µs, ×0.02
  10. AWS CodeBuild8 vCPUlarge · EBS1,755, p99 782 µs, ×0.02

Blacksmith and Namespace lead x64 8 vCPU QD1 read, within 5% (81,150 and 77,750).tmpfs for scale: 1,151,439 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Blacksmith8 vCPUVM disk · nobarrier18,586, p99 21 µs, ×1.00
  2. Namespace8 vCPU8x32 · VM disk17,821, p99 20 µs, ×0.96
  3. RunsOn8 vCPUi7i.2xlarge · local NVMe11,713, p99 38 µs, ×0.63
  4. Avrea8 vCPUVM disk8,780, p99 36 µs, ×0.47
  5. GitHub8 vCPUVM disk · nobarrier4,220, p99 232 µs, ×0.23
  6. StarSling8 vCPUVM disk3,295, p99 29 µs, ×0.18
  7. Ubicloud8 vCPUpremium · VM disk2,661, p99 1,516 µs, ×0.14
  8. Warpbuild8 vCPUVM disk2,133, p99 109 µs, ×0.11
  9. AWS CodeBuild8 vCPUlarge · EBS563, p99 987 µs, ×0.03
  10. RunsOn8 vCPUm8a.2xlarge · gp3 1000 MiB/s · nobarrier540, p99 1,028 µs, ×0.03

Blacksmith and Namespace lead x64 8 vCPU synced writes, within 5% (18,586 and 17,821).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 disk26,620, p99 79 µs, ×1.00
  2. Blacksmith8 vCPUVM disk24,944, p99 38 µs, ×0.94
  3. Avrea4 vCPUVM disk21,648, p99 57 µs, ×0.81
  4. Namespace4 vCPUApple silicon 4x16 · VM disk20,197, p99 98 µs, ×0.76
  5. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,508, p99 81 µs, ×0.51
  6. Ubicloud8 vCPUstandard · VM disk9,786, p99 379 µs, ×0.37
  7. GitHub4 vCPUnetwork disk8,202, p99 214 µs, ×0.31
  8. RunsOn4 vCPUc8g.xlarge · EBS gp31,838, p99 913 µs, ×0.07
  9. Warpbuild8 vCPUEBS1,808, p99 750 µs, ×0.07

Fastest arm64 QD1 read: Warpbuild (26,620), ahead of Blacksmith (24,944).tmpfs for scale: 682,673 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 · 4k + fdatasync · IOPS, higher is better
  1. RunsOn8 vCPUm9gd.2xlarge · local NVMe17,511, p99 19 µs, ×1.00
  2. Warpbuild12 vCPUxfast (Apple M4 Pro) · VM disk · nobarrier8,309, p99 61 µs, ×0.47
  3. Blacksmith8 vCPUVM disk · nobarrier7,401, p99 64 µs, ×0.42
  4. GitHub4 vCPUnetwork disk · nobarrier4,381, p99 281 µs, ×0.25
  5. Avrea2 vCPUVM disk4,202, p99 54 µs, ×0.24
  6. Ubicloud2 vCPUstandard · VM disk4,147, p99 453 µs, ×0.24
  7. Namespace8 vCPU8x32 · VM disk3,933, p99 171 µs, ×0.22
  8. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 1,004 µs, ×0.03
  9. Warpbuild8 vCPUEBS · nobarrier540, p99 987 µs, ×0.03

Fastest arm64 synced writes: RunsOn m9gd.2xlarge · NVMe (17,511), ahead of Warpbuild (8,309).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 disk21,992, p99 50 µs, ×1.00
  2. Avrea2 vCPUVM disk21,590, p99 58 µs, ×0.98
  3. Namespace2 vCPUApple silicon 2x8 · VM disk20,070, p99 88 µs, ×0.91
  4. RunsOn2 vCPUm9gd.large · local NVMe13,466, p99 81 µs, ×0.61
  5. Ubicloud2 vCPUstandard · VM disk8,415, p99 358 µs, ×0.38
  6. GitHub2 vCPUVM disk7,775, p99 232 µs, ×0.35
  7. Warpbuild2 vCPUEBS1,805, p99 799 µs, ×0.08
  8. RunsOn2 vCPUm9g.large · EBS gp31,789, p99 864 µs, ×0.08

Blacksmith and Avrea lead arm64 2 vCPU QD1 read, within 5% (21,992 and 21,590).tmpfs for scale: 682,673 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 · nobarrier6,383, p99 95 µs, ×0.88
  3. Avrea2 vCPUVM disk4,202, p99 54 µs, ×0.58
  4. Ubicloud2 vCPUstandard · VM disk4,147, p99 453 µs, ×0.57
  5. Namespace2 vCPU2x8 · VM disk3,881, p99 189 µs, ×0.53
  6. GitHub2 vCPUVM disk · nobarrier3,013, p99 420 µs, ×0.41
  7. RunsOn2 vCPUm9g.large · EBS gp3 · nobarrier543, p99 987 µs, ×0.07
  8. Warpbuild2 vCPUEBS · nobarrier538, p99 995 µs, ×0.07

Fastest arm64 2 vCPU synced writes: RunsOn m9gd.large · NVMe (7,267), ahead of Blacksmith (6,383).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 disk23,603, p99 54 µs, ×1.00
  2. Avrea4 vCPUVM disk21,648, p99 57 µs, ×0.92
  3. Namespace4 vCPUApple silicon 4x16 · VM disk20,197, p99 98 µs, ×0.86
  4. RunsOn4 vCPUm9gd.xlarge · local NVMe13,441, p99 84 µs, ×0.57
  5. GitHub4 vCPUnetwork disk8,202, p99 214 µs, ×0.35
  6. Ubicloud4 vCPUstandard · VM disk7,432, p99 594 µs, ×0.31
  7. RunsOn4 vCPUc8g.xlarge · EBS gp31,838, p99 913 µs, ×0.08
  8. Warpbuild4 vCPUEBS1,807, p99 823 µs, ×0.08

Fastest arm64 4 vCPU QD1 read: Blacksmith (23,603), ahead of Avrea (21,648).tmpfs for scale: 682,673 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn4 vCPUm9gd.xlarge · local NVMe14,867, p99 23 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier7,138, p99 75 µs, ×0.48
  3. GitHub4 vCPUnetwork disk · nobarrier4,381, p99 281 µs, ×0.29
  4. Avrea4 vCPUVM disk3,936, p99 55 µs, ×0.26
  5. Namespace4 vCPU4x8 · VM disk3,761, p99 202 µs, ×0.25
  6. Ubicloud4 vCPUstandard · VM disk1,888, p99 3,424 µs, ×0.13
  7. RunsOn4 vCPUm9g.xlarge · EBS gp3 · nobarrier542, p99 979 µs, ×0.04
  8. Warpbuild4 vCPUEBS · nobarrier539, p99 979 µs, ×0.04

Fastest arm64 4 vCPU synced writes: RunsOn m9gd.xlarge · NVMe (14,867), ahead of Blacksmith (7,138).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,944, p99 38 µs, ×1.00
  2. Avrea8 vCPUVM disk20,543, p99 53 µs, ×0.82
  3. Namespace8 vCPU8x32 · VM disk16,789, p99 93 µs, ×0.67
  4. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,508, p99 81 µs, ×0.54
  5. Ubicloud8 vCPUstandard · VM disk9,786, p99 379 µs, ×0.39
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp31,810, p99 856 µs, ×0.07
  7. Warpbuild8 vCPUEBS1,808, p99 750 µs, ×0.07

Fastest arm64 8 vCPU QD1 read: Blacksmith (24,944), ahead of Avrea (20,543).tmpfs for scale: 682,673 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn8 vCPUm9gd.2xlarge · local NVMe17,511, p99 19 µs, ×1.00
  2. Blacksmith8 vCPUVM disk · nobarrier7,401, p99 64 µs, ×0.42
  3. Namespace8 vCPU8x32 · VM disk3,933, p99 171 µs, ×0.22
  4. Avrea8 vCPUVM disk3,834, p99 56 µs, ×0.22
  5. Ubicloud8 vCPUstandard · VM disk3,608, p99 979 µs, ×0.21
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 1,004 µs, ×0.03
  7. Warpbuild8 vCPUEBS · nobarrier540, p99 987 µs, ×0.03

Fastest arm64 8 vCPU synced writes: RunsOn m9gd.2xlarge · NVMe (17,511), ahead of Blacksmith (7,401).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 81,150 times a second on Blacksmith 8 vCPU and 1,539 on RunsOn m8i.2xlarge · EBS gp3, 53× apart; p99 latency is 13 µs against 1,057 µs.
  • Synced 4k writes on x64 run from 489 per second on RunsOn m8i.2xlarge · EBS gp3 (workspace mounted nobarrier) to 18,654 on Blacksmith 2 vCPU (workspace mounted nobarrier).
  • r8a.large with tmpfs ($0.0010/min at spot) answers 1,097,813 QD1 reads and 424,773 synced writes per second: 91× and 32× the best local NVMe at 2 vCPU (i7i.large, $0.0010) and 606× and 785× default EBS gp3 (c8a.large, $0.0010); its workspace is 23 GiB, from RAM. (EC2 storage suite) What that does to real builds.
More findings22: arm64, NVMe vs EBS, provisioned gp3, tmpfs, storage classes
  • On arm64, one small read at a time (4k, QD1) comes back 26,620 times a second on Warpbuild xfast (Apple M4 Pro) 6 vCPU and 1,466 on RunsOn m9g.xlarge · EBS gp3, 18× apart; p99 latency is 79 µs against 1,028 µs.
  • Synced 4k writes on arm64 run from 537 per second on RunsOn c8g.large · EBS gp3 (workspace mounted nobarrier) to 17,511 on RunsOn m9gd.2xlarge · local NVMe.
  • Same Xeon 6975P-C CPU, different disk: m8id.2xlarge on local NVMe answers 10,286 QD1 reads and 7,361 synced writes per second, m8i.2xlarge on EBS gp3 1,539 and 489.
  • Same Xeon 6975P-C CPU, different disk: m8id.large on local NVMe answers 11,124 QD1 reads and 5,540 synced writes per second, m8i-flex.large on EBS gp3 1,745 and 532.
  • Same Xeon 6975P-C CPU, different disk: m8id.xlarge on local NVMe answers 11,059 QD1 reads and 8,128 synced writes per second, m8i-flex.xlarge on EBS gp3 1,707 and 520.
  • Same Neoverse-V3 CPU, different disk: m9gd.2xlarge on local NVMe answers 13,508 QD1 reads and 17,511 synced writes per second, m9g.2xlarge on EBS gp3 1,810 and 543.
  • Same Neoverse-V3 CPU, different disk: m9gd.xlarge on local NVMe answers 13,441 QD1 reads and 14,867 synced writes per second, m9g.xlarge on EBS gp3 1,466 and 542.
  • Same Neoverse-V3 CPU, different disk: m9gd.large on local NVMe answers 13,466 QD1 reads and 7,267 synced writes per second, m9g.large on EBS gp3 1,789 and 543.
  • Provisioning gp3 at 1000 MiB/s on m8a.2xlarge takes sequential reads from 402 MiB/s to 1,002 MiB/s (2.5×); QD1 reads barely move (1,791 → 1,792 IOPS): it buys bandwidth, not latency.
  • 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 go (1,780 → 1,541 IOPS).
  • tmpfs on m8a.2xlarge is not a disk at all: 1,120,738 QD1 reads and 424,611 synced writes per second, from RAM. The workspace is 46 GiB, sized by memory.
  • tmpfs on m9g.2xlarge is not a disk at all: 663,906 QD1 reads and 301,046 synced writes per second, from RAM. The workspace is 46 GiB, sized by memory.
  • tmpfs on m9g.xlarge is not a disk at all: 682,673 QD1 reads and 303,857 synced writes per second, from RAM. The workspace is 23 GiB, sized by memory.
  • tmpfs on r8a.2xlarge is not a disk at all: 1,151,439 QD1 reads and 426,203 synced writes per second, from RAM. The workspace is 92 GiB, sized by memory.
  • tmpfs on r8a.xlarge is not a disk at all: 1,120,049 QD1 reads and 432,796 synced writes per second, from RAM. The workspace is 46 GiB, sized by memory.
  • tmpfs on r9g.large is not a disk at all: 634,536 QD1 reads and 295,874 synced writes per second, from RAM. The workspace is 23 GiB, sized by memory.
  • tmpfs on r9g.xlarge is not a disk at all: 651,339 QD1 reads and 301,773 synced writes per second, from RAM. The workspace is 46 GiB, sized by memory.
  • tmpfs: 635k–1.2M QD1 reads and 296k–433k synced writes per second across 8 runners (8 RunsOn configurations).
  • VM disk: 6.0k–81k QD1 reads and 1.2k–19k 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: 10k–14k QD1 reads and 5.5k–18k synced writes per second across 9 runners (9 RunsOn configurations).
  • network disk: 6.6k–8.2k QD1 reads and 4.3k–4.4k synced writes per second across 2 runners (2 GitHub runners).
  • EBS: 1.5k–1.8k QD1 reads and 489–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.

At 4 vCPU, Namespace 4x8 answers 44× the QD1 reads of RunsOn m8a.xlarge · EBS gp3 (77,281 against 1,771 per second), and the Rust build takes 1m 52s on one and 1m 48s on the other. Every build, per runner.

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
Blacksmith 8 vCPU 32 GB VM disk EPYC · model hidden nobarrier 81,150 13 µs 18,586 625,138 337,040 7.1 GiB/s 1.9 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC · model hidden nobarrier 67,769 18 µs 16,362 714,954 209,551 6.5 GiB/s 1.9 GiB/s
2 vCPU 2 vCPU 8 GB VM disk EPYC · model hidden nobarrier 80,883 19 µs 18,654 795,024 190,497 7.7 GiB/s 2.0 GiB/s
Namespace 8x32 8 vCPU 32 GB VM disk EPYC · model hidden 77,750 12 µs 17,821 1,129,852 522,909 4.1 GiB/s 2.9 GiB/s
8x16 8 vCPU 16 GB VM disk EPYC · model hidden 75,666 13 µs 17,601 1,096,746 465,716 3.8 GiB/s 2.4 GiB/s
4x16 4 vCPU 16 GB VM disk EPYC · model hidden 76,383 13 µs 17,587 982,722 406,763 4.1 GiB/s 2.8 GiB/s
4x8 4 vCPU 8 GB VM disk EPYC · model hidden 77,281 13 µs 17,744 992,094 440,629 4.1 GiB/s 2.9 GiB/s
2x8 2 vCPU 8 GB VM disk EPYC · model hidden 77,442 13 µs 17,813 351,895 224,905 4.1 GiB/s 3.0 GiB/s
StarSling 8 vCPU 32 GB VM disk EPYC · model hidden 59,308 17 µs 3,295 231,481 52,979 2.4 GiB/s 2.7 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC · model hidden 55,952 18 µs 3,010 288,810 47,132 3.1 GiB/s 3.3 GiB/s
Avrea 4 vCPU 16 GB VM disk EPYC 4585PX 49,176 15 µs 8,723 391,395 224,464 8.6 GiB/s 7.4 GiB/s
8 vCPU 8 vCPU 32 GB VM disk EPYC 4585PX 46,088 14 µs 8,780 326,315 224,131 10.0 GiB/s 7.4 GiB/s
2 vCPU 2 vCPU 8 GB VM disk EPYC 4585PX 44,537 17 µs 8,263 315,150 324,338 12.0 GiB/s 7.5 GiB/s
Warpbuild 2 vCPU 8 GB VM disk Ryzen 9 9950X 28,166 47 µs 2,084 152,215 67,413 7.0 GiB/s 4.5 GiB/s
8 vCPU 8 vCPU 32 GB VM disk Ryzen 9 9950X 27,503 48 µs 2,133 154,260 46,890 8.4 GiB/s 5.1 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 9950X 26,074 57 µs 1,831 185,061 58,885 7.1 GiB/s 4.9 GiB/s
RunsOn i7i.large 2 vCPU 16 GB local NVMe Xeon 8559C 11,676 334 µs 13,043 75,023 41,224 503 MiB/s 395 MiB/s
m8azn.3xlarge 12 vCPU 48 GB EBS gp3 EPYC 9R05 nobarrier 1,558 995 µs 539 2,997 2,994 401 MiB/s 401 MiB/s
m8a.2xlarge 8 vCPU 32 GB EBS gp3 EPYC 9R45 nobarrier 1,814 872 µs 539 2,994 2,992 401 MiB/s 401 MiB/s
m8a.2xlarge 8 vCPU 32 GB gp3 1000 MiB/s EPYC 9R45 nobarrier 1,714 889 µs 540 15,996 15,992 1,001 MiB/s 1,001 MiB/s
c8a.2xlarge 8 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,710 872 µs 540 2,995 2,992 401 MiB/s 401 MiB/s
r8a.2xlarge 8 vCPU 64 GB tmpfs EPYC 9R45 1,151,439 <1 µs 426,203 4,220,451 3,797,787 18.5 GiB/s 10.0 GiB/s
m8a.2xlarge 8 vCPU 32 GB tmpfs EPYC 9R45 1,120,738 <1 µs 424,611 4,255,814 3,812,490 18.2 GiB/s 10.0 GiB/s
m8azn.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R05 nobarrier 1,780 872 µs 541 2,994 2,991 401 MiB/s 401 MiB/s
m8azn.xlarge 4 vCPU 16 GB gp3 1000 MiB/s EPYC 9R05 nobarrier 1,541 905 µs 539 15,994 15,992 1,001 MiB/s 1,001 MiB/s
m8id.2xlarge 8 vCPU 32 GB local NVMe Xeon 6975P-C 10,286 293 µs 7,361 134,258 67,071 905 MiB/s 432 MiB/s
m8i.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,539 1,057 µs 489 2,994 2,993 401 MiB/s 401 MiB/s
m8i-flex.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,754 889 µs 518 2,993 2,994 401 MiB/s 401 MiB/s
i7i.2xlarge 8 vCPU 64 GB local NVMe Xeon 8559C 11,608 293 µs 11,713 300,466 165,112 2.0 GiB/s 1.5 GiB/s
m8a.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,771 930 µs 540 2,994 2,993 401 MiB/s 401 MiB/s
r8a.xlarge 4 vCPU 32 GB tmpfs EPYC 9R45 1,120,049 <1 µs 432,796 4,213,197 3,801,248 18.4 GiB/s 10.1 GiB/s
c8a.xlarge 4 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,787 750 µs 540 2,994 2,992 401 MiB/s 401 MiB/s
m8azn.large 2 vCPU 8 GB EBS gp3 EPYC 9R05 nobarrier 1,809 815 µs 542 2,994 2,991 401 MiB/s 401 MiB/s
m8id.xlarge 4 vCPU 16 GB local NVMe Xeon 6975P-C 11,059 206 µs 8,128 67,090 33,524 451 MiB/s 216 MiB/s
m8i-flex.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,707 848 µs 520 2,994 2,992 401 MiB/s 401 MiB/s
m8i.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,696 832 µs 523 2,992 2,994 401 MiB/s 401 MiB/s
i7i.xlarge 4 vCPU 32 GB local NVMe Xeon 8559C 11,028 301 µs 12,583 150,052 82,489 1,010 MiB/s 788 MiB/s
m8a.large 2 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,782 725 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
r8a.large 2 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,780 782 µs 540 2,994 2,992 401 MiB/s 401 MiB/s
r8a.large 2 vCPU 16 GB tmpfs EPYC 9R45 1,097,813 <1 µs 424,773 2,178,293 1,943,626 18.1 GiB/s 9.9 GiB/s
c8a.large 2 vCPU 4 GB EBS gp3 EPYC 9R45 nobarrier 1,812 741 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
m8id.large 2 vCPU 8 GB local NVMe Xeon 6975P-C 11,124 204 µs 5,540 33,542 16,754 226 MiB/s 108 MiB/s
m8i-flex.large 2 vCPU 8 GB EBS gp3 Xeon 6975P-C nobarrier 1,745 848 µs 532 2,994 2,992 401 MiB/s 401 MiB/s
m8i.large 2 vCPU 8 GB EBS gp3 Xeon 6975P-C nobarrier 1,633 913 µs 535 2,993 2,994 401 MiB/s 401 MiB/s
t8i.medium 2 vCPU 4 GB EBS gp3 Xeon 6975P-C nobarrier 1,734 823 µs 521 3,005 2,998 401 MiB/s 401 MiB/s
Ubicloud premium 8 vCPU 32 GB VM disk Ryzen 9 7950X3D 10,785 167 µs 2,661 362,628 20,504 3.0 GiB/s 826 MiB/s
standard 8 vCPU 8 vCPU 32 GB VM disk EPYC 9454P 8,031 528 µs 1,562 251,230 14,889 2.7 GiB/s 716 MiB/s
premium 4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 7950X3D 6,435 2,114 µs 1,157 143,006 8,602 2.3 GiB/s 537 MiB/s
standard 4 vCPU 4 vCPU 16 GB VM disk EPYC 9454 9,177 465 µs 1,533 193,790 12,781 2.7 GiB/s 578 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk EPYC 9454P 6,445 1,090 µs 1,288 105,928 60,814 2.5 GiB/s 622 MiB/s
premium 2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 7950X3D 5,960 1,106 µs 2,683 129,551 67,557 2.6 GiB/s 752 MiB/s
GitHub 8 vCPU 32 GB VM disk EPYC 9V74 nobarrier 7,942 177 µs 4,220 38,977 18,507 783 MiB/s 532 MiB/s
4-core 4 vCPU 16 GB network disk EPYC 9V45 nobarrier 6,570 297 µs 4,328 19,577 9,322 394 MiB/s 245 MiB/s
2-core 2 vCPU 8 GB VM disk EPYC 7763 nobarrier 7,066 222 µs 4,336 9,383 9,098 199 MiB/s 200 MiB/s
AWS CodeBuild medium 4 vCPU 8 GB EBS Xeon 8488C 1,766 717 µs 566 2,990 2,979 251 MiB/s 251 MiB/s
large 8 vCPU 16 GB EBS Xeon 8488C 1,755 782 µs 563 2,991 2,977 251 MiB/s 251 MiB/s
small 2 vCPU 3 GB EBS Xeon 8488C 1,760 709 µs 571 2,988 2,972 195 MiB/s 251 MiB/s
arm6436 runners, 7 providers
Warpbuild xfast (Apple M4 Pro) 6 vCPU 14 GB VM disk nobarrier 26,620 79 µs 6,948 213,753 5,164 19.4 GiB/s 20.3 GiB/s
xfast (Apple M4 Pro) 12 vCPU 12 vCPU 28 GB VM disk nobarrier 23,397 52 µs 8,309 335,287 4,460 21.6 GiB/s 25.1 GiB/s
8 vCPU 8 vCPU 32 GB EBS Neoverse-V2 nobarrier 1,808 750 µs 540 4,995 4,993 401 MiB/s 401 MiB/s
4 vCPU 4 vCPU 16 GB EBS Neoverse-V2 nobarrier 1,807 823 µs 539 4,193 4,193 302 MiB/s 302 MiB/s
2 vCPU 2 vCPU 8 GB EBS Neoverse-V2 nobarrier 1,805 799 µs 538 4,194 4,194 302 MiB/s 301 MiB/s
Blacksmith 8 vCPU 32 GB VM disk Ampere-1a nobarrier 24,944 38 µs 7,401 218,423 25,290 1.6 GiB/s 902 MiB/s
4 vCPU 4 vCPU 16 GB VM disk Ampere-1a nobarrier 23,603 54 µs 7,138 171,567 24,783 1.6 GiB/s 863 MiB/s
2 vCPU 2 vCPU 6 GB VM disk Ampere-1a nobarrier 21,992 50 µs 6,383 74,915 26,068 1.7 GiB/s 813 MiB/s
Avrea 4 vCPU 16 GB VM disk Apple M5 Max · as stated by the provider 21,648 57 µs 3,936 148,274 67,748 31.5 GiB/s 17.2 GiB/s
8 vCPU 8 vCPU 32 GB VM disk Apple M5 Max · as stated by the provider 20,543 53 µs 3,834 139,939 18,426 36.8 GiB/s 16.1 GiB/s
2 vCPU 2 vCPU 8 GB VM disk Apple M5 Max · as stated by the provider 21,590 58 µs 4,202 166,655 26,821 31.2 GiB/s 14.8 GiB/s
Namespace Apple silicon 4x16 4 vCPU 16 GB VM disk CPU not reported 20,197 98 µs 3,461 139,782 13,347 31.3 GiB/s 14.8 GiB/s
Apple silicon 2x8 2 vCPU 8 GB VM disk CPU not reported 20,070 88 µs 3,695 160,201 16,572 33.8 GiB/s 14.2 GiB/s
8x32 8 vCPU 32 GB VM disk Ampere-1a 16,789 93 µs 3,933 184,768 39,396 891 MiB/s 691 MiB/s
8x16 8 vCPU 16 GB VM disk Ampere-1a 14,810 98 µs 3,419 163,472 41,036 890 MiB/s 736 MiB/s
4x8 4 vCPU 8 GB VM disk Ampere-1a 17,003 90 µs 3,761 143,176 32,144 962 MiB/s 696 MiB/s
4x16 4 vCPU 16 GB VM disk Ampere-1a 17,241 87 µs 3,758 144,961 32,179 962 MiB/s 760 MiB/s
2x8 2 vCPU 8 GB VM disk Ampere-1a 16,546 92 µs 3,881 79,835 28,646 941 MiB/s 763 MiB/s
RunsOn m9gd.2xlarge 8 vCPU 32 GB local NVMe Neoverse-V3 13,508 81 µs 17,511 174,572 87,207 1.1 GiB/s 561 MiB/s
m9g.2xlarge 8 vCPU 32 GB EBS gp3 Neoverse-V3 nobarrier 1,810 856 µs 543 2,995 2,992 401 MiB/s 401 MiB/s
m9g.2xlarge 8 vCPU 32 GB tmpfs Neoverse-V3 663,906 <1 µs 301,046 2,676,737 2,507,590 12.0 GiB/s 9.7 GiB/s
c8g.2xlarge 8 vCPU 16 GB EBS gp3 Neoverse-V2 nobarrier 1,778 864 µs 539 2,994 2,992 401 MiB/s 401 MiB/s
m9gd.xlarge 4 vCPU 16 GB local NVMe Neoverse-V3 13,441 84 µs 14,867 87,221 43,590 585 MiB/s 281 MiB/s
m9g.xlarge 4 vCPU 16 GB EBS gp3 Neoverse-V3 nobarrier 1,466 1,028 µs 542 2,994 2,991 401 MiB/s 401 MiB/s
m9g.xlarge 4 vCPU 16 GB tmpfs Neoverse-V3 682,673 <1 µs 303,857 2,738,123 2,547,343 15.7 GiB/s 9.6 GiB/s
r9g.xlarge 4 vCPU 32 GB tmpfs Neoverse-V3 651,339 <1 µs 301,773 2,616,847 2,493,564 13.3 GiB/s 9.1 GiB/s
c8g.xlarge 4 vCPU 8 GB EBS gp3 Neoverse-V2 nobarrier 1,838 913 µs 539 2,994 2,993 401 MiB/s 401 MiB/s
m9gd.large 2 vCPU 8 GB local NVMe Neoverse-V3 13,466 81 µs 7,267 43,607 21,782 293 MiB/s 141 MiB/s
m9g.large 2 vCPU 8 GB EBS gp3 Neoverse-V3 nobarrier 1,789 864 µs 543 2,993 2,994 401 MiB/s 401 MiB/s
r9g.large 2 vCPU 16 GB tmpfs Neoverse-V3 634,536 <1 µs 295,874 1,218,242 1,203,310 13.2 GiB/s 8.5 GiB/s
c8g.large 2 vCPU 4 GB EBS gp3 Neoverse-V2 nobarrier 1,739 954 µs 537 2,993 2,994 401 MiB/s 401 MiB/s
Ubicloud standard 8 vCPU 32 GB VM disk Neoverse-N1 9,786 379 µs 3,608 241,605 119,660 822 MiB/s 487 MiB/s
standard 4 vCPU 4 vCPU 16 GB VM disk Neoverse-N1 7,432 594 µs 1,888 170,555 50,555 810 MiB/s 357 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk Neoverse-N1 8,415 358 µs 4,147 74,749 39,464 892 MiB/s 481 MiB/s
GitHub 4 vCPU 16 GB network disk Neoverse-N2 nobarrier 8,202 214 µs 4,381 19,596 11,809 394 MiB/s 339 MiB/s
2-core 2 vCPU 8 GB VM disk Neoverse-N2 nobarrier 7,775 232 µs 3,013 9,376 6,035 199 MiB/s 164 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.