Skip to content
Crash-safe file writes for Go

Never lose a byte to a crash.

TOCTOU-safe writes via fingerprint verification, cross-platform locking, atomic rename, and fsync for crash durability.

2
Dependencies
~27
GB/s hash
0
Allocations
MIT
License
main.go
package main

import (
    "os"

    atomicwrite "github.com/larsartmann/go-atomic-write"
)

func main() {
    path := "/etc/app/config.json"

    data, _ := os.ReadFile(path)
    fp := atomicwrite.FingerprintFromBytes(data)

    newData := []byte(`{"updated": true}`)

    err := atomicwrite.Write(path, newData, fp)
    // err == ErrConcurrentModification if someone
    // else wrote between your read and write
    _ = err
}
Features

Safety you can rely on.

Every decision optimized for crash safety and concurrent-write integrity.

TOCTOU-Safe Writes

Fingerprint verification detects concurrent modification between read and write. No silent overwrites.

xxhash64 Fingerprinting

~11x faster than SHA-256, zero allocations, ~27 GB/s throughput. Memory-bound, not compute-bound.

Cross-Platform Locking

flock on Unix, LockFileEx on Windows. Protects across processes, not just goroutines.

Atomic Rename

Single rename(2) on POSIX — no window where the file is missing. MoveFileEx on Windows.

Crash Durability

fsync on the temp file before rename, fsync on the directory after. Data survives power loss.

Minimal Dependencies

Only xxhash for hashing and flock for locking. Both intentional, neither replaceable.

How it works

Four phases. No window for corruption.

Every write passes through this pipeline. If any check fails, the original file is untouched.

1

Fingerprint

Compute an xxhash64 digest when you read the file.

fp := atomicwrite.FingerprintFile(path)
2

Stage + fsync

Write new content to a unique temp file, then fsync for durability.

atomicwrite.Write(path, data, fp)
3

Lock + Verify

Acquire exclusive lock, re-read the file, verify fingerprint still matches.

// flock.Lock() + Fingerprint.Matches()
4

Atomic Rename

Single rename(2) replaces the target. Directory is fsync'd (POSIX).

// os.Rename(tmp, path) + syncDir()
Comparison

Why go-atomic-write?

os.WriteFile handles none of this. A naive temp+rename handles one.

os.WriteFile DIY go-atomic-write
TOCTOU-safe
Crash-durable (fsync)
Concurrent-write safe
Atomic rename ~
Fingerprint verification
Cross-platform locking
Dependencies 0 0 2
Use Cases

Built for real workloads.

Drop it into any read-modify-write cycle.

Config Files

Read-modify-write cycles safe from concurrent edits

State & Checkpoints

Corruption-free persistence for databases and jobs

CI/CD Pipelines

Concurrent writers on shared artifacts and lock files

Get Started

Start writing safely.

Two functions. Zero corruption.