Benchmark Kotlin (JVM) write to File
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.sandbox
import com.asgard.testTools.benchmarker.BenchMarkerJVM
import java.io.File
import java.io.FileOutputStream
suspend fun main(args: Array<String>) {
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) {
FileOutputStream(file).use { fos ->
fos.write(string.toByteArray(Charsets.UTF_8))
fos.flush()
fos.fd.sync()
}
} else {
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
File("/tmp/output-file").writeText(string, Charsets.UTF_8)
We will write to OS cache buffer.
- PRO: Performance will look order of magnitude faster (eg. from 5millis to 1/20th millis).
- CON: Data is NOT guaranteed to survive a system crash, after
writeText
completes.
Backlinks