EC2 storage: NVMe vs gp3 vs tmpfs.
RunsOn launches the instance type you ask for, so the workspace disk is yours to pick: EBS gp3 by default,
local NVMe on i and d families, or RAM with tmpfs: the workspace lives in memory, so the trade-off is capacity shared with the build, not durability.
- Provisioned gp3 lifted sequential reads 2.5× on the same m8a.2xlarge (402 MiB/s to 1,002 MiB/s), but single-queue reads (1,791 to 1,792 IOPS) and synced writes (538 to 539 IOPS) barely moved: it buys bandwidth, not latency.
- Local NVMe bandwidth grows with the instance: i7i.large reads 503 MiB/s, i7i.4xlarge 4.0 GiB/s (8.1×).
- On the same m8a.2xlarge, tmpfs ran pgbench's read/write mix at 29,390 TPS against 3,297 on default gp3: 8.9× faster.
- r8a.xlarge with tmpfs ($0.0021/min at spot) answers 1,054,041 QD1 reads and 912,188 synced writes per second: 87× and 77× the best local NVMe at 4 vCPU (i7i.xlarge, $0.0019) and 577× and 1,692× default EBS gp3 (m8a.xlarge, $0.0015); its workspace is 31 GiB, from RAM.
Sequential read by instance size
Local NVMe grows with the instance; EBS gp3 grows with what you provision. Right: random-read IOPS.
i7i · local NVMe
m8id · local NVMe
m9gd · local NVMe
EBS gp3 · default and provisioned
tmpfs is off this scale: 18.5 GiB/s on r8a.2xlarge, from RAM.
Every storage option measured
fio inside the job workspace; random reads span three orders of magnitude (log bars). Other providers for context.
| Instance | Rand read | Rand write | QD1 read | p99 | Sync write | Seq read | Seq write | $/min |
|---|---|---|---|---|---|---|---|---|
| i7i · local NVMe instance store | ||||||||
| i7i.4xlarge | 339,203 | 12,258 | 200 µs | 12,081 | 4.0 GiB/s | 3.1 GiB/s | $0.0101 $0.0255 OD | |
| i7i.2xlarge | 165,109 | 12,324 | 251 µs | 9,607 | 2.0 GiB/s | 1.5 GiB/s | $0.0055 $0.0129 OD | |
| i7i.xlarge | 82,487 | 12,185 | 301 µs | 11,883 | 1,010 MiB/s | 788 MiB/s | $0.0019 $0.0066 OD | |
| i7i.large | 41,227 | 12,120 | 313 µs | 13,180 | 503 MiB/s | 395 MiB/s | $0.0011 $0.0035 OD | |
| m8id · local NVMe instance store | ||||||||
| m8id.4xlarge | 134,243 | 11,343 | 100 µs | 6,942 | 1.8 GiB/s | 866 MiB/s | $0.0057 $0.0177 OD | |
| m8id.2xlarge | 67,075 | 10,342 | 313 µs | 7,025 | 905 MiB/s | 432 MiB/s | $0.0028 $0.0090 OD | |
| m8id.xlarge | 33,526 | 11,056 | 210 µs | 7,841 | 451 MiB/s | 216 MiB/s | $0.0017 $0.0047 OD | |
| m8id.large | 16,753 | 11,154 | 108 µs | 5,555 | 226 MiB/s | 108 MiB/s | $0.0009 $0.0025 OD | |
| m9gd · local NVMe instance store | ||||||||
| m9gd.2xlarge | 87,210 | 13,398 | 88 µs | 17,495 | 1.1 GiB/s | 560 MiB/s | $0.0028 $0.0087 OD | |
| m9gd.xlarge | 43,583 | 12,610 | 138 µs | 11,264 | 585 MiB/s | 280 MiB/s | $0.0014 $0.0045 OD | |
| m9gd.large | 21,784 | 13,126 | 104 µs | 7,159 | 293 MiB/s | 141 MiB/s | $0.0008 $0.0024 OD | |
| EBS gp3 · RunsOn default volume, and provisioned | ||||||||
| m8a.2xlarge | 2,995 | 1,791 | 856 µs | 538 | 402 MiB/s | 401 MiB/s | $0.0029 $0.0084 OD | |
| m8a.2xlarge | 15,993 | 1,792 | 852 µs | 539 | 1,002 MiB/s | 1,001 MiB/s | $0.0051 $0.0105 OD | |
| c8a.large | 2,993 | 1,809 | 807 µs | 541 | 401 MiB/s | 401 MiB/s | $0.0009 $0.0021 OD | |
| c8a.xlarge | 2,993 | 1,745 | 930 µs | 540 | 401 MiB/s | 401 MiB/s | $0.0016 $0.0039 OD | |
| c8a.2xlarge | 2,992 | 1,796 | 832 µs | 539 | 401 MiB/s | 401 MiB/s | $0.0030 $0.0075 OD | |
| c8g.large | 2,994 | 1,779 | 815 µs | 539 | 401 MiB/s | 401 MiB/s | $0.0008 $0.0016 OD | |
| c8g.xlarge | 2,994 | 1,703 | 889 µs | 539 | 401 MiB/s | 401 MiB/s | $0.0013 $0.0030 OD | |
| c8g.2xlarge | 2,994 | 1,817 | 815 µs | 540 | 401 MiB/s | 401 MiB/s | $0.0027 $0.0056 OD | |
| m8a.large | 2,993 | 1,749 | 770 µs | 541 | 401 MiB/s | 401 MiB/s | $0.0009 $0.0023 OD | |
| m8a.xlarge | 2,993 | 1,828 | 840 µs | 539 | 401 MiB/s | 401 MiB/s | $0.0015 $0.0044 OD | |
| m8azn.large | 2,994 | 1,827 | 815 µs | 542 | 401 MiB/s | 401 MiB/s | $0.0011 $0.0037 OD | |
| m8azn.xlarge | 2,992 | 1,775 | 963 µs | 541 | 401 MiB/s | 401 MiB/s | $0.0026 $0.0072 OD | |
| m8azn.xlarge | 15,991 | 1,775 | 856 µs | 540 | 1,002 MiB/s | 1,001 MiB/s | $0.0047 $0.0093 OD | |
| m8azn.3xlarge | 2,996 | 1,827 | 766 µs | 539 | 401 MiB/s | 401 MiB/s | $0.0078 $0.0210 OD | |
| m8i.large | 2,994 | 1,736 | 872 µs | 534 | 401 MiB/s | 401 MiB/s | $0.0009 $0.0021 OD | |
| m8i.xlarge | 2,994 | 1,634 | 930 µs | 508 | 401 MiB/s | 401 MiB/s | $0.0017 $0.0038 OD | |
| m8i.2xlarge | 2,994 | 1,559 | 1,036 µs | 470 | 401 MiB/s | 401 MiB/s | $0.0033 $0.0074 OD | |
| m8i-flex.large | 2,994 | 1,745 | 881 µs | 527 | 401 MiB/s | 401 MiB/s | $0.0010 $0.0020 OD | |
| m8i-flex.xlarge | 2,993 | 1,576 | 963 µs | 527 | 401 MiB/s | 401 MiB/s | $0.0017 $0.0037 OD | |
| m8i-flex.2xlarge | 2,995 | 1,746 | 848 µs | 516 | 401 MiB/s | 401 MiB/s | $0.0027 $0.0070 OD | |
| m9g.large | 2,994 | 1,660 | 963 µs | 543 | 401 MiB/s | 401 MiB/s | $0.0010 $0.0019 OD | |
| m9g.xlarge | 2,993 | 1,818 | 938 µs | 543 | 401 MiB/s | 401 MiB/s | $0.0018 $0.0036 OD | |
| m9g.2xlarge | 2,993 | 1,720 | 823 µs | 543 | 401 MiB/s | 401 MiB/s | $0.0036 $0.0068 OD | |
| r8a.large | 2,994 | 1,842 | 881 µs | 541 | 401 MiB/s | 401 MiB/s | $0.0010 $0.0030 OD | |
| t8i.medium | 2,998 | 1,750 | 799 µs | 524 | 401 MiB/s | 401 MiB/s | $0.0007 $0.0011 OD | |
| tmpfs · workspace in RAM | ||||||||
| m8a.2xlarge | 3,663,155 | 1,108,954 | <1 µs | 931,027 | 18.1 GiB/s | 10.1 GiB/s | $0.0029 $0.0084 OD | |
| m9g.2xlarge | 2,433,754 | 657,000 | <1 µs | 647,961 | 15.7 GiB/s | 6.7 GiB/s | $0.0036 $0.0068 OD | |
| r8a.2xlarge | 3,669,702 | 1,098,003 | <1 µs | 877,674 | 18.5 GiB/s | 10.1 GiB/s | $0.0043 $0.0110 OD | |
| m9g.xlarge | 2,450,656 | 655,954 | <1 µs | 647,658 | 15.2 GiB/s | 4.5 GiB/s | $0.0018 $0.0036 OD | |
| r8a.xlarge | 3,665,859 | 1,054,041 | <1 µs | 912,188 | 18.2 GiB/s | 9.9 GiB/s | $0.0021 $0.0056 OD | |
| Other providers, 8/4/2 vCPU x64 (hardware suite) | ||||||||
| Namespace 8x16 | 423,854 | 78,141 | 12 µs | 17,901 | 4.1 GiB/s | 2.9 GiB/s | $0.0120 | |
| Namespace 8x32 | 417,764 | 78,586 | 13 µs | 18,160 | 4.2 GiB/s | 2.9 GiB/s | $0.0240 | |
| Namespace 4x16 | 436,056 | 78,615 | 12 µs | 17,844 | 4.1 GiB/s | 2.9 GiB/s | $0.0120 | |
| Namespace 4x8 | 403,484 | 78,033 | 12 µs | 17,941 | 4.1 GiB/s | 3.0 GiB/s | $0.0060 | |
| Blacksmith 4 vCPU | 251,762 | 84,854 | 14 µs | 18,024 | 6.9 GiB/s | 1.6 GiB/s | $0.0080 | |
| Blacksmith 8 vCPU | 199,982 | 68,500 | 19 µs | 15,392 | 4.0 GiB/s | 1.7 GiB/s | $0.0160 | |
| Blacksmith 2 vCPU | 136,106 | 61,629 | 19 µs | 15,532 | 4.7 GiB/s | 1.9 GiB/s | $0.0040 | |
| Avrea 2 vCPU | 132,755 | 45,672 | 20 µs | 8,163 | 5.3 GiB/s | 3.4 GiB/s | $0.0040 | |
| Avrea 4 vCPU | 172,765 | 47,519 | 18 µs | 8,386 | 4.6 GiB/s | 3.1 GiB/s | $0.0080 | |
| Ubicloud premium 8 vCPU | 19,859 | 9,657 | 408 µs | 3,195 | 3.1 GiB/s | 1.2 GiB/s | $0.0080 | |
| Namespace 2x8 | 222,621 | 77,512 | 13 µs | 18,068 | 4.1 GiB/s | 2.9 GiB/s | $0.0060 | |
| StarSling 8 vCPU | 10,959 | 52,315 | 18 µs | 2,812 | 2.5 GiB/s | 2.0 GiB/s | $0.0160 | |
| Ubicloud standard 8 vCPU | 11,860 | 8,407 | 569 µs | 1,670 | 2.6 GiB/s | 689 MiB/s | $0.0050 | |
| StarSling 4 vCPU | 11,527 | 53,300 | 17 µs | 3,023 | 2.5 GiB/s | 3.4 GiB/s | $0.0080 | |
| Avrea 8 vCPU | 139,439 | 43,414 | 23 µs | 7,763 | 7.4 GiB/s | 5.4 GiB/s | $0.0160 | |
| Ubicloud premium 4 vCPU | 16,062 | 8,328 | 1,679 µs | 1,343 | 2.7 GiB/s | 807 MiB/s | $0.0040 | |
| Ubicloud standard 4 vCPU | 8,344 | 3,805 | 2,073 µs | 578 | 2.2 GiB/s | 250 MiB/s | $0.0025 | |
| Warpbuild 2 vCPU | 72,474 | 26,143 | 56 µs | 2,056 | 7.6 GiB/s | 4.6 GiB/s | $0.0040 | |
| Warpbuild 4 vCPU | 40,569 | 22,245 | 58 µs | 1,980 | 7.8 GiB/s | 5.1 GiB/s | $0.0080 | |
| Ubicloud premium 2 vCPU | 64,617 | 5,988 | 1,106 µs | 2,391 | 2.8 GiB/s | 833 MiB/s | $0.0020 | |
| Ubicloud standard 2 vCPU | 46,311 | 6,847 | 864 µs | 1,549 | 2.3 GiB/s | 398 MiB/s | $0.0013 | |
| Warpbuild 8 vCPU | 44,952 | 19,636 | 60 µs | 1,813 | 7.9 GiB/s | 4.5 GiB/s | $0.0160 | |
| GitHub 8-core | 18,761 | 8,049 | 192 µs | 3,968 | 784 MiB/s | 532 MiB/s | $0.0220 | |
| GitHub 4-core | 11,712 | 6,843 | 251 µs | 3,262 | 394 MiB/s | 394 MiB/s | $0.0120 | |
| GitHub 2-core | 8,712 | 6,531 | 289 µs | 3,904 | 199 MiB/s | 199 MiB/s | $0.0060 | |
| AWS CodeBuild medium | 2,967 | 1,748 | 778 µs | 559 | 252 MiB/s | 252 MiB/s | $0.0100 | |
| AWS CodeBuild small | 2,969 | 1,755 | 791 µs | 562 | 252 MiB/s | 252 MiB/s | $0.0050 | |
| AWS CodeBuild large | 2,970 | 1,763 | 799 µs | 559 | 252 MiB/s | 252 MiB/s | $0.0200 | |
- IOPS are 4k blocks · QD32 keeps 32 requests in flight, QD1 one
- $/min: EC2 spot + EBS, on-demand (OD) under it; a dash means no price yet. The RunsOn license is a fixed cost, not included
More findings8: every NVMe family, provisioned gp3, tmpfs
- i7i: random read climbs from 75,023 IOPS on i7i.large to 589,309 on i7i.4xlarge (7.9×), while single-request (QD1) reads stay between 12,120 and 12,324 IOPS.
- m8id: random read climbs from 33,541 IOPS on m8id.large to 268,804 on m8id.4xlarge (8.0×), while single-request (QD1) reads stay between 10,342 and 11,343 IOPS.
- m9gd: random read climbs from 43,608 IOPS on m9gd.large to 174,573 on m9gd.2xlarge (4.0×), while single-request (QD1) reads stay between 12,610 and 13,398 IOPS.
- On m8azn.xlarge, gp3 provisioned at 1,000 MiB/s and 16,000 IOPS delivers it: 1,002 MiB/s and 15,994 random-read IOPS, against 401 MiB/s and 2,994 on the default volume. QD1 reads barely move (1,775 → 1,775 IOPS): provisioning buys throughput, not latency.
- tmpfs on m9g.xlarge answers 2,634,992 random-read IOPS and 647,658 synced writes per second; the same m9g.xlarge on default gp3 manages 2,994 and 543. The price is capacity: the workspace is 15 GiB of RAM.
- tmpfs on m8a.2xlarge answers 4,111,775 random-read IOPS and 931,027 synced writes per second; the same m8a.2xlarge on default gp3 manages 2,995 and 538. The price is capacity: the workspace is 31 GiB of RAM.
- tmpfs on m9g.2xlarge answers 2,689,280 random-read IOPS and 647,961 synced writes per second; the same m9g.2xlarge on default gp3 manages 2,995 and 543. The price is capacity: the workspace is 31 GiB of RAM.
- tmpfs on r8a.2xlarge answers 4,207,889 random-read IOPS and 877,674 synced writes per second; c8a.2xlarge (same CPU, 16 vs 64 GiB RAM) on default gp3 manages 2,995 and 539. The price is capacity: the workspace is 62 GiB of RAM.
What storage does to real builds
The same three builds on RunsOn runners that differ by storage, one 4 vCPU runner per kind first.
| Runner | Rust | TypeScript | bun install | Docker | $/Rust build |
|---|---|---|---|---|---|
| RunsOn x64 | |||||
| m8azn.xlarge | 1m 53s | 56s | 21s | 8m 13s | $0.0079 |
| m8a.xlarge | 1m 59s | 1m 01s | 21s | 9m 05s | $0.0050 |
| c8a.xlarge | 2m 05s | 1m 03s | 21s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0044 |
| m8i-flex.xlarge | 2m 56s | 1m 28s | 22s | 12m 15s | $0.0065 |
| m8i.xlarge | 2m 59s | 1m 29s | 23s | 12m 10s | $0.0068 |
| m8azn.3xlarge | 1m 10s | 37s | 21s | 4m 52s | $0.0178 |
| c8a.2xlarge | 1m 26s | 47s | 25s | 7m 19s | $0.0072 |
| m8a.2xlarge | 1m 27s | 42s | 22s | 5m 39s | $0.0069 |
| m8i.2xlarge | 1m 57s | 55s | 20s | 7m 18s | $0.0092 |
| m8i-flex.2xlarge | 1m 59s | 58s | 22s | 7m 29s | $0.0101 |
| m8azn.large | 2m 51s | 1m 45s | 20s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0047 |
| r8a.large | 3m 06s | 1m 41s | 22s | 11m 18s | $0.0040 |
| m8a.large | 3m 12s | 1m 37s | 20s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0088 |
| c8a.large | 3m 39s | failed: out of memory: 4 GB was not enough on this runner for the opencode typecheck, even with turbo limited to 4 tasks: TypeScript processes are killed out of memory (exit 137). 16 GB passes. It has 3.7 GiB of swap (zram). | — | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0039 |
| m8i.large | 5m 12s | 2m 43s | 21s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0066 |
| m8i-flex.large | 5m 18s | 2m 36s | 20s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0060 |
| t8i.medium | 5m 34s | failed: out of memory: 4 GB was not enough on this runner for the opencode typecheck, even with turbo limited to 4 tasks: TypeScript processes are killed out of memory (exit 137). 16 GB passes. It has 3.7 GiB of swap (zram). | — | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0046 |
| m8azn.xlarge | 1m 54s | 45s | 10s | 6m 42s | $0.0136 |
| m8a.2xlarge | 1m 26s | 33s | 11s | 4m 26s | $0.0122 |
| m8id.xlarge | 2m 57s | 1m 20s | 16s | 9m 18s | $0.0071 |
| i7i.xlarge | 3m 06s | 1m 17s | 11s | 8m 34s | $0.0077 |
| m8id.2xlarge | 1m 56s | 44s | 10s | 5m 49s | $0.0116 |
| i7i.2xlarge | 1m 57s | 47s | 10s | 5m 47s | $0.0142 |
| m8id.large | 5m 02s | 3m 07s | 36s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0139 |
| i7i.large | 5m 18s | 2m 23s | 16s | 14m 51s | $0.0065 |
| r8a.xlarge | 2m 06s | 48s | 8s | n/a: Not run: needs more than 32 GB of RAM with tmpfs, where Docker's data root lives in RAM; PostHog's layers plus the build's own memory exceeded it and the runner was shut down mid-build. The 64 GB tmpfs runner builds it. | $0.0065 |
| r8a.2xlarge | 1m 28s | 31s | 8s | 3m 46s | $0.0107 |
| m8a.2xlarge | 1m 29s | 30s | 8s | n/a: Not run: needs more than 32 GB of RAM with tmpfs, where Docker's data root lives in RAM; PostHog's layers plus the build's own memory exceeded it and the runner was shut down mid-build. The 64 GB tmpfs runner builds it. | $0.0075 |
| RunsOn arm64 | |||||
| m9g.xlarge | 2m 02s | 1m 00s | 22s | 9m 10s | $0.0091 |
| c8g.xlarge | 2m 43s | 1m 20s | 22s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0057 |
| m9g.2xlarge | 1m 28s | 42s | 20s | 5m 54s | $0.0079 |
| c8g.2xlarge | 1m 54s | 53s | 26s | 8m 20s | $0.0083 |
| m9g.large | 3m 13s | 1m 40s | 19s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0075 |
| c8g.large | 5m 17s | failed: out of memory: 4 GB was not enough on this runner for the opencode typecheck, even with turbo limited to 4 tasks: TypeScript processes are killed out of memory (exit 137). 16 GB passes. It has 3.7 GiB of swap (zram). | — | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0048 |
| m9gd.xlarge | 2m 04s | 50s | 13s | 6m 23s | $0.0118 |
| m9gd.2xlarge | 1m 30s | 30s | 8s | 4m 33s | $0.0188 |
| m9gd.large | 3m 09s | 1m 40s | 29s | n/a: Not run: the PostHog Docker build needs more than 8 GB of memory; it ran out of memory on 8 GB runners. | $0.0092 |
| m9g.xlarge | 2m 04s | 46s | 9s | n/a: Not run: needs more than 32 GB of RAM with tmpfs, where Docker's data root lives in RAM; PostHog's layers plus the build's own memory exceeded it and the runner was shut down mid-build. The 64 GB tmpfs runner builds it. | $0.0091 |
| m9g.2xlarge | 1m 31s | 29s | 8s | n/a: Not run: needs more than 32 GB of RAM with tmpfs, where Docker's data root lives in RAM; PostHog's layers plus the build's own memory exceeded it and the runner was shut down mid-build. The 64 GB tmpfs runner builds it. | $0.0084 |
- Groups: EBS gp3, default · EBS gp3, provisioned · local NVMe · tmpfs
- Cost at EC2 spot, RunsOn's default
- Every machine next to the other providers: RunsOn profile
Same CPU, different disk24 comparisons
- m8a.2xlarge on EBS gp3 and on gp3 1000 MiB/s: Rust even within run-to-run spread (1m 25s–1m 29s on EBS gp3, 1m 23s–1m 31s on gp3 1000 MiB/s); TypeScript even within run-to-run spread (39s–48s on EBS gp3, 32s–39s on gp3 1000 MiB/s); Docker 4m 26s on gp3 1000 MiB/s vs 5m 39s.
- m8a.2xlarge on EBS gp3 and on tmpfs: Rust even within run-to-run spread (1m 25s–1m 29s on EBS gp3, 1m 26s–1m 33s on tmpfs); TypeScript 30s on tmpfs vs 42s.
- m8azn.xlarge on EBS gp3 and on gp3 1000 MiB/s: Rust even within run-to-run spread (1m 50s–1m 57s on EBS gp3, 1m 51s–1m 55s on gp3 1000 MiB/s); TypeScript 45s on gp3 1000 MiB/s vs 56s; Docker 6m 42s on gp3 1000 MiB/s vs 8m 13s.
- m9g.xlarge on EBS gp3 and on tmpfs: Rust even within run-to-run spread (1m 59s–2m 05s on EBS gp3, 1m 58s–2m 06s on tmpfs); TypeScript 46s on tmpfs vs 1m 00s.
- m9g.2xlarge on EBS gp3 and on tmpfs: Rust even within run-to-run spread (1m 25s–1m 31s on EBS gp3, 1m 24s–1m 42s on tmpfs); TypeScript 29s on tmpfs vs 42s.
- m8a.2xlarge on gp3 1000 MiB/s and on tmpfs: Rust even within run-to-run spread (1m 23s–1m 31s on gp3 1000 MiB/s, 1m 26s–1m 33s on tmpfs); TypeScript even within run-to-run spread (32s–39s on gp3 1000 MiB/s, 29s–33s on tmpfs).
- m8i.2xlarge (EBS gp3) and m8id.2xlarge (local NVMe) share the Xeon 6975P-C: Rust even within run-to-run spread (1m 51s–2m 00s on EBS gp3, 1m 51s–2m 02s on local NVMe); TypeScript 44s on local NVMe vs 55s; Docker 5m 49s on local NVMe vs 7m 18s.
- m8i-flex.2xlarge (EBS gp3) and m8id.2xlarge (local NVMe) share the Xeon 6975P-C: Rust even within run-to-run spread (1m 54s–2m 06s on EBS gp3, 1m 51s–2m 02s on local NVMe); TypeScript 44s on local NVMe vs 58s; Docker 5m 49s on local NVMe vs 7m 29s.
- m8i-flex.large (EBS gp3) and m8id.large (local NVMe) share the Xeon 6975P-C: Rust even within run-to-run spread (4m 57s–5m 27s on EBS gp3, 4m 50s–5m 07s on local NVMe); TypeScript 2m 36s on EBS gp3 vs 3m 07s.
- m8i-flex.xlarge (EBS gp3) and m8id.xlarge (local NVMe) share the Xeon 6975P-C: Rust even within run-to-run spread (2m 53s–3m 02s on EBS gp3, 2m 50s–3m 00s on local NVMe); TypeScript 1m 20s on local NVMe vs 1m 28s; Docker 9m 18s on local NVMe vs 12m 15s.
- m8i.large (EBS gp3) and m8id.large (local NVMe) share the Xeon 6975P-C: Rust even within run-to-run spread (4m 58s–5m 35s on EBS gp3, 4m 50s–5m 07s on local NVMe); TypeScript 2m 43s on EBS gp3 vs 3m 07s.
- m8i.xlarge (EBS gp3) and m8id.xlarge (local NVMe) share the Xeon 6975P-C: Rust even within run-to-run spread (2m 56s–3m 00s on EBS gp3, 2m 50s–3m 00s on local NVMe); TypeScript 1m 20s on local NVMe vs 1m 29s; Docker 9m 18s on local NVMe vs 12m 10s.
- m9g.xlarge (EBS gp3) and m9gd.xlarge (local NVMe) share the Neoverse-V3: Rust even within run-to-run spread (1m 59s–2m 05s on EBS gp3, 1m 56s–2m 07s on local NVMe); TypeScript 50s on local NVMe vs 1m 00s; Docker 6m 23s on local NVMe vs 9m 10s.
- m9g.2xlarge (EBS gp3) and m9gd.2xlarge (local NVMe) share the Neoverse-V3: Rust even within run-to-run spread (1m 25s–1m 31s on EBS gp3, 1m 20s–1m 36s on local NVMe); TypeScript 30s on local NVMe vs 42s; Docker 4m 33s on local NVMe vs 5m 54s.
- m9g.large (EBS gp3) and m9gd.large (local NVMe) share the Neoverse-V3: Rust even within run-to-run spread (3m 01s–3m 25s on EBS gp3, 3m 01s–3m 10s on local NVMe); TypeScript within 1s of each other.
- m9gd.2xlarge (local NVMe) and m9g.2xlarge (tmpfs) share the Neoverse-V3: Rust even within run-to-run spread (1m 20s–1m 36s on local NVMe, 1m 24s–1m 42s on tmpfs); TypeScript even within run-to-run spread (28s–31s on local NVMe, 29s–32s on tmpfs).
- m9gd.xlarge (local NVMe) and m9g.xlarge (tmpfs) share the Neoverse-V3: Rust even within run-to-run spread (1m 56s–2m 07s on local NVMe, 1m 58s–2m 06s on tmpfs); TypeScript 46s on tmpfs vs 50s.
- c8a.xlarge (EBS gp3) and r8a.xlarge (tmpfs) share the EPYC 9R45 (RAM differs: 8 vs 32 GiB): Rust even within run-to-run spread (1m 57s–2m 09s on EBS gp3, 1m 59s–2m 14s on tmpfs); TypeScript 48s on tmpfs vs 1m 03s.
- c8a.2xlarge (EBS gp3) and m8a.2xlarge (gp3 1000 MiB/s) share the EPYC 9R45 (RAM differs: 16 vs 32 GiB): Rust even within run-to-run spread (1m 21s–1m 32s on EBS gp3, 1m 23s–1m 31s on gp3 1000 MiB/s); TypeScript 33s on gp3 1000 MiB/s vs 47s; Docker 4m 26s on gp3 1000 MiB/s vs 7m 19s.
- c8a.2xlarge (EBS gp3) and m8a.2xlarge (tmpfs) share the EPYC 9R45 (RAM differs: 16 vs 32 GiB): Rust even within run-to-run spread (1m 21s–1m 32s on EBS gp3, 1m 26s–1m 33s on tmpfs); TypeScript 30s on tmpfs vs 47s.
- c8a.2xlarge (EBS gp3) and r8a.2xlarge (tmpfs) share the EPYC 9R45 (RAM differs: 16 vs 64 GiB): Rust even within run-to-run spread (1m 21s–1m 32s on EBS gp3, 1m 24s–1m 30s on tmpfs); TypeScript 31s on tmpfs vs 47s; Docker 3m 46s on tmpfs vs 7m 19s.
- m8a.2xlarge (EBS gp3) and r8a.2xlarge (tmpfs) share the EPYC 9R45 (RAM differs: 32 vs 64 GiB): Rust even within run-to-run spread (1m 25s–1m 29s on EBS gp3, 1m 24s–1m 30s on tmpfs); TypeScript 31s on tmpfs vs 42s; Docker 3m 46s on tmpfs vs 5m 39s.
- m8a.xlarge (EBS gp3) and r8a.xlarge (tmpfs) share the EPYC 9R45 (RAM differs: 16 vs 32 GiB): Rust even within run-to-run spread (1m 55s–2m 11s on EBS gp3, 1m 59s–2m 14s on tmpfs); TypeScript 48s on tmpfs vs 1m 01s.
- m8a.2xlarge (gp3 1000 MiB/s) and r8a.2xlarge (tmpfs) share the EPYC 9R45 (RAM differs: 32 vs 64 GiB): Rust even within run-to-run spread (1m 23s–1m 31s on gp3 1000 MiB/s, 1m 24s–1m 30s on tmpfs); TypeScript even within run-to-run spread (32s–39s on gp3 1000 MiB/s, 29s–33s on tmpfs); Docker 3m 46s on tmpfs vs 4m 26s.
How it's measured
The same fio tests as the runner table, inside the job workspace, on every size of each family. The jobs ran on RunsOn's default capacity: 24 on spot and 21 on on-demand, its fallback. 6 were interrupted on spot: shown as failures and left out of the medians, so an interruption never touches a timing.