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 101,308 Namespace 4x16 (4 vCPU) · reads/s
Fastest QD1 read, arm64 at 4 vCPU 23,627 Blacksmith 4 vCPU · reads/s
GitHub at 4 vCPU 7,216 x64 QD1 reads/s on GitHub 4-core
Fastest synced writes, x64 at 4 vCPU 27,833 Namespace 4x16 · writes/s
tmpfs, for scale 1.2M QD1 reads/s on RunsOn r8a.xlarge · 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. Namespace2 vCPU2x8 · VM disk104,659, p99 10 µs, ×1.00
  2. Blacksmith2 vCPUVM disk76,132, p99 15 µs, ×0.73
  3. StarSling8 vCPUVM disk51,989, p99 22 µs, ×0.50
  4. Avrea8 vCPUVM disk50,590, p99 19 µs, ×0.48
  5. Warpbuild8 vCPUVM disk33,993, p99 34 µs, ×0.32
  6. RunsOn8 vCPUi7i.2xlarge · local NVMe12,332, p99 264 µs, ×0.12
  7. Ubicloud4 vCPUstandard · VM disk9,597, p99 379 µs, ×0.09
  8. GitHub8 vCPUVM disk7,870, p99 239 µs, ×0.08
  9. RunsOn2 vCPUm8azn.large · EBS gp31,822, p99 750 µs, ×0.02
  10. AWS CodeBuild2 vCPUsmall · EBS1,761, p99 709 µs, ×0.02

Fastest x64 QD1 read: Namespace (104,659), ahead of Blacksmith (76,132).tmpfs for scale: 1,153,799 on RunsOn r8a.xlarge · tmpfs.

Synced writesx64 · 4k + fdatasync · IOPS, higher is better
  1. Namespace2 vCPU2x8 · VM disk32,331, p99 14 µs, ×1.00
  2. StarSling8 vCPUVM disk17,805, p99 36 µs, ×0.55
  3. Blacksmith2 vCPUVM disk · nobarrier17,760, p99 27 µs, ×0.55
  4. RunsOn2 vCPUi7i.large · local NVMe12,861, p99 34 µs, ×0.40
  5. Avrea2 vCPUVM disk · nobarrier12,521, p99 29 µs, ×0.39
  6. GitHub4 vCPUnetwork disk · nobarrier4,203, p99 367 µs, ×0.13
  7. Ubicloud8 vCPUpremium · VM disk · nobarrier2,822, p99 1,663 µs, ×0.09
  8. Warpbuild8 vCPUVM disk2,743, p99 121 µs, ×0.08
  9. AWS CodeBuild2 vCPUsmall · EBS571, p99 995 µs, ×0.02
  10. RunsOn4 vCPUm8azn.xlarge · EBS gp3 · nobarrier542, p99 995 µs, ×0.02

Fastest x64 synced writes: Namespace (32,331), ahead of StarSling (17,805).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 disk76,132, p99 15 µs, ×0.73
  3. Avrea2 vCPUVM disk50,427, p99 16 µs, ×0.48
  4. Warpbuild2 vCPUVM disk22,485, p99 60 µs, ×0.21
  5. RunsOn2 vCPUi7i.large · local NVMe11,951, p99 293 µs, ×0.11
  6. GitHub2 vCPUVM disk6,868, p99 272 µs, ×0.07
  7. Ubicloud2 vCPUstandard · VM disk6,569, p99 1,045 µs, ×0.06
  8. RunsOn2 vCPUm8azn.large · EBS gp31,822, p99 750 µs, ×0.02
  9. AWS CodeBuild2 vCPUsmall · EBS1,761, p99 709 µs, ×0.02

Fastest x64 2 vCPU QD1 read: Namespace (104,659), ahead of Blacksmith (76,132).tmpfs for scale: 1,153,799 on RunsOn r8a.xlarge · 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 · nobarrier17,760, p99 27 µs, ×0.55
  3. RunsOn2 vCPUi7i.large · local NVMe12,861, p99 34 µs, ×0.40
  4. Avrea2 vCPUVM disk · nobarrier12,521, p99 29 µs, ×0.39
  5. GitHub2 vCPUVM disk · nobarrier3,862, p99 212 µs, ×0.12
  6. Warpbuild2 vCPUVM disk2,287, p99 68 µs, ×0.07
  7. Ubicloud2 vCPUpremium · VM disk · nobarrier1,491, p99 2,572 µs, ×0.05
  8. AWS CodeBuild2 vCPUsmall · EBS571, p99 995 µ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 (17,760).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 disk101,308, p99 11 µs, ×1.00
  2. Blacksmith4 vCPUVM disk70,530, p99 16 µs, ×0.70
  3. Avrea4 vCPUVM disk49,995, p99 16 µs, ×0.49
  4. StarSling4 vCPUVM disk41,156, p99 25 µs, ×0.41
  5. Warpbuild4 vCPUVM disk29,556, p99 53 µs, ×0.29
  6. RunsOn4 vCPUi7i.xlarge · local NVMe11,028, p99 261 µs, ×0.11
  7. Ubicloud4 vCPUstandard · VM disk9,597, p99 379 µs, ×0.09
  8. GitHub4 vCPUnetwork disk7,216, p99 297 µs, ×0.07
  9. RunsOn4 vCPUm8a.xlarge · EBS gp31,817, p99 741 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,760, p99 684 µs, ×0.02

Fastest x64 4 vCPU QD1 read: Namespace (101,308), ahead of Blacksmith (70,530).tmpfs for scale: 1,153,799 on RunsOn r8a.xlarge · tmpfs.

Synced writesx64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace4 vCPU4x16 · VM disk27,833, p99 17 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier17,134, p99 24 µs, ×0.62
  3. StarSling4 vCPUVM disk · volatile13,381, p99 38 µs, ×0.48
  4. RunsOn4 vCPUi7i.xlarge · local NVMe12,619, p99 33 µs, ×0.45
  5. Avrea4 vCPUVM disk · nobarrier12,385, p99 29 µs, ×0.44
  6. GitHub4 vCPUnetwork disk · nobarrier4,203, p99 367 µs, ×0.15
  7. Warpbuild4 vCPUVM disk2,329, p99 140 µs, ×0.08
  8. Ubicloud4 vCPUstandard · VM disk · nobarrier1,826, p99 2,507 µs, ×0.07
  9. AWS CodeBuild4 vCPUmedium · EBS566, p99 938 µs, ×0.02
  10. RunsOn4 vCPUm8azn.xlarge · EBS gp3 · nobarrier542, p99 995 µs, ×0.02

Fastest x64 4 vCPU synced writes: Namespace (27,833), ahead of Blacksmith (17,134).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 vCPU8x32 · VM disk104,083, p99 10 µs, ×1.00
  2. Blacksmith8 vCPUVM disk55,275, p99 19 µs, ×0.53
  3. StarSling8 vCPUVM disk51,989, p99 22 µs, ×0.50
  4. Avrea8 vCPUVM disk50,590, p99 19 µs, ×0.49
  5. Warpbuild8 vCPUVM disk33,993, p99 34 µs, ×0.33
  6. RunsOn8 vCPUi7i.2xlarge · local NVMe12,332, p99 264 µs, ×0.12
  7. Ubicloud8 vCPUpremium · VM disk9,253, p99 326 µs, ×0.09
  8. GitHub8 vCPUVM disk7,870, p99 239 µs, ×0.08
  9. RunsOn8 vCPUm8i-flex.2xlarge · EBS gp31,787, p99 905 µs, ×0.02
  10. AWS CodeBuild8 vCPUlarge · EBS1,757, p99 692 µs, ×0.02

Fastest x64 8 vCPU QD1 read: Namespace (104,083), ahead of Blacksmith (55,275).tmpfs for scale: 1,153,799 on RunsOn r8a.xlarge · tmpfs.

Synced writesx64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace8 vCPU8x32 · VM disk28,934, p99 14 µs, ×1.00
  2. StarSling8 vCPUVM disk17,805, p99 36 µs, ×0.62
  3. Blacksmith8 vCPUVM disk · nobarrier13,820, p99 27 µs, ×0.48
  4. RunsOn8 vCPUi7i.2xlarge · local NVMe11,692, p99 38 µs, ×0.40
  5. Avrea8 vCPUVM disk · nobarrier11,323, p99 43 µs, ×0.39
  6. GitHub8 vCPUVM disk · nobarrier3,710, p99 261 µs, ×0.13
  7. Ubicloud8 vCPUpremium · VM disk · nobarrier2,822, p99 1,663 µs, ×0.10
  8. Warpbuild8 vCPUVM disk2,743, p99 121 µs, ×0.09
  9. AWS CodeBuild8 vCPUlarge · EBS565, p99 971 µs, ×0.02
  10. RunsOn8 vCPUm8a.2xlarge · EBS gp3 · nobarrier540, p99 987 µs, ×0.02

Fastest x64 8 vCPU synced writes: Namespace (28,934), 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. Warpbuild12 vCPUxfast (Apple M4 Pro) · VM disk29,545, p99 32 µs, ×1.00
  2. Blacksmith8 vCPUVM disk24,442, p99 38 µs, ×0.83
  3. Avrea2 vCPUVM disk21,199, p99 59 µs, ×0.72
  4. Namespace2 vCPUApple silicon 2x8 · VM disk20,079, p99 77 µs, ×0.68
  5. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,487, p99 81 µs, ×0.46
  6. Ubicloud4 vCPUstandard · VM disk9,977, p99 375 µs, ×0.34
  7. GitHub2 vCPUVM disk7,775, p99 216 µs, ×0.26
  8. RunsOn2 vCPUc8g.large · EBS gp31,816, p99 856 µs, ×0.06
  9. Warpbuild4 vCPUEBS1,812, p99 848 µs, ×0.06

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

Synced writesarm64 · 4k + fdatasync · IOPS, higher is better
  1. RunsOn8 vCPUm9gd.2xlarge · local NVMe17,484, p99 20 µs, ×1.00
  2. Warpbuild12 vCPUxfast (Apple M4 Pro) · VM disk · nobarrier9,400, p99 55 µs, ×0.54
  3. Blacksmith8 vCPUVM disk · nobarrier7,401, p99 64 µs, ×0.42
  4. Ubicloud8 vCPUstandard · VM disk · nobarrier4,597, p99 946 µs, ×0.26
  5. Namespace8 vCPU8x16 · VM disk4,026, p99 169 µs, ×0.23
  6. Avrea2 vCPUVM disk3,959, p99 120 µs, ×0.23
  7. GitHub2 vCPUVM disk · nobarrier3,100, p99 602 µs, ×0.18
  8. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 971 µs, ×0.03
  9. Warpbuild8 vCPUEBS · nobarrier540, p99 987 µs, ×0.03

Fastest arm64 synced writes: RunsOn m9gd.2xlarge · NVMe (17,484), ahead of Warpbuild (9,400).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,414, p99 42 µs, ×1.00
  2. Avrea2 vCPUVM disk21,199, p99 59 µs, ×0.91
  3. Namespace2 vCPUApple silicon 2x8 · VM disk20,079, p99 77 µs, ×0.86
  4. RunsOn2 vCPUm9gd.large · local NVMe13,480, p99 81 µs, ×0.58
  5. Ubicloud2 vCPUstandard · VM disk7,846, p99 510 µs, ×0.34
  6. GitHub2 vCPUVM disk7,775, p99 216 µs, ×0.33
  7. RunsOn2 vCPUc8g.large · EBS gp31,816, p99 856 µs, ×0.08
  8. Warpbuild2 vCPUEBS1,775, p99 905 µs, ×0.08

Fastest arm64 2 vCPU QD1 read: Blacksmith (23,414), ahead of Avrea (21,199).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,203, p99 46 µs, ×1.00
  2. Blacksmith2 vCPUVM disk · nobarrier6,627, p99 85 µs, ×0.92
  3. Ubicloud2 vCPUstandard · VM disk · nobarrier4,024, p99 1,004 µs, ×0.56
  4. Avrea2 vCPUVM disk3,959, p99 120 µs, ×0.55
  5. Namespace2 vCPU2x8 · VM disk3,695, p99 198 µs, ×0.51
  6. GitHub2 vCPUVM disk · nobarrier3,100, p99 602 µs, ×0.43
  7. RunsOn2 vCPUm9g.large · EBS gp3 · nobarrier542, p99 971 µs, ×0.08
  8. Warpbuild2 vCPUEBS · nobarrier539, p99 987 µs, ×0.07

Fastest arm64 2 vCPU synced writes: RunsOn m9gd.large · NVMe (7,203), ahead of Blacksmith (6,627).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,627, p99 44 µs, ×1.00
  2. Avrea4 vCPUVM disk19,824, p99 58 µs, ×0.84
  3. Namespace4 vCPUApple silicon 4x16 · VM disk18,972, p99 98 µs, ×0.80
  4. RunsOn4 vCPUm9gd.xlarge · local NVMe13,441, p99 85 µs, ×0.57
  5. Ubicloud4 vCPUstandard · VM disk9,977, p99 375 µs, ×0.42
  6. GitHub4 vCPUnetwork disk5,177, p99 247 µs, ×0.22
  7. Warpbuild4 vCPUEBS1,812, p99 848 µs, ×0.08
  8. RunsOn4 vCPUm9g.xlarge · EBS gp31,793, p99 930 µs, ×0.08

Fastest arm64 4 vCPU QD1 read: Blacksmith (23,627), ahead of Avrea (19,824).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,861, p99 23 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier7,023, p99 78 µs, ×0.47
  3. Namespace4 vCPU4x16 · VM disk3,943, p99 181 µs, ×0.27
  4. Avrea4 vCPUVM disk3,889, p99 55 µs, ×0.26
  5. Ubicloud4 vCPUstandard · VM disk · nobarrier3,419, p99 1,073 µs, ×0.23
  6. GitHub4 vCPUnetwork disk · nobarrier2,660, p99 305 µs, ×0.18
  7. RunsOn4 vCPUm9g.xlarge · EBS gp3 · nobarrier543, p99 995 µs, ×0.04
  8. Warpbuild4 vCPUEBS · nobarrier539, p99 979 µs, ×0.04

Fastest arm64 4 vCPU synced writes: RunsOn m9gd.xlarge · NVMe (14,861), 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,442, p99 38 µs, ×1.00
  2. Avrea8 vCPUVM disk20,797, p99 56 µs, ×0.85
  3. Namespace8 vCPU8x32 · VM disk16,939, p99 90 µs, ×0.69
  4. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,487, p99 81 µs, ×0.55
  5. Ubicloud8 vCPUstandard · VM disk9,282, p99 408 µs, ×0.38
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp31,812, p99 848 µs, ×0.07
  7. Warpbuild8 vCPUEBS1,779, p99 823 µs, ×0.07

Fastest arm64 8 vCPU QD1 read: Blacksmith (24,442), ahead of Avrea (20,797).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,484, p99 20 µs, ×1.00
  2. Blacksmith8 vCPUVM disk · nobarrier7,401, p99 64 µs, ×0.42
  3. Ubicloud8 vCPUstandard · VM disk · nobarrier4,597, p99 946 µs, ×0.26
  4. Namespace8 vCPU8x16 · VM disk4,026, p99 169 µs, ×0.23
  5. Avrea8 vCPUVM disk3,812, p99 56 µs, ×0.22
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 971 µs, ×0.03
  7. Warpbuild8 vCPUEBS · nobarrier540, p99 987 µs, ×0.03

Fastest arm64 8 vCPU synced writes: RunsOn m9gd.2xlarge · NVMe (17,484), 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 104,659 times a second on Namespace 2x8 and 1,506 on RunsOn m8i.large · EBS gp3, 69× apart; p99 latency is 10 µs against 1,036 µ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,105,180 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 (m8a.large, $0.0009); 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,506 and 1,822 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 29,545 times a second on Warpbuild xfast (Apple M4 Pro) 12 vCPU and 1,756 on RunsOn c8g.2xlarge · EBS gp3, 17× apart; p99 latency is 32 µs against 864 µs.
  • Synced 4k writes on arm64 run from 537 per second on RunsOn c8g.large · EBS gp3 (workspace mounted nobarrier) to 17,484 on RunsOn m9gd.2xlarge · local NVMe.
  • Same Xeon 6975P-C CPU, different disk: m8id.2xlarge on local NVMe answers 10,759 QD1 reads and 7,106 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,102 QD1 reads and 5,542 synced writes per second, m8i-flex.large on EBS gp3 1,683 and 532.
  • Same Xeon 6975P-C CPU, different disk: m8id.xlarge on local NVMe answers 10,971 QD1 reads and 8,057 synced writes per second, m8i-flex.xlarge on EBS gp3 1,740 and 527.
  • Same Neoverse-V3 CPU, different disk: m9gd.2xlarge on local NVMe answers 13,487 QD1 reads and 17,484 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,441 QD1 reads and 14,861 synced writes per second, m9g.xlarge on EBS gp3 1,793 and 543.
  • Same Neoverse-V3 CPU, different disk: m9gd.large on local NVMe answers 13,480 QD1 reads and 7,203 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 go (1,518 → 1,764 IOPS).
  • tmpfs on m8a.2xlarge is not a disk at all: 1,127,120 QD1 reads and 426,870 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs on m9g.2xlarge is not a disk at all: 653,094 QD1 reads and 299,229 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 302,931 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,150,238 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,153,799 QD1 reads and 433,121 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–433k synced writes per second across 8 runners (8 RunsOn configurations).
  • VM disk: 4.4k–105k 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–13k QD1 reads and 5.5k–17k synced writes per second across 9 runners (9 RunsOn configurations).
  • network disk: 5.2k–7.2k QD1 reads and 2.7k–4.2k 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 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
8x32 8 vCPU 32 GB VM disk EPYC · model hidden 104,083 10 µs 28,934 1,103,472 576,011 5.0 GiB/s 3.4 GiB/s
8x16 8 vCPU 16 GB VM disk EPYC · model hidden 77,171 12 µs 18,215 1,096,746 465,716 4.2 GiB/s 2.4 GiB/s
4x16 4 vCPU 16 GB VM disk EPYC · model hidden 101,308 11 µs 27,833 1,196,382 559,921 5.0 GiB/s 3.3 GiB/s
4x8 4 vCPU 8 GB VM disk EPYC · model hidden 76,727 13 µs 18,399 987,375 454,539 4.1 GiB/s 2.9 GiB/s
Blacksmith 2 vCPU 8 GB VM disk EPYC · model hidden nobarrier 76,132 15 µs 17,760 622,999 158,699 5.6 GiB/s 1.8 GiB/s
8 vCPU 8 vCPU 32 GB VM disk EPYC · model hidden nobarrier 55,275 19 µs 13,820 425,239 222,802 7.6 GiB/s 2.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC · model hidden nobarrier 70,530 16 µs 17,134 700,085 209,551 6.3 GiB/s 1.6 GiB/s
StarSling 8 vCPU 32 GB VM disk EPYC · model hidden 51,989 22 µs 17,805 289,806 70,106 5.2 GiB/s 4.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Xeon · model hidden volatile 41,156 25 µs 13,381 315,333 51,153 3.7 GiB/s 3.6 GiB/s
Avrea 8 vCPU 32 GB VM disk EPYC 4585PX nobarrier 50,590 19 µs 11,323 331,271 219,575 12.5 GiB/s 9.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC 4585PX nobarrier 49,995 16 µs 12,385 420,948 172,216 11.6 GiB/s 8.8 GiB/s
2 vCPU 2 vCPU 8 GB VM disk EPYC 4585PX nobarrier 50,427 16 µs 12,521 484,653 283,518 15.2 GiB/s 9.1 GiB/s
Warpbuild 8 vCPU 32 GB VM disk Ryzen 9 9950X 33,993 34 µs 2,743 141,309 57,088 4.4 GiB/s 3.2 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 9950X 29,556 53 µs 2,329 179,057 70,031 4.6 GiB/s 3.6 GiB/s
2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 9950X 22,485 60 µs 2,287 151,057 67,413 4.3 GiB/s 3.0 GiB/s
RunsOn i7i.2xlarge 8 vCPU 64 GB local NVMe Xeon 8559C 12,332 264 µs 11,692 300,467 165,110 2.0 GiB/s 1.5 GiB/s
m8azn.3xlarge 12 vCPU 48 GB EBS gp3 EPYC 9R05 nobarrier 1,779 889 µs 538 2,997 2,994 401 MiB/s 401 MiB/s
m8a.2xlarge 8 vCPU 32 GB EBS gp3 EPYC 9R45 nobarrier 1,677 872 µ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 889 µs 540 15,994 15,992 1,001 MiB/s 1,001 MiB/s
m8a.2xlarge 8 vCPU 32 GB tmpfs EPYC 9R45 1,127,120 <1 µs 426,870 4,232,110 3,820,879 18.5 GiB/s 9.9 GiB/s
r8a.2xlarge 8 vCPU 64 GB tmpfs EPYC 9R45 1,150,238 <1 µs 430,608 4,315,373 3,831,509 18.1 GiB/s 10.0 GiB/s
c8a.2xlarge 8 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,710 905 µs 539 2,994 2,991 401 MiB/s 401 MiB/s
m8azn.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R05 nobarrier 1,518 963 µs 542 2,994 2,991 401 MiB/s 401 MiB/s
m8azn.xlarge 4 vCPU 16 GB gp3 1000 MiB/s EPYC 9R05 nobarrier 1,764 823 µs 539 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,995 401 MiB/s 401 MiB/s
m8a.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,817 741 µs 540 2,994 2,992 401 MiB/s 401 MiB/s
m8id.2xlarge 8 vCPU 32 GB local NVMe Xeon 6975P-C 10,759 272 µs 7,106 134,252 67,076 905 MiB/s 432 MiB/s
m8i-flex.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,787 905 µs 515 2,992 2,995 401 MiB/s 401 MiB/s
c8a.xlarge 4 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,790 864 µs 540 2,994 2,991 401 MiB/s 401 MiB/s
r8a.xlarge 4 vCPU 32 GB tmpfs EPYC 9R45 1,153,799 <1 µs 433,121 4,276,584 3,832,030 18.1 GiB/s 10.1 GiB/s
m8azn.large 2 vCPU 8 GB EBS gp3 EPYC 9R05 nobarrier 1,822 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,971 224 µs 8,057 67,090 33,526 451 MiB/s 216 MiB/s
m8i-flex.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,740 897 µs 527 2,992 2,994 401 MiB/s 401 MiB/s
m8i.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,675 905 µs 519 2,992 2,993 401 MiB/s 401 MiB/s
i7i.xlarge 4 vCPU 32 GB local NVMe Xeon 8559C 11,028 261 µs 12,619 150,053 82,487 1,010 MiB/s 788 MiB/s
m8a.large 2 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,805 864 µ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 807 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
r8a.large 2 vCPU 16 GB tmpfs EPYC 9R45 1,105,180 <1 µs 428,125 2,149,284 1,943,726 17.7 GiB/s 10.1 GiB/s
c8a.large 2 vCPU 4 GB EBS gp3 EPYC 9R45 nobarrier 1,789 774 µs 541 2,995 2,992 401 MiB/s 401 MiB/s
m8id.large 2 vCPU 8 GB local NVMe Xeon 6975P-C 11,102 189 µs 5,542 33,541 16,753 226 MiB/s 108 MiB/s
m8i-flex.large 2 vCPU 8 GB EBS gp3 Xeon 6975P-C nobarrier 1,683 954 µs 532 2,993 2,993 401 MiB/s 401 MiB/s
m8i.large 2 vCPU 8 GB EBS gp3 Xeon 6975P-C nobarrier 1,506 1,036 µs 535 2,993 2,993 401 MiB/s 401 MiB/s
i7i.large 2 vCPU 16 GB local NVMe Xeon 8559C 11,951 293 µs 12,861 75,023 41,231 503 MiB/s 395 MiB/s
t8i.medium 2 vCPU 4 GB EBS gp3 Xeon 6975P-C nobarrier 1,736 864 µs 523 2,999 2,998 401 MiB/s 401 MiB/s
Ubicloud standard 4 vCPU 16 GB VM disk EPYC 9454 nobarrier 9,597 379 µs 1,826 188,948 26,731 2.6 GiB/s 553 MiB/s
standard 8 vCPU 8 vCPU 32 GB VM disk EPYC 9454P nobarrier 9,075 469 µs 1,846 211,320 20,376 2.2 GiB/s 744 MiB/s
premium 8 vCPU 8 vCPU 32 GB VM disk Ryzen 9 7950X3D nobarrier 9,253 326 µs 2,822 292,912 19,429 3.0 GiB/s 1.4 GiB/s
premium 4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 7950X3D nobarrier 7,441 1,253 µs 1,414 258,030 23,853 2.1 GiB/s 909 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk EPYC 9454P nobarrier 6,569 1,045 µs 691 125,230 19,627 2.5 GiB/s 1.0 GiB/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.4 GiB/s 857 MiB/s
GitHub 8 vCPU 32 GB VM disk Xeon 6973P-C nobarrier 7,870 239 µs 3,710 38,977 20,168 784 MiB/s 784 MiB/s
4-core 4 vCPU 16 GB network disk EPYC 9V45 nobarrier 7,216 297 µs 4,203 19,577 10,264 394 MiB/s 245 MiB/s
2-core 2 vCPU 8 GB VM disk EPYC 7763 nobarrier 6,868 272 µs 3,862 9,382 9,112 199 MiB/s 199 MiB/s
AWS CodeBuild small 2 vCPU 3 GB EBS Xeon 8488C 1,761 709 µs 571 2,989 2,971 248 MiB/s 251 MiB/s
large 8 vCPU 16 GB EBS Xeon 8488C 1,757 692 µs 565 2,987 2,977 248 MiB/s 251 MiB/s
medium 4 vCPU 8 GB EBS Xeon 8488C 1,760 684 µs 566 2,990 2,974 253 MiB/s 251 MiB/s
arm6436 runners, 7 providers
Warpbuild xfast (Apple M4 Pro) 12 vCPU 28 GB VM disk nobarrier 29,545 32 µs 9,400 384,762 5,596 11.5 GiB/s 10.5 GiB/s
xfast (Apple M4 Pro) 6 vCPU 6 vCPU 14 GB VM disk nobarrier 29,080 56 µs 8,864 347,190 4,902 12.6 GiB/s 12.4 GiB/s
8 vCPU 8 vCPU 32 GB EBS Neoverse-V2 nobarrier 1,779 823 µs 540 4,994 4,994 401 MiB/s 401 MiB/s
4 vCPU 4 vCPU 16 GB EBS Neoverse-V2 nobarrier 1,812 848 µs 539 4,194 4,193 302 MiB/s 302 MiB/s
2 vCPU 2 vCPU 8 GB EBS Neoverse-V2 nobarrier 1,775 905 µs 539 4,193 4,194 302 MiB/s 301 MiB/s
Blacksmith 8 vCPU 32 GB VM disk Ampere-1a nobarrier 24,442 38 µs 7,401 220,885 26,756 1.7 GiB/s 781 MiB/s
4 vCPU 4 vCPU 16 GB VM disk Ampere-1a nobarrier 23,627 44 µs 7,023 153,065 24,783 1.6 GiB/s 828 MiB/s
2 vCPU 2 vCPU 6 GB VM disk Ampere-1a nobarrier 23,414 42 µs 6,627 73,977 26,895 1.7 GiB/s 797 MiB/s
Avrea 2 vCPU 8 GB VM disk Apple M5 Max · as stated by the provider 21,199 59 µs 3,959 150,825 18,394 34.1 GiB/s 14.9 GiB/s
8 vCPU 8 vCPU 32 GB VM disk Apple M5 Max · as stated by the provider 20,797 56 µs 3,812 141,694 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,824 58 µs 3,889 146,545 15,117 39.9 GiB/s 16.0 GiB/s
Namespace Apple silicon 2x8 2 vCPU 8 GB VM disk CPU not reported 20,079 77 µs 3,602 158,843 14,215 30.6 GiB/s 14.9 GiB/s
Apple silicon 4x16 4 vCPU 16 GB VM disk CPU not reported 18,972 98 µs 3,485 139,782 21,805 32.7 GiB/s 12.0 GiB/s
8x16 8 vCPU 16 GB VM disk Ampere-1a 16,122 100 µs 4,026 182,900 31,064 913 MiB/s 700 MiB/s
8x32 8 vCPU 32 GB VM disk Ampere-1a 16,939 90 µs 4,001 184,768 28,671 918 MiB/s 767 MiB/s
4x16 4 vCPU 16 GB VM disk Ampere-1a 16,821 92 µs 3,943 147,360 40,493 943 MiB/s 732 MiB/s
4x8 4 vCPU 8 GB VM disk Ampere-1a 16,654 94 µs 3,874 143,176 43,292 951 MiB/s 661 MiB/s
2x8 2 vCPU 8 GB VM disk Ampere-1a 15,941 97 µs 3,695 72,899 26,107 905 MiB/s 742 MiB/s
RunsOn m9gd.2xlarge 8 vCPU 32 GB local NVMe Neoverse-V3 13,487 81 µs 17,484 174,573 87,207 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 653,094 <1 µs 299,229 2,614,999 2,502,932 13.3 GiB/s 9.0 GiB/s
c8g.2xlarge 8 vCPU 16 GB EBS gp3 Neoverse-V2 nobarrier 1,756 864 µs 539 2,994 2,993 401 MiB/s 401 MiB/s
m9gd.xlarge 4 vCPU 16 GB local NVMe Neoverse-V3 13,441 85 µs 14,861 87,221 43,584 585 MiB/s 281 MiB/s
m9g.xlarge 4 vCPU 16 GB EBS gp3 Neoverse-V3 nobarrier 1,793 930 µs 543 2,994 2,991 401 MiB/s 401 MiB/s
m9g.xlarge 4 vCPU 16 GB tmpfs Neoverse-V3 673,423 <1 µs 302,931 2,725,463 2,524,280 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 930 µs 538 2,992 2,994 401 MiB/s 401 MiB/s
m9gd.large 2 vCPU 8 GB local NVMe Neoverse-V3 13,480 81 µs 7,203 43,609 21,782 293 MiB/s 141 MiB/s
m9g.large 2 vCPU 8 GB EBS gp3 Neoverse-V3 nobarrier 1,789 864 µs 542 2,993 2,995 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,816 856 µs 537 2,994 2,992 401 MiB/s 401 MiB/s
Ubicloud standard 4 vCPU 16 GB VM disk Neoverse-N1 nobarrier 9,977 375 µs 3,419 159,875 35,176 777 MiB/s 394 MiB/s
standard 8 vCPU 8 vCPU 32 GB VM disk Neoverse-N1 nobarrier 9,282 408 µs 4,597 241,605 112,271 818 MiB/s 503 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk Neoverse-N1 nobarrier 7,846 510 µs 4,024 108,266 61,472 780 MiB/s 481 MiB/s
GitHub 2 vCPU 8 GB VM disk Neoverse-N2 nobarrier 7,775 216 µs 3,100 9,376 6,317 199 MiB/s 164 MiB/s
4-core 4 vCPU 16 GB network disk Neoverse-N2 nobarrier 5,177 247 µs 2,660 19,576 12,560 394 MiB/s 313 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.