quickstart →

Fastest GitHub Actions runners: disk I/O.

fio inside the job workspace of 94 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,808 Namespace 4x8 (4 vCPU) · reads/s
Fastest QD1 read, arm64 at 4 vCPU 32,691 Blacksmith 4 vCPU · reads/s
GitHub at 4 vCPU 7,332 x64 QD1 reads/s on GitHub 4-core
Fastest synced writes, x64 at 4 vCPU 30,012 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 disk107,149, p99 10 µs, ×1.00
  2. Blacksmith2 vCPUVM disk76,132, p99 15 µs, ×0.71
  3. Avrea8 vCPUVM disk52,645, p99 19 µs, ×0.49
  4. Warpbuild8 vCPUVM disk37,153, p99 29 µs, ×0.35
  5. RunsOn2 vCPUi7i.large · local NVMe12,510, p99 285 µs, ×0.12
  6. boat2 vCPUVM disk10,783, p99 206 µs, ×0.10
  7. Ubicloud8 vCPUpremium · VM disk8,023, p99 684 µs, ×0.07
  8. GitHub8 vCPUVM disk7,499, p99 239 µs, ×0.07
  9. RunsOn12 vCPUm8azn.3xlarge · EBS gp31,821, p99 840 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,794, p99 733 µs, ×0.02

Fastest x64 QD1 read: Namespace (107,149), ahead of Blacksmith (76,132).tmpfs for scale: 1,153,982 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 · 4k + fdatasync · IOPS, higher is better
  1. Namespace4 vCPU4x8 · VM disk30,012, p99 14 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier18,263, p99 24 µs, ×0.61
  3. RunsOn2 vCPUi7i.large · local NVMe12,959, p99 33 µs, ×0.43
  4. Avrea2 vCPUVM disk · nobarrier12,808, p99 28 µs, ×0.43
  5. GitHub4 vCPUnetwork disk · nobarrier4,203, p99 247 µs, ×0.14
  6. Warpbuild8 vCPUVM disk2,743, p99 105 µs, ×0.09
  7. Ubicloud4 vCPUpremium · VM disk · nobarrier2,598, p99 2,146 µs, ×0.09
  8. boat2 vCPUVM disk2,355, p99 273 µs, ×0.08
  9. AWS CodeBuild2 vCPUsmall · EBS571, p99 995 µs, ×0.02
  10. RunsOn2 vCPUm8azn.large · EBS gp3 · nobarrier542, p99 963 µs, ×0.02

Fastest x64 synced writes: Namespace (30,012), ahead of Blacksmith (18,263).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 disk52,438, p99 14 µs, ×0.50
  4. Warpbuild2 vCPUVM disk22,485, p99 60 µs, ×0.21
  5. RunsOn2 vCPUi7i.large · local NVMe12,510, p99 285 µs, ×0.12
  6. boat2 vCPUVM disk10,783, p99 206 µs, ×0.10
  7. GitHub2 vCPUVM disk6,868, p99 272 µs, ×0.07
  8. Ubicloud2 vCPUstandard · VM disk6,767, p99 1,122 µs, ×0.06
  9. RunsOn2 vCPUc8a.large · EBS gp31,809, p99 741 µs, ×0.02
  10. AWS CodeBuild2 vCPUsmall · EBS1,761, p99 791 µs, ×0.02

Fastest x64 2 vCPU QD1 read: Namespace (104,659), ahead of Blacksmith (76,132).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 disk28,582, p99 14 µs, ×1.00
  2. Blacksmith2 vCPUVM disk · nobarrier17,760, p99 28 µs, ×0.62
  3. RunsOn2 vCPUi7i.large · local NVMe12,959, p99 33 µs, ×0.45
  4. Avrea2 vCPUVM disk · nobarrier12,808, p99 28 µs, ×0.45
  5. GitHub2 vCPUVM disk · nobarrier3,862, p99 212 µs, ×0.14
  6. boat2 vCPUVM disk2,355, p99 273 µs, ×0.08
  7. Warpbuild2 vCPUVM disk2,287, p99 67 µs, ×0.08
  8. Ubicloud2 vCPUpremium · VM disk · nobarrier1,491, p99 3,654 µs, ×0.05
  9. AWS CodeBuild2 vCPUsmall · EBS571, p99 995 µs, ×0.02
  10. RunsOn2 vCPUm8azn.large · EBS gp3 · nobarrier542, p99 963 µs, ×0.02

Fastest x64 2 vCPU synced writes: Namespace (28,582), 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 vCPU4x8 · VM disk105,808, p99 10 µs, ×1.00
  2. Blacksmith4 vCPUVM disk72,739, p99 16 µs, ×0.69
  3. Avrea4 vCPUVM disk49,995, p99 21 µs, ×0.47
  4. Warpbuild4 vCPUVM disk31,288, p99 40 µs, ×0.30
  5. RunsOn4 vCPUi7i.xlarge · local NVMe11,384, p99 261 µs, ×0.11
  6. boat4 vCPUVM disk9,981, p99 331 µs, ×0.09
  7. Ubicloud4 vCPUstandard · VM disk7,982, p99 528 µs, ×0.08
  8. GitHub4 vCPUnetwork disk7,332, p99 255 µs, ×0.07
  9. RunsOn4 vCPUm8a.xlarge · EBS gp31,820, p99 799 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,794, p99 733 µs, ×0.02

Fastest x64 4 vCPU QD1 read: Namespace (105,808), ahead of Blacksmith (72,739).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 disk30,012, p99 14 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier18,263, p99 24 µs, ×0.61
  3. RunsOn4 vCPUi7i.xlarge · local NVMe12,590, p99 33 µs, ×0.42
  4. Avrea4 vCPUVM disk · nobarrier12,385, p99 31 µs, ×0.41
  5. GitHub4 vCPUnetwork disk · nobarrier4,203, p99 247 µs, ×0.14
  6. Ubicloud4 vCPUpremium · VM disk · nobarrier2,598, p99 2,146 µs, ×0.09
  7. Warpbuild4 vCPUVM disk2,542, p99 100 µs, ×0.08
  8. boat4 vCPUVM disk1,824, p99 1,100 µs, ×0.06
  9. AWS CodeBuild4 vCPUmedium · EBS566, p99 987 µs, ×0.02
  10. RunsOn4 vCPUm8azn.xlarge · EBS gp3 · nobarrier541, p99 995 µs, ×0.02

Fastest x64 4 vCPU synced writes: Namespace (30,012), ahead of Blacksmith (18,263).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 disk107,149, p99 10 µs, ×1.00
  2. Blacksmith8 vCPUVM disk67,311, p99 19 µs, ×0.63
  3. Avrea8 vCPUVM disk52,645, p99 19 µs, ×0.49
  4. Warpbuild8 vCPUVM disk37,153, p99 29 µs, ×0.35
  5. RunsOn8 vCPUi7i.2xlarge · local NVMe11,113, p99 346 µs, ×0.10
  6. boat8 vCPUVM disk8,179, p99 569 µs, ×0.08
  7. Ubicloud8 vCPUpremium · VM disk8,023, p99 684 µs, ×0.07
  8. GitHub8 vCPUVM disk7,499, p99 239 µs, ×0.07
  9. RunsOn8 vCPUc8a.2xlarge · EBS gp31,812, p99 897 µs, ×0.02
  10. AWS CodeBuild8 vCPUlarge · EBS1,758, p99 725 µs, ×0.02

Fastest x64 8 vCPU QD1 read: Namespace (107,149), ahead of Blacksmith (67,311).tmpfs for scale: 1,153,982 on RunsOn r8a.2xlarge · tmpfs.

Synced writesx64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace8 vCPU8x32 · VM disk28,934, p99 14 µs, ×1.00
  2. Blacksmith8 vCPUVM disk · nobarrier17,257, p99 26 µs, ×0.60
  3. RunsOn8 vCPUi7i.2xlarge · local NVMe11,586, p99 40 µs, ×0.40
  4. Avrea8 vCPUVM disk · nobarrier11,150, p99 45 µs, ×0.39
  5. GitHub8 vCPUVM disk · nobarrier3,937, p99 261 µs, ×0.14
  6. Warpbuild8 vCPUVM disk2,743, p99 105 µs, ×0.09
  7. Ubicloud8 vCPUpremium · VM disk · nobarrier2,573, p99 1,991 µs, ×0.09
  8. boat8 vCPUVM disk1,062, p99 1,193 µs, ×0.04
  9. AWS CodeBuild8 vCPUlarge · EBS566, p99 979 µs, ×0.02
  10. RunsOn8 vCPUc8a.2xlarge · EBS gp3 · nobarrier540, p99 1,004 µs, ×0.02

Fastest x64 8 vCPU synced writes: Namespace (28,934), ahead of Blacksmith (17,257).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. Blacksmith4 vCPUVM disk32,691, p99 37 µs, ×1.00
  2. Warpbuild6 vCPUxfast (Apple M4 Pro) · VM disk30,673, p99 40 µs, ×0.94
  3. Avrea2 vCPUVM disk20,971, p99 60 µs, ×0.64
  4. Namespace2 vCPUApple silicon 2x8 · VM disk19,957, p99 77 µs, ×0.61
  5. RunsOn2 vCPUm9gd.large · local NVMe13,533, p99 81 µs, ×0.41
  6. Ubicloud8 vCPUstandard · VM disk9,282, p99 408 µs, ×0.28
  7. GitHub2 vCPUVM disk8,119, p99 214 µs, ×0.25
  8. RunsOn4 vCPUm9g.xlarge · EBS gp31,822, p99 856 µs, ×0.06
  9. Warpbuild4 vCPUEBS1,812, p99 848 µs, ×0.06

Fastest arm64 QD1 read: Blacksmith (32,691), ahead of Warpbuild (30,673).tmpfs for scale: 669,005 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. Blacksmith4 vCPUVM disk · nobarrier9,201, p99 69 µs, ×0.53
  4. Namespace8 vCPU8x16 · VM disk4,157, p99 167 µs, ×0.24
  5. Ubicloud2 vCPUstandard · VM disk · nobarrier4,024, p99 1,004 µs, ×0.23
  6. Avrea2 vCPUVM disk3,909, p99 120 µs, ×0.22
  7. GitHub2 vCPUVM disk · nobarrier3,110, p99 651 µs, ×0.18
  8. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 987 µs, ×0.03
  9. Warpbuild8 vCPUEBS · nobarrier539, p99 987 µ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 disk31,028, p99 39 µs, ×1.00
  2. Avrea2 vCPUVM disk20,971, p99 60 µs, ×0.68
  3. Namespace2 vCPUApple silicon 2x8 · VM disk19,957, p99 77 µs, ×0.64
  4. RunsOn2 vCPUm9gd.large · local NVMe13,533, p99 81 µs, ×0.44
  5. GitHub2 vCPUVM disk8,119, p99 214 µs, ×0.26
  6. Ubicloud2 vCPUstandard · VM disk7,846, p99 510 µs, ×0.25
  7. RunsOn2 vCPUm9g.large · EBS gp31,789, p99 848 µs, ×0.06
  8. Warpbuild2 vCPUEBS1,777, p99 840 µs, ×0.06

Fastest arm64 2 vCPU QD1 read: Blacksmith (31,028), ahead of Avrea (20,971).tmpfs for scale: 669,005 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 2 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Blacksmith2 vCPUVM disk · nobarrier8,442, p99 71 µs, ×1.00
  2. RunsOn2 vCPUm9gd.large · local NVMe7,267, p99 49 µs, ×0.86
  3. Ubicloud2 vCPUstandard · VM disk · nobarrier4,024, p99 1,004 µs, ×0.48
  4. Avrea2 vCPUVM disk3,909, p99 120 µs, ×0.46
  5. Namespace2 vCPUApple silicon 2x8 · VM disk3,725, p99 101 µs, ×0.44
  6. GitHub2 vCPUVM disk · nobarrier3,110, p99 651 µs, ×0.37
  7. RunsOn2 vCPUm9g.large · EBS gp3 · nobarrier542, p99 971 µs, ×0.06
  8. Warpbuild2 vCPUEBS · nobarrier538, p99 987 µs, ×0.06

Fastest arm64 2 vCPU synced writes: Blacksmith (8,442), ahead of RunsOn m9gd.large · NVMe (7,267).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 disk32,691, p99 37 µs, ×1.00
  2. Avrea4 vCPUVM disk19,824, p99 58 µs, ×0.61
  3. Namespace4 vCPUApple silicon 4x16 · VM disk18,901, p99 105 µs, ×0.58
  4. RunsOn4 vCPUm9gd.xlarge · local NVMe13,382, p99 116 µs, ×0.41
  5. Ubicloud4 vCPUstandard · VM disk8,334, p99 498 µs, ×0.25
  6. GitHub4 vCPUnetwork disk5,893, p99 228 µs, ×0.18
  7. RunsOn4 vCPUm9g.xlarge · EBS gp31,822, p99 856 µs, ×0.06
  8. Warpbuild4 vCPUEBS1,812, p99 848 µs, ×0.06

Fastest arm64 4 vCPU QD1 read: Blacksmith (32,691), ahead of Avrea (19,824).tmpfs for scale: 669,005 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn4 vCPUm9gd.xlarge · local NVMe14,861, p99 24 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier9,201, p99 69 µs, ×0.62
  3. Avrea4 vCPUVM disk3,870, p99 56 µs, ×0.26
  4. Namespace4 vCPU4x16 · VM disk3,870, p99 177 µs, ×0.26
  5. Ubicloud4 vCPUstandard · VM disk · nobarrier3,419, p99 1,073 µs, ×0.23
  6. GitHub4 vCPUnetwork disk · nobarrier2,931, p99 289 µs, ×0.20
  7. RunsOn4 vCPUm9g.xlarge · EBS gp3 · nobarrier543, p99 1,073 µs, ×0.04
  8. Warpbuild4 vCPUEBS · nobarrier539, p99 995 µs, ×0.04

Fastest arm64 4 vCPU synced writes: RunsOn m9gd.xlarge · NVMe (14,861), ahead of Blacksmith (9,201).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 disk28,610, p99 37 µs, ×1.00
  2. Avrea8 vCPUVM disk20,797, p99 56 µs, ×0.73
  3. Namespace8 vCPU8x32 · VM disk16,635, p99 91 µs, ×0.58
  4. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,446, p99 84 µs, ×0.47
  5. Ubicloud8 vCPUstandard · VM disk9,282, p99 408 µs, ×0.32
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp31,812, p99 848 µs, ×0.06
  7. Warpbuild8 vCPUEBS1,781, p99 823 µs, ×0.06

Fastest arm64 8 vCPU QD1 read: Blacksmith (28,610), ahead of Avrea (20,797).tmpfs for scale: 669,005 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 · nobarrier9,092, p99 60 µs, ×0.52
  3. Namespace8 vCPU8x16 · VM disk4,157, p99 167 µs, ×0.24
  4. Ubicloud8 vCPUstandard · VM disk · nobarrier3,791, p99 946 µs, ×0.22
  5. Avrea8 vCPUVM disk3,729, p99 58 µs, ×0.21
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 987 µs, ×0.03
  7. Warpbuild8 vCPUEBS · nobarrier539, p99 987 µs, ×0.03

Fastest arm64 8 vCPU synced writes: RunsOn m9gd.2xlarge · NVMe (17,416), ahead of Blacksmith (9,092).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 107,149 times a second on Namespace 8x16 and 1,430 on RunsOn m8a.2xlarge · EBS gp3, 75× apart; p99 latency is 10 µs against 995 µs.
  • Synced 4k writes on x64 run from 487 per second on RunsOn m8i.2xlarge · EBS gp3 (workspace mounted nobarrier) to 30,012 on Namespace 4x8.
  • 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.0009); its workspace is 14 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 32,691 times a second on Blacksmith 4 vCPU and 1,777 on Warpbuild 2 vCPU, 18× apart; p99 latency is 37 µs against 840 µ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 10,966 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,102 QD1 reads and 5,555 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,878 QD1 reads and 7,930 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,446 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,861 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,648 → 1,771 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: 653,126 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: 669,005 QD1 reads and 304,088 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,102,306 QD1 reads and 433,841 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs on r9g.large is not a disk at all: 651,023 QD1 reads and 297,673 synced writes per second, from RAM. The workspace is 14 GiB, sized by memory.
  • tmpfs on r9g.xlarge is not a disk at all: 642,690 QD1 reads and 302,278 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs: 643k–1.2M QD1 reads and 298k–434k synced writes per second across 8 runners (8 RunsOn configurations).
  • VM disk: 5.3k–107k QD1 reads and 806–30k synced writes per second across 44 runners from 7 providers (6 Avrea runners, 6 Blacksmith runners, 3 boat x64 runners, 3 GitHub runners, 12 Namespace runners, 9 Ubicloud runners and 5 Warpbuild runners).
  • local NVMe: 11k–14k QD1 reads and 5.6k–17k synced writes per second across 9 runners (9 RunsOn configurations).
  • network disk: 5.9k–7.3k QD1 reads and 2.9k–4.2k synced writes per second across 2 runners (2 GitHub runners).
  • EBS: 1.4k–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 ↑
x6458 runners, 9 providers
Namespace 8x16 8 vCPU 16 GB VM disk EPYC · model hidden 107,149 10 µs 26,611 908,730 548,767 4.3 GiB/s 2.8 GiB/s
8x32 8 vCPU 32 GB VM disk EPYC · model hidden 104,251 10 µs 28,934 1,095,135 563,499 5.0 GiB/s 3.4 GiB/s
4x16 4 vCPU 16 GB VM disk EPYC · model hidden 105,050 11 µs 28,631 1,205,486 568,824 5.0 GiB/s 3.4 GiB/s
4x8 4 vCPU 8 GB VM disk EPYC · model hidden 105,808 10 µs 30,012 1,208,861 603,259 5.0 GiB/s 3.4 GiB/s
2x8 2 vCPU 8 GB VM disk EPYC · model hidden 104,659 10 µs 28,582 802,042 544,907 4.4 GiB/s 2.9 GiB/s
Blacksmith 2 vCPU 8 GB VM disk EPYC · model hidden nobarrier 76,132 15 µs 17,760 783,458 174,903 5.3 GiB/s 2.2 GiB/s
8 vCPU 8 vCPU 32 GB VM disk EPYC · model hidden nobarrier 67,311 19 µs 17,257 425,239 222,802 5.9 GiB/s 2.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC · model hidden nobarrier 72,739 16 µs 18,263 746,571 220,196 6.6 GiB/s 1.6 GiB/s
Avrea 8 vCPU 32 GB VM disk EPYC 4585PX nobarrier 52,645 19 µs 11,150 331,271 203,674 16.5 GiB/s 11.3 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC 4585PX nobarrier 49,995 21 µs 12,385 451,829 219,963 15.7 GiB/s 10.8 GiB/s
2 vCPU 2 vCPU 8 GB VM disk EPYC 4585PX nobarrier 52,438 14 µs 12,808 553,778 261,987 15.9 GiB/s 10.3 GiB/s
Warpbuild 8 vCPU 32 GB VM disk Ryzen 9 9950X 37,153 29 µs 2,743 191,815 67,698 4.4 GiB/s 3.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 9950X 31,288 40 µs 2,542 210,099 78,934 4.3 GiB/s 3.1 GiB/s
2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 9950X 22,485 60 µs 2,287 204,864 88,324 4.2 GiB/s 2.7 GiB/s
RunsOn i7i.large 2 vCPU 16 GB local NVMe Xeon 8559C 12,510 285 µs 12,959 75,023 41,231 503 MiB/s 395 MiB/s
m8azn.3xlarge 12 vCPU 48 GB EBS gp3 EPYC 9R05 nobarrier 1,821 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,812 897 µs 540 2,995 2,991 401 MiB/s 401 MiB/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
m8a.2xlarge 8 vCPU 32 GB gp3 1000 MiB/s EPYC 9R45 nobarrier 1,772 807 µs 540 15,994 15,991 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,310,049 3,831,509 18.4 GiB/s 10.0 GiB/s
m8a.2xlarge 8 vCPU 32 GB EBS gp3 EPYC 9R45 nobarrier 1,430 995 µs 540 2,995 2,991 401 MiB/s 401 MiB/s
m8azn.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R05 nobarrier 1,648 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,771 823 µs 541 15,994 15,991 1,001 MiB/s 1,001 MiB/s
m8i.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,580 1,020 µs 487 2,993 2,993 401 MiB/s 401 MiB/s
m8id.2xlarge 8 vCPU 32 GB local NVMe Xeon 6975P-C 10,966 247 µs 7,472 134,257 67,076 905 MiB/s 432 MiB/s
m8i-flex.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,785 954 µs 519 2,992 2,995 401 MiB/s 401 MiB/s
m8a.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,820 799 µs 540 2,994 2,991 401 MiB/s 401 MiB/s
c8a.xlarge 4 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,733 938 µs 541 2,994 2,991 401 MiB/s 401 MiB/s
i7i.2xlarge 8 vCPU 64 GB local NVMe Xeon 8559C 11,113 346 µs 11,586 300,466 165,110 2.0 GiB/s 1.5 GiB/s
r8a.xlarge 4 vCPU 32 GB tmpfs EPYC 9R45 1,102,306 <1 µs 433,841 4,201,526 3,800,170 17.8 GiB/s 9.9 GiB/s
m8azn.large 2 vCPU 8 GB EBS gp3 EPYC 9R05 nobarrier 1,782 758 µs 542 2,994 2,992 401 MiB/s 401 MiB/s
m8id.xlarge 4 vCPU 16 GB local NVMe Xeon 6975P-C 10,878 247 µs 7,930 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,658 995 µs 517 2,993 2,993 401 MiB/s 401 MiB/s
i7i.xlarge 4 vCPU 32 GB local NVMe Xeon 8559C 11,384 261 µs 12,590 150,053 82,487 1,010 MiB/s 788 MiB/s
m8a.large 2 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,734 872 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
r8a.large 2 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,778 856 µs 541 2,995 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,149,284 1,933,449 18.3 GiB/s 10.0 GiB/s
c8a.large 2 vCPU 4 GB EBS gp3 EPYC 9R45 nobarrier 1,809 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,102 167 µs 5,555 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,994 401 MiB/s 401 MiB/s
m8i-flex.large 2 vCPU 8 GB EBS gp3 Xeon 6975P-C nobarrier 1,767 889 µs 528 2,993 2,994 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,998 401 MiB/s 401 MiB/s
boat 2 vCPU 4 GB VM disk Ryzen 7 9700X 10,783 206 µs 2,355 466,442 165,954 10.5 GiB/s 892 MiB/s
8 vCPU 8 vCPU 16 GB VM disk Ryzen 9 9950X 8,179 569 µs 1,062 294,651 66,127 7.4 GiB/s 1,000 MiB/s
4 vCPU 4 vCPU 8 GB VM disk Ryzen 9 9950X 9,981 331 µs 1,824 406,699 99,819 9.7 GiB/s 1.1 GiB/s
Ubicloud premium 8 vCPU 32 GB VM disk Ryzen 9 7950X3D nobarrier 8,023 684 µs 2,573 274,211 19,507 2.9 GiB/s 735 MiB/s
standard 8 vCPU 8 vCPU 32 GB VM disk EPYC 9454P nobarrier 7,548 856 µs 1,921 255,065 20,376 2.3 GiB/s 923 MiB/s
standard 4 vCPU 4 vCPU 16 GB VM disk EPYC 9454P nobarrier 7,982 528 µs 1,826 188,948 21,529 2.5 GiB/s 694 MiB/s
premium 4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 7950X3D nobarrier 7,801 725 µs 2,598 228,178 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,122 µs 806 127,031 19,627 2.5 GiB/s 793 MiB/s
premium 2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 7950X3D nobarrier 5,289 2,114 µs 1,491 116,012 23,536 2.6 GiB/s 857 MiB/s
GitHub 8 vCPU 32 GB VM disk Xeon 8370C nobarrier 7,499 239 µs 3,937 38,975 18,243 784 MiB/s 545 MiB/s
4-core 4 vCPU 16 GB network disk EPYC 9V74 nobarrier 7,332 255 µs 4,203 19,574 10,796 394 MiB/s 245 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,794 733 µs 566 2,991 2,974 241 MiB/s 251 MiB/s
large 8 vCPU 16 GB EBS Xeon 8488C 1,758 725 µs 566 2,988 2,977 243 MiB/s 251 MiB/s
small 2 vCPU 3 GB EBS Xeon 8488C 1,761 791 µs 571 2,989 2,972 251 MiB/s 251 MiB/s
arm6436 runners, 7 providers
Blacksmith 4 vCPU 16 GB VM disk Ampere-1a nobarrier 32,691 37 µs 9,201 249,846 35,425 1.6 GiB/s 831 MiB/s
8 vCPU 8 vCPU 32 GB VM disk Ampere-1a nobarrier 28,610 37 µs 9,092 248,393 28,043 1.7 GiB/s 781 MiB/s
2 vCPU 2 vCPU 6 GB VM disk Ampere-1a nobarrier 31,028 39 µs 8,442 252,404 36,713 1.7 GiB/s 857 MiB/s
Warpbuild xfast (Apple M4 Pro) 6 vCPU 14 GB VM disk nobarrier 30,673 40 µs 9,790 376,960 5,311 11.7 GiB/s 10.7 GiB/s
xfast (Apple M4 Pro) 12 vCPU 12 vCPU 28 GB VM disk nobarrier 30,396 33 µs 9,355 384,762 5,596 10.5 GiB/s 11.1 GiB/s
8 vCPU 8 vCPU 32 GB EBS Neoverse-V2 nobarrier 1,781 823 µs 539 4,995 4,993 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,777 840 µs 538 4,194 4,194 302 MiB/s 301 MiB/s
Avrea 2 vCPU 8 GB VM disk Apple M5 Max · as stated by the provider 20,971 60 µs 3,909 151,990 18,394 34.1 GiB/s 14.8 GiB/s
8 vCPU 8 vCPU 32 GB VM disk Apple M5 Max · as stated by the provider 20,797 56 µs 3,729 143,275 12,897 47.5 GiB/s 16.0 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Apple M5 Max · as stated by the provider 19,824 58 µs 3,870 149,169 15,117 39.9 GiB/s 15.8 GiB/s
Namespace Apple silicon 2x8 2 vCPU 8 GB VM disk CPU not reported 19,957 77 µs 3,725 150,754 15,029 30.6 GiB/s 11.7 GiB/s
Apple silicon 4x16 4 vCPU 16 GB VM disk CPU not reported 18,901 105 µs 3,308 145,281 21,805 32.4 GiB/s 12.7 GiB/s
8x32 8 vCPU 32 GB VM disk Ampere-1a 16,635 91 µs 3,843 185,101 45,666 920 MiB/s 769 MiB/s
8x16 8 vCPU 16 GB VM disk Ampere-1a 16,609 95 µs 4,157 183,519 36,033 926 MiB/s 700 MiB/s
4x8 4 vCPU 8 GB VM disk Ampere-1a 16,613 94 µs 3,829 142,059 34,657 943 MiB/s 628 MiB/s
4x16 4 vCPU 16 GB VM disk Ampere-1a 16,425 96 µs 3,870 146,800 31,796 928 MiB/s 657 MiB/s
2x8 2 vCPU 8 GB VM disk Ampere-1a 15,941 103 µs 3,704 77,677 25,565 924 MiB/s 672 MiB/s
RunsOn m9gd.large 2 vCPU 8 GB local NVMe Neoverse-V3 13,533 81 µs 7,267 43,609 21,783 293 MiB/s 141 MiB/s
m9gd.2xlarge 8 vCPU 32 GB local NVMe Neoverse-V3 13,446 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,992 401 MiB/s 401 MiB/s
m9g.2xlarge 8 vCPU 32 GB tmpfs Neoverse-V3 653,126 <1 µs 300,362 2,615,018 2,495,107 13.3 GiB/s 9.1 GiB/s
c8g.2xlarge 8 vCPU 16 GB EBS gp3 Neoverse-V2 nobarrier 1,779 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 116 µs 14,861 87,221 43,589 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
r9g.xlarge 4 vCPU 32 GB tmpfs Neoverse-V3 642,690 <1 µs 302,278 2,611,352 2,491,994 13.8 GiB/s 8.9 GiB/s
m9g.xlarge 4 vCPU 16 GB tmpfs Neoverse-V3 669,005 <1 µs 304,088 2,695,794 2,522,498 14.7 GiB/s 9.4 GiB/s
c8g.xlarge 4 vCPU 8 GB EBS gp3 Neoverse-V2 nobarrier 1,796 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 848 µs 542 2,993 2,994 401 MiB/s 401 MiB/s
r9g.large 2 vCPU 16 GB tmpfs Neoverse-V3 651,023 <1 µs 297,673 1,277,313 1,235,007 13.8 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 3,791 241,173 112,271 748 MiB/s 503 MiB/s
standard 4 vCPU 4 vCPU 16 GB VM disk Neoverse-N1 nobarrier 8,334 498 µs 3,419 150,193 35,176 742 MiB/s 394 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk Neoverse-N1 nobarrier 7,846 510 µs 4,024 99,268 27,725 776 MiB/s 422 MiB/s
GitHub 2 vCPU 8 GB VM disk Neoverse-N2 nobarrier 8,119 214 µ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,893 228 µs 2,931 19,574 12,391 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.