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 78,187 Namespace 4x8 (4 vCPU) · reads/s
Fastest QD1 read, arm64 at 4 vCPU 23,456 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 18,093 Namespace 4x8 · 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. Namespace8 vCPU8x32 · VM disk80,310, p99 12 µs, ×1.00
  2. Blacksmith2 vCPUVM disk77,996, p99 27 µs, ×0.97
  3. StarSling8 vCPUVM disk54,118, p99 17 µs, ×0.67
  4. Avrea8 vCPUVM disk50,387, p99 14 µs, ×0.63
  5. Warpbuild8 vCPUVM disk28,843, p99 45 µs, ×0.36
  6. RunsOn8 vCPUi7i.2xlarge · local NVMe12,054, p99 301 µs, ×0.15
  7. Ubicloud8 vCPUpremium · VM disk10,777, p99 305 µs, ×0.13
  8. GitHub8 vCPUVM disk7,928, p99 155 µs, ×0.10
  9. RunsOn8 vCPUm8a.2xlarge · EBS gp31,816, p99 815 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,766, p99 717 µs, ×0.02

Namespace and Blacksmith lead x64 QD1 read, within 5% (80,310 and 77,996).tmpfs for scale: 1,150,953 on RunsOn r8a.xlarge · tmpfs.

Synced writesx64 · 4k + fdatasync · IOPS, higher is better
  1. Blacksmith2 vCPUVM disk · nobarrier18,654, p99 26 µs, ×1.00
  2. Namespace8 vCPU8x32 · VM disk18,341, p99 20 µs, ×0.98
  3. RunsOn2 vCPUi7i.large · local NVMe13,001, p99 33 µs, ×0.70
  4. Avrea4 vCPUVM disk · nobarrier9,205, p99 29 µs, ×0.49
  5. GitHub4 vCPUnetwork disk · nobarrier4,328, p99 367 µs, ×0.23
  6. StarSling8 vCPUVM disk · volatile3,463, p99 32 µs, ×0.19
  7. Ubicloud8 vCPUpremium · VM disk · nobarrier2,822, p99 1,516 µs, ×0.15
  8. Warpbuild2 vCPUVM disk2,210, p99 90 µs, ×0.12
  9. AWS CodeBuild2 vCPUsmall · EBS571, p99 971 µs, ×0.03
  10. RunsOn4 vCPUm8azn.xlarge · EBS gp3 · nobarrier542, p99 979 µs, ×0.03

Blacksmith and Namespace lead x64 synced writes, within 5% (18,654 and 18,341).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 disk77,996, p99 27 µs, ×1.00
  2. Namespace2 vCPU2x8 · VM disk77,883, p99 13 µs, ×1.00
  3. Avrea2 vCPUVM disk47,774, p99 16 µs, ×0.61
  4. Warpbuild2 vCPUVM disk28,166, p99 47 µs, ×0.36
  5. RunsOn2 vCPUi7i.large · local NVMe11,951, p99 293 µs, ×0.15
  6. GitHub2 vCPUVM disk7,499, p99 222 µs, ×0.10
  7. Ubicloud2 vCPUstandard · VM disk6,445, p99 1,090 µs, ×0.08
  8. RunsOn2 vCPUm8azn.large · EBS gp31,809, p99 774 µ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% (77,996 and 77,883).tmpfs for scale: 1,150,953 on RunsOn r8a.xlarge · tmpfs.

Synced writesx64 at 2 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Blacksmith2 vCPUVM disk · nobarrier18,654, p99 26 µs, ×1.00
  2. Namespace2 vCPU2x8 · VM disk18,050, p99 21 µs, ×0.97
  3. RunsOn2 vCPUi7i.large · local NVMe13,001, p99 33 µs, ×0.70
  4. Avrea2 vCPUVM disk · nobarrier9,105, p99 30 µs, ×0.49
  5. GitHub2 vCPUVM disk · nobarrier4,147, p99 151 µs, ×0.22
  6. Warpbuild2 vCPUVM disk2,210, p99 90 µs, ×0.12
  7. Ubicloud2 vCPUpremium · VM disk · nobarrier1,986, p99 2,572 µs, ×0.11
  8. AWS CodeBuild2 vCPUsmall · EBS571, p99 971 µs, ×0.03
  9. RunsOn2 vCPUm8azn.large · EBS gp3 · nobarrier542, p99 979 µs, ×0.03

Blacksmith and Namespace lead x64 2 vCPU synced writes, within 5% (18,654 and 18,050).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 disk78,187, p99 13 µs, ×1.00
  2. Blacksmith4 vCPUVM disk67,769, p99 18 µs, ×0.87
  3. Avrea4 vCPUVM disk49,995, p99 14 µs, ×0.64
  4. StarSling4 vCPUVM disk46,881, p99 22 µs, ×0.60
  5. Warpbuild4 vCPUVM disk27,792, p99 56 µs, ×0.36
  6. RunsOn4 vCPUi7i.xlarge · local NVMe11,028, p99 281 µs, ×0.14
  7. Ubicloud4 vCPUstandard · VM disk9,661, p99 326 µs, ×0.12
  8. GitHub4 vCPUnetwork disk7,240, p99 297 µs, ×0.09
  9. RunsOn4 vCPUc8a.xlarge · EBS gp31,790, p99 807 µs, ×0.02
  10. AWS CodeBuild4 vCPUmedium · EBS1,766, p99 717 µs, ×0.02

Fastest x64 4 vCPU QD1 read: Namespace (78,187), ahead of Blacksmith (67,769).tmpfs for scale: 1,150,953 on RunsOn r8a.xlarge · tmpfs.

Synced writesx64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace4 vCPU4x8 · VM disk18,093, p99 21 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier16,362, p99 26 µs, ×0.90
  3. RunsOn4 vCPUi7i.xlarge · local NVMe12,619, p99 34 µs, ×0.70
  4. Avrea4 vCPUVM disk · nobarrier9,205, p99 29 µs, ×0.51
  5. GitHub4 vCPUnetwork disk · nobarrier4,328, p99 367 µs, ×0.24
  6. StarSling4 vCPUVM disk · volatile3,081, p99 38 µs, ×0.17
  7. Warpbuild4 vCPUVM disk2,194, p99 163 µs, ×0.12
  8. Ubicloud4 vCPUstandard · VM disk · nobarrier1,826, p99 2,507 µs, ×0.10
  9. AWS CodeBuild4 vCPUmedium · EBS566, p99 971 µs, ×0.03
  10. RunsOn4 vCPUm8azn.xlarge · EBS gp3 · nobarrier542, p99 979 µs, ×0.03

Fastest x64 4 vCPU synced writes: Namespace (18,093), 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. Namespace8 vCPU8x32 · VM disk80,310, p99 12 µs, ×1.00
  2. Blacksmith8 vCPUVM disk75,819, p99 16 µs, ×0.94
  3. StarSling8 vCPUVM disk54,118, p99 17 µs, ×0.67
  4. Avrea8 vCPUVM disk50,387, p99 14 µs, ×0.63
  5. Warpbuild8 vCPUVM disk28,843, p99 45 µs, ×0.36
  6. RunsOn8 vCPUi7i.2xlarge · local NVMe12,054, p99 301 µs, ×0.15
  7. Ubicloud8 vCPUpremium · VM disk10,777, p99 305 µs, ×0.13
  8. GitHub8 vCPUVM disk7,928, p99 155 µs, ×0.10
  9. RunsOn8 vCPUm8a.2xlarge · EBS gp31,816, p99 815 µs, ×0.02
  10. AWS CodeBuild8 vCPUlarge · EBS1,756, p99 684 µs, ×0.02

Fastest x64 8 vCPU QD1 read: Namespace (80,310), ahead of Blacksmith (75,819).tmpfs for scale: 1,150,953 on RunsOn r8a.xlarge · tmpfs.

Synced writesx64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. Namespace8 vCPU8x32 · VM disk18,341, p99 20 µs, ×1.00
  2. Blacksmith8 vCPUVM disk · nobarrier18,022, p99 27 µs, ×0.98
  3. RunsOn8 vCPUi7i.2xlarge · local NVMe11,713, p99 38 µs, ×0.64
  4. Avrea8 vCPUVM disk · nobarrier9,198, p99 32 µs, ×0.50
  5. GitHub8 vCPUVM disk · nobarrier4,220, p99 208 µs, ×0.23
  6. StarSling8 vCPUVM disk · volatile3,463, p99 32 µs, ×0.19
  7. Ubicloud8 vCPUpremium · VM disk · nobarrier2,822, p99 1,516 µs, ×0.15
  8. Warpbuild8 vCPUVM disk2,190, p99 121 µs, ×0.12
  9. AWS CodeBuild8 vCPUlarge · EBS563, p99 987 µs, ×0.03
  10. RunsOn8 vCPUm8a.2xlarge · EBS gp3 · nobarrier540, p99 979 µs, ×0.03

Namespace and Blacksmith lead x64 8 vCPU synced writes, within 5% (18,341 and 18,022).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 disk27,941, p99 56 µs, ×1.00
  2. Blacksmith8 vCPUVM disk23,825, p99 40 µs, ×0.85
  3. Avrea2 vCPUVM disk21,590, p99 58 µs, ×0.77
  4. Namespace2 vCPUApple silicon 2x8 · VM disk19,829, p99 88 µs, ×0.71
  5. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,508, p99 81 µs, ×0.48
  6. Ubicloud4 vCPUstandard · VM disk9,977, p99 375 µs, ×0.36
  7. GitHub4 vCPUnetwork disk7,891, p99 222 µs, ×0.28
  8. RunsOn4 vCPUc8g.xlarge · EBS gp31,837, p99 856 µs, ×0.07
  9. Warpbuild4 vCPUEBS1,807, p99 758 µs, ×0.06

Fastest arm64 QD1 read: Warpbuild (27,941), ahead of Blacksmith (23,825).tmpfs for scale: 677,120 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 · 4k + fdatasync · IOPS, higher is better
  1. RunsOn8 vCPUm9gd.2xlarge · local NVMe17,569, p99 19 µs, ×1.00
  2. Warpbuild6 vCPUxfast (Apple M4 Pro) · VM disk · nobarrier8,864, p99 68 µs, ×0.50
  3. Blacksmith8 vCPUVM disk · nobarrier7,373, p99 65 µs, ×0.42
  4. Ubicloud8 vCPUstandard · VM disk · nobarrier4,141, p99 979 µs, ×0.24
  5. GitHub4 vCPUnetwork disk · nobarrier4,098, p99 301 µs, ×0.23
  6. Namespace8 vCPU8x16 · VM disk4,026, p99 167 µs, ×0.23
  7. Avrea2 vCPUVM disk4,000, p99 92 µs, ×0.23
  8. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 971 µs, ×0.03
  9. Warpbuild8 vCPUEBS · nobarrier540, p99 979 µs, ×0.03

Fastest arm64 synced writes: RunsOn m9gd.2xlarge · NVMe (17,569), ahead of Warpbuild (8,864).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 disk22,245, p99 47 µs, ×1.00
  2. Avrea2 vCPUVM disk21,590, p99 58 µs, ×0.97
  3. Namespace2 vCPUApple silicon 2x8 · VM disk19,829, p99 88 µs, ×0.89
  4. RunsOn2 vCPUm9gd.large · local NVMe13,480, p99 81 µs, ×0.61
  5. Ubicloud2 vCPUstandard · VM disk8,034, p99 510 µs, ×0.36
  6. GitHub2 vCPUVM disk7,775, p99 222 µs, ×0.35
  7. RunsOn2 vCPUc8g.large · EBS gp31,816, p99 1,004 µs, ×0.08
  8. Warpbuild2 vCPUEBS1,775, p99 905 µs, ×0.08

Blacksmith and Avrea lead arm64 2 vCPU QD1 read, within 5% (22,245 and 21,590).tmpfs for scale: 677,120 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 90 µs, ×0.88
  3. Avrea2 vCPUVM disk4,000, p99 92 µs, ×0.55
  4. Namespace2 vCPUApple silicon 2x8 · VM disk3,695, p99 101 µs, ×0.51
  5. GitHub2 vCPUVM disk · nobarrier3,094, p99 420 µs, ×0.43
  6. Ubicloud2 vCPUstandard · VM disk · nobarrier3,000, p99 848 µs, ×0.41
  7. RunsOn2 vCPUm9g.large · EBS gp3 · nobarrier543, p99 995 µs, ×0.07
  8. Warpbuild2 vCPUEBS · nobarrier538, p99 987 µ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,456, p99 44 µs, ×1.00
  2. Avrea4 vCPUVM disk21,376, p99 57 µs, ×0.91
  3. Namespace4 vCPUApple silicon 4x16 · VM disk18,972, p99 105 µs, ×0.81
  4. RunsOn4 vCPUm9gd.xlarge · local NVMe13,455, p99 84 µs, ×0.57
  5. Ubicloud4 vCPUstandard · VM disk9,977, p99 375 µs, ×0.43
  6. GitHub4 vCPUnetwork disk7,891, p99 222 µs, ×0.34
  7. RunsOn4 vCPUc8g.xlarge · EBS gp31,837, p99 856 µs, ×0.08
  8. Warpbuild4 vCPUEBS1,807, p99 758 µs, ×0.08

Fastest arm64 4 vCPU QD1 read: Blacksmith (23,456), ahead of Avrea (21,376).tmpfs for scale: 677,120 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 4 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn4 vCPUm9gd.xlarge · local NVMe14,869, p99 23 µs, ×1.00
  2. Blacksmith4 vCPUVM disk · nobarrier6,597, p99 84 µs, ×0.44
  3. GitHub4 vCPUnetwork disk · nobarrier4,098, p99 301 µs, ×0.28
  4. Avrea4 vCPUVM disk3,936, p99 56 µs, ×0.26
  5. Namespace4 vCPU4x16 · VM disk3,869, p99 187 µs, ×0.26
  6. Ubicloud4 vCPUstandard · VM disk · nobarrier2,612, p99 2,998 µs, ×0.18
  7. RunsOn4 vCPUm9g.xlarge · EBS gp3 · nobarrier543, 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,869), ahead of Blacksmith (6,597).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 disk23,825, p99 40 µs, ×1.00
  2. Avrea8 vCPUVM disk20,543, p99 52 µs, ×0.86
  3. Namespace8 vCPU8x16 · VM disk16,122, p99 98 µs, ×0.68
  4. RunsOn8 vCPUm9gd.2xlarge · local NVMe13,508, p99 81 µs, ×0.57
  5. Ubicloud8 vCPUstandard · VM disk9,786, p99 379 µs, ×0.41
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp31,810, p99 774 µs, ×0.08
  7. Warpbuild8 vCPUEBS1,790, p99 774 µs, ×0.08

Fastest arm64 8 vCPU QD1 read: Blacksmith (23,825), ahead of Avrea (20,543).tmpfs for scale: 677,120 on RunsOn m9g.xlarge · tmpfs.

Synced writesarm64 at 8 vCPU · 4k + fdatasync · IOPS, higher is better
  1. RunsOn8 vCPUm9gd.2xlarge · local NVMe17,569, p99 19 µs, ×1.00
  2. Blacksmith8 vCPUVM disk · nobarrier7,373, p99 65 µs, ×0.42
  3. Ubicloud8 vCPUstandard · VM disk · nobarrier4,141, p99 979 µs, ×0.24
  4. Namespace8 vCPU8x16 · VM disk4,026, p99 167 µs, ×0.23
  5. Avrea8 vCPUVM disk3,823, p99 56 µs, ×0.22
  6. RunsOn8 vCPUm9g.2xlarge · EBS gp3 · nobarrier543, p99 971 µs, ×0.03
  7. Warpbuild8 vCPUEBS · nobarrier540, p99 979 µs, ×0.03

Fastest arm64 8 vCPU synced writes: RunsOn m9gd.2xlarge · NVMe (17,569), ahead of Blacksmith (7,373).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 80,310 times a second on Namespace 8x32 and 1,543 on RunsOn m8i.2xlarge · EBS gp3, 52× apart; p99 latency is 12 µs against 971 µ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,105,119 QD1 reads and 426,617 synced writes per second: 91× and 32× the best local NVMe at 2 vCPU (i7i.large, $0.0011) and 619× and 789× 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,543 and 1,837 QD1 reads and 489 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 27,941 times a second on Warpbuild xfast (Apple M4 Pro) 6 vCPU and 1,642 on RunsOn m9g.xlarge · EBS gp3, 17× apart; p99 latency is 56 µs against 1,004 µs.
  • Synced 4k writes on arm64 run from 537 per second on RunsOn c8g.large · EBS gp3 (workspace mounted nobarrier) to 17,569 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,106 synced writes per second, m8i.2xlarge on EBS gp3 1,543 and 489.
  • Same Xeon 6975P-C CPU, different disk: m8id.large on local NVMe answers 11,182 QD1 reads and 5,542 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 10,996 QD1 reads and 8,057 synced writes per second, m8i-flex.xlarge on EBS gp3 1,740 and 520.
  • Same Neoverse-V3 CPU, different disk: m9gd.2xlarge on local NVMe answers 13,508 QD1 reads and 17,569 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,455 QD1 reads and 14,869 synced writes per second, m9g.xlarge on EBS gp3 1,642 and 543.
  • Same Neoverse-V3 CPU, different disk: m9gd.large on local NVMe answers 13,480 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 barely move (1,780 → 1,757 IOPS): it buys bandwidth, not latency.
  • tmpfs on m8a.2xlarge is not a disk at all: 1,111,843 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,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: 677,120 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,150,238 QD1 reads and 428,713 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,150,953 QD1 reads and 432,796 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs on r9g.large is not a disk at all: 634,536 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: 644,236 QD1 reads and 302,278 synced writes per second, from RAM. The workspace is 29 GiB, sized by memory.
  • tmpfs: 635k–1.2M QD1 reads and 297k–433k synced writes per second across 8 runners (8 RunsOn configurations).
  • VM disk: 5.5k–80k QD1 reads and 976–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: 7.2k–7.9k QD1 reads and 4.1k–4.3k 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 (78,187 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
Namespace 8x32 8 vCPU 32 GB VM disk EPYC · model hidden 80,310 12 µs 18,341 1,129,852 522,909 4.2 GiB/s 3.0 GiB/s
8x16 8 vCPU 16 GB VM disk EPYC · model hidden 77,720 12 µs 17,740 1,138,192 465,716 4.1 GiB/s 2.9 GiB/s
4x16 4 vCPU 16 GB VM disk EPYC · model hidden 77,245 13 µs 17,722 988,446 455,585 4.1 GiB/s 3.0 GiB/s
4x8 4 vCPU 8 GB VM disk EPYC · model hidden 78,187 13 µs 18,093 1,000,575 454,539 4.1 GiB/s 2.9 GiB/s
2x8 2 vCPU 8 GB VM disk EPYC · model hidden 77,883 13 µs 18,050 354,904 231,225 4.2 GiB/s 3.0 GiB/s
Blacksmith 2 vCPU 8 GB VM disk EPYC · model hidden nobarrier 77,996 27 µs 18,654 780,194 174,903 6.6 GiB/s 2.0 GiB/s
8 vCPU 8 vCPU 32 GB VM disk EPYC · model hidden nobarrier 75,819 16 µs 18,022 523,413 293,806 7.6 GiB/s 2.1 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.7 GiB/s
StarSling 8 vCPU 32 GB VM disk EPYC · model hidden volatile 54,118 17 µs 3,463 249,722 59,965 2.9 GiB/s 2.9 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Xeon · model hidden volatile 46,881 22 µs 3,081 315,539 48,009 3.1 GiB/s 3.0 GiB/s
Avrea 8 vCPU 32 GB VM disk EPYC 4585PX nobarrier 50,387 14 µs 9,198 343,640 234,017 11.7 GiB/s 7.4 GiB/s
4 vCPU 4 vCPU 16 GB VM disk EPYC 4585PX nobarrier 49,995 14 µs 9,205 420,948 190,365 10.4 GiB/s 8.4 GiB/s
2 vCPU 2 vCPU 8 GB VM disk EPYC 4585PX nobarrier 47,774 16 µs 9,105 315,150 324,338 12.0 GiB/s 7.5 GiB/s
Warpbuild 8 vCPU 32 GB VM disk Ryzen 9 9950X 28,843 45 µs 2,190 154,260 57,088 5.0 GiB/s 3.6 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 9950X 27,792 56 µs 2,194 179,057 66,661 6.4 GiB/s 4.3 GiB/s
2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 9950X 28,166 47 µs 2,210 152,215 67,413 6.6 GiB/s 4.1 GiB/s
RunsOn i7i.2xlarge 8 vCPU 64 GB local NVMe Xeon 8559C 12,054 301 µs 11,713 300,467 165,110 2.0 GiB/s 1.5 GiB/s
m8azn.3xlarge 12 vCPU 48 GB EBS gp3 EPYC 9R05 nobarrier 1,558 995 µs 538 2,997 2,994 401 MiB/s 401 MiB/s
m8a.2xlarge 8 vCPU 32 GB EBS gp3 EPYC 9R45 nobarrier 1,816 815 µs 540 2,994 2,992 401 MiB/s 401 MiB/s
m8a.2xlarge 8 vCPU 32 GB gp3 1000 MiB/s EPYC 9R45 nobarrier 1,692 889 µs 540 15,994 15,992 1,001 MiB/s 1,001 MiB/s
c8a.2xlarge 8 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,710 856 µs 540 2,995 2,992 401 MiB/s 401 MiB/s
r8a.2xlarge 8 vCPU 64 GB tmpfs EPYC 9R45 1,150,238 <1 µs 428,713 4,280,104 3,818,921 17.9 GiB/s 10.0 GiB/s
m8a.2xlarge 8 vCPU 32 GB tmpfs EPYC 9R45 1,111,843 <1 µs 428,937 4,286,079 3,820,879 18.5 GiB/s 10.0 GiB/s
m8azn.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R05 nobarrier 1,780 848 µs 542 2,994 2,992 401 MiB/s 401 MiB/s
m8azn.xlarge 4 vCPU 16 GB gp3 1000 MiB/s EPYC 9R05 nobarrier 1,757 840 µ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,543 971 µs 489 2,992 2,994 401 MiB/s 401 MiB/s
m8id.2xlarge 8 vCPU 32 GB local NVMe Xeon 6975P-C 10,286 313 µs 7,106 134,257 67,076 905 MiB/s 432 MiB/s
m8i-flex.2xlarge 8 vCPU 32 GB EBS gp3 Xeon 6975P-C nobarrier 1,774 938 µs 516 2,992 2,995 401 MiB/s 401 MiB/s
m8a.xlarge 4 vCPU 16 GB EBS gp3 EPYC 9R45 nobarrier 1,771 848 µs 540 2,994 2,992 401 MiB/s 401 MiB/s
c8a.xlarge 4 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,790 807 µs 540 2,994 2,992 401 MiB/s 401 MiB/s
r8a.xlarge 4 vCPU 32 GB tmpfs EPYC 9R45 1,150,953 <1 µs 432,796 4,238,360 3,832,030 18.1 GiB/s 10.1 GiB/s
m8azn.large 2 vCPU 8 GB EBS gp3 EPYC 9R05 nobarrier 1,809 774 µs 542 2,994 2,991 401 MiB/s 401 MiB/s
m8i-flex.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,740 848 µs 520 2,992 2,994 401 MiB/s 401 MiB/s
m8i.xlarge 4 vCPU 16 GB EBS gp3 Xeon 6975P-C nobarrier 1,696 840 µs 521 2,992 2,994 401 MiB/s 401 MiB/s
m8id.xlarge 4 vCPU 16 GB local NVMe Xeon 6975P-C 10,996 218 µs 8,057 67,090 33,527 451 MiB/s 216 MiB/s
i7i.xlarge 4 vCPU 32 GB local NVMe Xeon 8559C 11,028 281 µs 12,619 150,052 82,486 1,010 MiB/s 788 MiB/s
m8a.large 2 vCPU 8 GB EBS gp3 EPYC 9R45 nobarrier 1,782 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,680 864 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
r8a.large 2 vCPU 16 GB tmpfs EPYC 9R45 1,105,119 <1 µs 426,617 2,178,293 1,943,626 18.4 GiB/s 10.0 GiB/s
c8a.large 2 vCPU 4 GB EBS gp3 EPYC 9R45 nobarrier 1,784 864 µs 541 2,994 2,992 401 MiB/s 401 MiB/s
m8id.large 2 vCPU 8 GB local NVMe Xeon 6975P-C 11,182 187 µ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,745 897 µ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,633 971 µs 535 2,994 2,994 401 MiB/s 401 MiB/s
i7i.large 2 vCPU 16 GB local NVMe Xeon 8559C 11,951 293 µs 13,001 75,023 41,231 503 MiB/s 395 MiB/s
t8i.medium 2 vCPU 4 GB EBS gp3 Xeon 6975P-C nobarrier 1,736 791 µs 522 2,998 2,998 401 MiB/s 401 MiB/s
Ubicloud premium 8 vCPU 32 GB VM disk Ryzen 9 7950X3D nobarrier 10,777 305 µs 2,822 362,628 20,504 3.0 GiB/s 1.4 GiB/s
standard 8 vCPU 8 vCPU 32 GB VM disk EPYC 9454P nobarrier 8,014 561 µs 1,763 211,320 14,889 2.7 GiB/s 716 MiB/s
premium 4 vCPU 4 vCPU 16 GB VM disk Ryzen 9 7950X3D nobarrier 6,435 2,073 µs 1,060 169,052 16,583 2.3 GiB/s 909 MiB/s
standard 4 vCPU 4 vCPU 16 GB VM disk EPYC 9454P nobarrier 9,661 326 µs 1,826 193,790 19,414 2.7 GiB/s 668 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk EPYC 9454P nobarrier 6,445 1,090 µs 976 101,862 30,075 2.5 GiB/s 622 MiB/s
premium 2 vCPU 2 vCPU 8 GB VM disk Ryzen 9 7950X3D nobarrier 5,490 1,106 µs 1,986 97,077 56,269 2.6 GiB/s 849 MiB/s
GitHub 8 vCPU 32 GB VM disk Xeon 8573C nobarrier 7,928 155 µs 4,220 38,977 19,839 784 MiB/s 532 MiB/s
4-core 4 vCPU 16 GB network disk EPYC 9V45 nobarrier 7,240 297 µs 4,328 19,578 10,796 394 MiB/s 245 MiB/s
2-core 2 vCPU 8 GB VM disk EPYC 7763 nobarrier 7,499 222 µs 4,147 9,384 8,788 199 MiB/s 200 MiB/s
AWS CodeBuild medium 4 vCPU 8 GB EBS Xeon 8488C 1,766 717 µs 566 2,990 2,978 253 MiB/s 251 MiB/s
large 8 vCPU 16 GB EBS Xeon 8488C 1,756 684 µs 563 2,990 2,978 251 MiB/s 251 MiB/s
small 2 vCPU 3 GB EBS Xeon 8488C 1,760 709 µs 571 2,989 2,972 248 MiB/s 251 MiB/s
arm6436 runners, 7 providers
Warpbuild xfast (Apple M4 Pro) 6 vCPU 14 GB VM disk nobarrier 27,941 56 µs 8,864 321,484 4,986 20.1 GiB/s 20.3 GiB/s
xfast (Apple M4 Pro) 12 vCPU 12 vCPU 28 GB VM disk nobarrier 26,738 40 µs 8,562 335,287 4,460 21.6 GiB/s 22.7 GiB/s
8 vCPU 8 vCPU 32 GB EBS Neoverse-V2 nobarrier 1,790 774 µs 540 4,994 4,994 401 MiB/s 401 MiB/s
4 vCPU 4 vCPU 16 GB EBS Neoverse-V2 nobarrier 1,807 758 µs 539 4,193 4,193 302 MiB/s 302 MiB/s
2 vCPU 2 vCPU 8 GB EBS Neoverse-V2 nobarrier 1,775 905 µs 538 4,193 4,194 302 MiB/s 301 MiB/s
Blacksmith 8 vCPU 32 GB VM disk Ampere-1a nobarrier 23,825 40 µs 7,373 218,423 25,290 1.6 GiB/s 822 MiB/s
4 vCPU 4 vCPU 16 GB VM disk Ampere-1a nobarrier 23,456 44 µs 6,597 153,065 22,534 1.6 GiB/s 855 MiB/s
2 vCPU 2 vCPU 6 GB VM disk Ampere-1a nobarrier 22,245 47 µs 6,383 75,635 26,550 1.7 GiB/s 857 MiB/s
Avrea 2 vCPU 8 GB VM disk Apple M5 Max · as stated by the provider 21,590 58 µs 4,000 166,655 38,604 31.9 GiB/s 14.9 GiB/s
8 vCPU 8 vCPU 32 GB VM disk Apple M5 Max · as stated by the provider 20,543 52 µs 3,823 141,093 18,426 43.1 GiB/s 16.1 GiB/s
4 vCPU 4 vCPU 16 GB VM disk Apple M5 Max · as stated by the provider 21,376 57 µs 3,936 148,274 18,814 32.7 GiB/s 17.1 GiB/s
Namespace Apple silicon 2x8 2 vCPU 8 GB VM disk CPU not reported 19,829 88 µs 3,695 151,596 15,029 31.5 GiB/s 10.5 GiB/s
Apple silicon 4x16 4 vCPU 16 GB VM disk CPU not reported 18,972 105 µs 3,461 127,914 17,304 30.6 GiB/s 11.9 GiB/s
8x32 8 vCPU 32 GB VM disk Ampere-1a 15,699 93 µs 3,285 180,698 28,671 891 MiB/s 691 MiB/s
8x16 8 vCPU 16 GB VM disk Ampere-1a 16,122 98 µs 4,026 171,247 41,036 901 MiB/s 690 MiB/s
4x16 4 vCPU 16 GB VM disk Ampere-1a 17,241 86 µs 3,869 147,360 32,179 943 MiB/s 760 MiB/s
4x8 4 vCPU 8 GB VM disk Ampere-1a 16,963 91 µs 3,713 143,176 33,883 951 MiB/s 696 MiB/s
2x8 2 vCPU 8 GB VM disk Ampere-1a 16,094 95 µs 3,695 77,556 27,386 927 MiB/s 755 MiB/s
RunsOn m9gd.2xlarge 8 vCPU 32 GB local NVMe Neoverse-V3 13,508 81 µs 17,569 174,573 87,209 1.1 GiB/s 561 MiB/s
m9g.2xlarge 8 vCPU 32 GB EBS gp3 Neoverse-V3 nobarrier 1,810 774 µ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,636,493 2,512,316 12.0 GiB/s 9.0 GiB/s
c8g.2xlarge 8 vCPU 16 GB EBS gp3 Neoverse-V2 nobarrier 1,805 864 µs 539 2,994 2,992 401 MiB/s 401 MiB/s
m9gd.xlarge 4 vCPU 16 GB local NVMe Neoverse-V3 13,455 84 µs 14,869 87,221 43,589 585 MiB/s 281 MiB/s
m9g.xlarge 4 vCPU 16 GB EBS gp3 Neoverse-V3 nobarrier 1,642 1,004 µs 543 2,994 2,991 401 MiB/s 401 MiB/s
m9g.xlarge 4 vCPU 16 GB tmpfs Neoverse-V3 677,120 <1 µs 304,088 2,738,123 2,547,343 15.0 GiB/s 9.7 GiB/s
r9g.xlarge 4 vCPU 32 GB tmpfs Neoverse-V3 644,236 <1 µs 302,278 2,611,352 2,491,994 13.8 GiB/s 9.2 GiB/s
c8g.xlarge 4 vCPU 8 GB EBS gp3 Neoverse-V2 nobarrier 1,837 856 µs 539 2,993 2,994 401 MiB/s 401 MiB/s
m9gd.large 2 vCPU 8 GB local NVMe Neoverse-V3 13,480 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,993 401 MiB/s 401 MiB/s
r9g.large 2 vCPU 16 GB tmpfs Neoverse-V3 634,536 <1 µs 296,835 1,268,375 1,231,202 13.5 GiB/s 9.1 GiB/s
c8g.large 2 vCPU 4 GB EBS gp3 Neoverse-V2 nobarrier 1,816 1,004 µs 537 2,992 2,994 401 MiB/s 401 MiB/s
Ubicloud standard 4 vCPU 16 GB VM disk Neoverse-N1 nobarrier 9,977 375 µs 2,612 159,875 50,555 798 MiB/s 357 MiB/s
standard 8 vCPU 8 vCPU 32 GB VM disk Neoverse-N1 nobarrier 9,786 379 µs 4,141 241,605 101,993 756 MiB/s 487 MiB/s
standard 2 vCPU 2 vCPU 8 GB VM disk Neoverse-N1 nobarrier 8,034 510 µs 3,000 97,196 61,472 804 MiB/s 481 MiB/s
GitHub 4 vCPU 16 GB network disk Neoverse-N2 nobarrier 7,891 222 µs 4,098 19,579 11,834 394 MiB/s 337 MiB/s
2-core 2 vCPU 8 GB VM disk Neoverse-N2 nobarrier 7,775 222 µs 3,094 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.