ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 88

  1. Blog
  2. /Observability & SRE

mmap Write vs pwrite Region: Localhost Lab

Hands-on mmap MAP_SHARED write+msync vs pwrite region update: real MB/s with durability labels, measured on Linux localhost in this hands-on lab for SREs.

Aditya Challa·1 October 2026·4 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — one-shot update (p50 MB/s)
  5. Reuse check (8 updates, aggregate MB/s)
  6. Why mmap setup shows up
  7. Reading it
  8. Durability cheat sheet
  9. vs read-scan labs
  10. Pitfalls
  11. Reproduce
  12. Limits
  13. Takeaway

Intro — what this post promises

Update a fixed-size file region (1 MiB at offset 2 MiB in a 16 MiB file): mmap MAP_SHARED write + msync/flush vs os.pwrite / write+seek with clearly labeled fsync/fdatasync variants. This lab reports MB/s on Linux localhost.

It is not mmap-vs-read-scan (lab 81) and not a whole-file fsync-vs-fdatasync redo (lab 32). Focus: write path — mmap shared mapping vs syscall write to a slice.

Related links:

  • mmap vs read scan localhost lab
  • fsync vs fdatasync localhost lab
  • mmap vs read odirect localhost lab
  • stat vs path stat localhost lab
  • configparser vs json localhost lab
  • html escape vs manual localhost lab
  • queue vs deque handoff localhost lab
  • stringio vs list join localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Affiliates: 0. No Docker. Each one-shot arm opens/closes the fd (harsh but honest).

Verdict up front (1 MiB slice): pwrite only ~7821.2 MB/s (page cache); pwrite+fdatasync ~824.3; mmap+msync(MS_SYNC) ~536.0; mmap+MS_ASYNC ~2005.6; mmap no sync ~1781.2.


Arms

ArmDurability
mmap write, no syncnot durable
mmap flush / msync(MS_SYNC)waits writeback
msync(MS_ASYNC)schedules writeback
pwrite onlypage cache
pwrite + fdatasync / fsyncdurable variants
seek+write+fdatasyncclassic equivalent

Lab topology

file 16 MiB · slice 1 MiB @ offset 2 MiB · 7 rounds · p50
metric: MB/s = slice_bytes / p50_s / 1024²
Python mmap.flush = msync sync; libc msync for ASYNC/SYNC

Script: lab-evidence/107-mmap-write-vs-write/results/run_lab.py.


Lead table — one-shot update (p50 MB/s)

ArmMB/s
pwrite only7821.2
mmap msync MS_ASYNC2005.6
mmap write no sync1781.2
pwrite + fsync926.0
write+seek + fdatasync854.2
pwrite + fdatasync824.3
mmap flush/msync SYNC536.0

Cached pwrite looks “impossibly” fast — it has not waited for disk. Compare durable arms to durable arms.


Reuse check (8 updates, aggregate MB/s)

ArmMB/s
mmap reuse + MS_ASYNC ×87846.6
pwrite reuse + fdatasync ×8847.0

Keeping a mapping hot helps async mmap. Durable pwrite still pays fdatasync each iteration.


Why mmap setup shows up

Each one-shot mmap arm pays open + mmap + munmap + close. In servers that keep a map for the process lifetime, that tax amortizes — see the reuse×8 async arm. Microbenches that only show undurable memcpy into the map overstate steady durable throughput.


Reading it

  • Need durability? Compare pwrite+fdatasync vs mmap+MS_SYNC — not vs pwrite alone.
  • MS_ASYNC is not a durability guarantee; it only kicks writeback.
  • mmap shines for many in-place edits on a long-lived mapping; one-shot open/map/close taxes setup.
  • Do not confuse with read/scan mmap labs (81 / 21).

Durability cheat sheet

GoalPrefer
Fast ephemeral updatepwrite or mmap assign (accept loss on crash)
Data durable, metadata maybe lagpwrite + fdatasync
Full file metadata durablepwrite + fsync
mmap durable regionmsync(MS_SYNC) / mmap.flush

Never cite undurable MB/s next to durable MB/s without a label — that is how blog charts mislead.


vs read-scan labs

Labs 81/21 measure read/scan bandwidth and page-touch behavior. This post only moves a dirty slice toward storage. Mixing those headlines in one article cannibalizes both topics; keep write-path numbers here.


Pitfalls

  • Publishing undurable pwrite_only numbers as “disk throughput.”
  • Forgetting page alignment when calling libc msync.
  • Rehashing lab 32’s whole-file fsync story without a region focus.
  • Assuming MAP_SHARED assign is visible to other processes before sync (visibility vs durability differ).

Reproduce

python3 lab-evidence/107-mmap-write-vs-write/results/run_lab.py

Evidence: summary.json, summary.txt, region.dat.


Limits

One Linux box / local FS. 1 MiB slice only. Open/close per one-shot arm. Not O_DIRECT. Not multi-writer coherency stress.


Takeaway

For a 1 MiB region, undurable pwrite ~7821.2 MB/s led; durable pwrite+fdatasync ~824.3 beat one-shot mmap+MS_SYNC ~536.0 MB/s. Match durability labels before picking a winner.

mmap writemsyncpwritefdatasyncmap_sharedlocalhost labsremb/s

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. 1MiB@2MiB in 16MiB file: pwrite_only 7821.2 MB/s; pwrite_fdatasync 824.3; mmap MS_SYNC 536.0; MS_ASYNC 2005.6. Write path not lab 81. Affiliates: 0. Evidence: lab-evidence/107-mmap-write-vs-write/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 24

    zlib vs gzip.compress Same Level: Localhost Lab

    Hands-on zlib.compress vs gzip.compress same-level (6) stdlib bake-off: real MB/s and sizes, measured on Linux localhost in this hands-on lab for SREs.

    Observability & SRE · 30 Sept 2026

  • Plate 12

    islice vs list Slice Windows: Localhost Lab

    Hands-on itertools.islice vs list slice window lab: real ops/s taking ranges from sequences, measured on Linux localhost in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

  • Plate 07

    heapq.merge vs sorted(chain): Localhost Lab

    Hands-on heapq.merge vs sorted(chain) multi-way merge: real records/s on pre-sorted lists, measured on Linux localhost today in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — one-shot update (p50 MB/s)
  5. Reuse check (8 updates, aggregate MB/s)
  6. Why mmap setup shows up
  7. Reading it
  8. Durability cheat sheet
  9. vs read-scan labs
  10. Pitfalls
  11. Reproduce
  12. Limits
  13. Takeaway
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove