About 5-10ms to fully write string of less than 10,000 characters to disk (synced).
About 0.05-0.1 milliseconds to write to OS buffer (un-synced).
About 50-100X difference between RAM and SSD write.
GT-Sandbox-Snapshot: Benchmarked in 2025
Code
package com.glassthought.sandboximport com.asgard.testTools.benchmarker.BenchMarkerJVMimport java.io.Fileimport java.io.FileOutputStream/** * Benchmark comparing file write performance WITH and WITHOUT disk sync. * * CRITICAL DISTINCTION: * - WITHOUT sync (File.writeText): Writes only to OS cache buffer * PRO: Order of magnitude faster (e.g., 0.05ms vs 5ms) * CON: Data NOT guaranteed to survive system crash after writeText completes * * - WITH sync (fd.sync()): Forces write to physical disk * PRO: Data guaranteed to survive power loss/system crash * CON: Much slower due to physical I/O */suspend fun main(args: Array<String>) { // Compare with and without sync to see the performance difference println("\n=== WITH DISK SYNC (guaranteed persistence) ===") benchmarkFileWrite(500, syncToDisk = true) benchmarkFileWrite(1000, syncToDisk = true) benchmarkFileWrite(2000, syncToDisk = true) benchmarkFileWrite(10000, syncToDisk = true) println("=== WITHOUT DISK SYNC (OS buffer only) ===") benchmarkFileWrite(500, syncToDisk = false) benchmarkFileWrite(1000, syncToDisk = false) benchmarkFileWrite(2000, syncToDisk = false) benchmarkFileWrite(10000, syncToDisk = false)}fun getRandomChar(): String { return ('a'..'z').random().toString()}private suspend fun benchmarkFileWrite(howManyChars: Int, syncToDisk: Boolean = true) { val string = (1..howManyChars).joinToString("") { getRandomChar() } val file = File("/tmp/output-file") val description = if (syncToDisk) { "Write [${string.length}] chars WITH disk sync (guaranteed persistence)" } else { "Write [${string.length}] chars WITHOUT sync (OS buffer only)" } val result = BenchMarkerJVM.benchMark({ if (syncToDisk) { // WITH SYNC: Data is guaranteed to survive system crash // CON: Much slower (e.g., 5ms) FileOutputStream(file).use { fos -> fos.write(string.toByteArray(Charsets.UTF_8)) fos.flush() // Flush to OS buffer fos.fd.sync() // Force sync to physical disk - GUARANTEES persistence } } else { // WITHOUT SYNC: Only writes to OS cache buffer // PRO: Order of magnitude faster (e.g., 0.05ms instead of 5ms) // CON: Data is NOT guaranteed to survive a system crash after writeText completes file.writeText(string, Charsets.UTF_8) } }, 1000, description = description) result.printFormattedTable()}
Command to reproduce:
gt.sandbox.checkout.commit b7ad25225b70a37866b9 \&& cd "${GT_SANDBOX_REPO}" \&& cmd.run.announce "./gradlew run --quiet"
Recorded output of command:
= WITH DISK SYNC (guaranteed persistence) =
Benchmark: Write [500] chars WITH disk sync (guaranteed persistence)
Metric
(millis)
(millis)
Min
5
4.852
P50 (Median)
5
5.109
P90
5
5.265
P95
5
5.375
P99
6
5.699
P99.9
10
10.050
Max
10
10.050
Total
5,146
5146.270
Iterations
1,000
Benchmark: Write [1000] chars WITH disk sync (guaranteed persistence)
Metric
(millis)
(millis)
Min
5
4.964
P50 (Median)
5
5.129
P90
5
5.273
P95
5
5.383
P99
7
7.497
P99.9
13
12.547
Max
13
12.547
Total
5,210
5210.009
Iterations
1,000
Benchmark: Write [2000] chars WITH disk sync (guaranteed persistence)
Metric
(millis)
(millis)
Min
5
4.964
P50 (Median)
5
5.107
P90
5
5.261
P95
5
5.333
P99
6
5.716
P99.9
10
9.933
Max
10
9.933
Total
5,148
5148.111
Iterations
1,000
Benchmark: Write [10000] chars WITH disk sync (guaranteed persistence)
Metric
(millis)
(millis)
Min
5
4.882
P50 (Median)
5
5.090
P90
5
5.206
P95
5
5.253
P99
5
5.357
P99.9
9
9.306
Max
9
9.306
Total
5,112
5111.684
Iterations
1,000
= WITHOUT DISK SYNC (OS buffer only) =
Benchmark: Write [500] chars WITHOUT sync (OS buffer only)
Metric
(micros)
(millis)
Min
54
0.054
P50 (Median)
65
0.065
P90
68
0.068
P95
71
0.071
P99
77
0.077
P99.9
142
0.142
Max
142
0.142
Total
65,610
65.610
Iterations
1,000
Benchmark: Write [1000] chars WITHOUT sync (OS buffer only)
Metric
(micros)
(millis)
Min
54
0.054
P50 (Median)
64
0.064
P90
73
0.073
P95
77
0.077
P99
91
0.091
P99.9
173
0.173
Max
173
0.173
Total
65,928
65.928
Iterations
1,000
Benchmark: Write [2000] chars WITHOUT sync (OS buffer only)
Metric
(micros)
(millis)
Min
52
0.052
P50 (Median)
64
0.064
P90
66
0.066
P95
69
0.069
P99
76
0.076
P99.9
119
0.119
Max
119
0.119
Total
63,527
63.527
Iterations
1,000
Benchmark: Write [10000] chars WITHOUT sync (OS buffer only)
Metric
(micros)
(millis)
Min
71
0.071
P50 (Median)
83
0.083
P90
88
0.088
P95
92
0.092
P99
108
0.108
P99.9
176
0.176
Max
176
0.176
Total
84,336
84.336
Iterations
1,000
writeText does NOT auto sync.
Note if we do not explicitly sync to disk with code like
5-10ms to write to SSD for strings less than 10,000 characters.
(with sync to disk).
GT-Sandbox-Snapshot
Command to reproduce:
gt.sandbox.checkout.commit 90303db14ce95a6df23d \&& cd "${GT_SANDBOX_REPO}" \&& cmd.run.announce "./run.sh"
Recorded output of command:
Starting file write benchmarks...Started [Write a string of [500] characters to file (Node.js)], going to run for [1000]...#### Benchmark: Write a string of [500] characters to file (Node.js)| Metric | Time | Value (ns) ||--------------|------------|--------------:|| Min | 4.899 ms | 4,899,398 || P50 (Median) | 5.186 ms | 5,185,765 || P90 | 5.308 ms | 5,307,762 || P95 | 5.370 ms | 5,370,353 || P99 | 5.686 ms | 5,686,219 || P99.9 | 9.962 ms | 9,962,423 || Max | 9.962 ms | 9,962,423 || Total | 5.200 s | 5,199,505,394 || Iterations | 1,000 | |Started [Write a string of [1000] characters to file (Node.js)], going to run for [1000]...#### Benchmark: Write a string of [1000] characters to file (Node.js)| Metric | Time | Value (ns) ||--------------|------------|--------------:|| Min | 4.913 ms | 4,913,184 || P50 (Median) | 5.124 ms | 5,124,034 || P90 | 5.274 ms | 5,274,016 || P95 | 5.319 ms | 5,318,924 || P99 | 5.802 ms | 5,801,763 || P99.9 | 10.144 ms | 10,144,346 || Max | 10.144 ms | 10,144,346 || Total | 5.166 s | 5,165,946,193 || Iterations | 1,000 | |Started [Write a string of [2000] characters to file (Node.js)], going to run for [1000]...#### Benchmark: Write a string of [2000] characters to file (Node.js)| Metric | Time | Value (ns) ||--------------|------------|--------------:|| Min | 4.860 ms | 4,860,061 || P50 (Median) | 5.112 ms | 5,112,402 || P90 | 5.321 ms | 5,321,158 || P95 | 5.476 ms | 5,475,930 || P99 | 6.214 ms | 6,213,986 || P99.9 | 10.127 ms | 10,126,632 || Max | 10.127 ms | 10,126,632 || Total | 5.190 s | 5,189,873,467 || Iterations | 1,000 | |Started [Write a string of [10000] characters to file (Node.js)], going to run for [1000]...#### Benchmark: Write a string of [10000] characters to file (Node.js)| Metric | Time | Value (ns) ||--------------|------------|--------------:|| Min | 4.889 ms | 4,888,916 || P50 (Median) | 5.100 ms | 5,099,928 || P90 | 5.279 ms | 5,278,977 || P95 | 5.498 ms | 5,497,842 || P99 | 6.359 ms | 6,359,360 || P99.9 | 9.896 ms | 9,896,024 || Max | 9.896 ms | 9,896,024 || Total | 5.166 s | 5,166,243,294 || Iterations | 1,000 | |All benchmarks completed!