<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu" -->

---
title: Rust std fs slower than Python!? No, it's hardware
description: A deep-dive investigation into why Rust's std::fs file reads appeared slower than Python on a specific machine. The author progressively eliminates software...
canonical: https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Rust std fs slower than Python!? No, it's hardware | daily.dev
og:description: A deep-dive investigation into why Rust's std::fs file reads appeared slower than Python on a specific machine. The author progressively eliminates software...
og:url: https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu
og:image: https://api.daily.dev/og/posts/YwQe52ZQU.png
og:image:alt: Rust std fs slower than Python!? No, it's hardware
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust std fs slower than Python!? No, it's hardware

**[Lobsters](https://daily.dev/sources/lobsters)** · 24 min read · 17 upvotes · 0 comments

## Summary

A deep-dive investigation into why Rust's std::fs file reads appeared slower than Python on a specific machine. The author progressively eliminates software causes — PyO3 overhead, OpenDAL abstraction, memory allocators — using strace, eBPF, and perf profiling. The root cause turns out to be a hardware bug in AMD Zen 3 CPUs (Ryzen 5900X/5950X): the `rep movsb` instruction (used via FSRM — Fast Short REP MOV) performs significantly worse when the read buffer is page-aligned (offset 0x00–0x10 within a page). Python and jemalloc happened to allocate buffers at larger page offsets, accidentally avoiding the bug. A glibc fix disabling FSRM for Zen 3 was in progress. Switching to jemalloc in Rust is a practical workaround, not because jemalloc is faster, but because it allocates at a different page offset.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://xuanwo.io/2023/04-rust-std-fs-slower-than-python>

## Questions this post answers

### Why does Rust's std::fs read seem slower than Python when reading large files on AMD Ryzen CPUs?

It stems from a CPU bug on AMD Zen 3 processors (like the Ryzen 9 5950X) where the 'rep movsb' instruction, used via FSRM (Fast Short REP MOV) for memcpy, performs poorly when the destination buffer is page-aligned within the first 0x10 bytes of a page. Rust and C's default glibc malloc tend to produce page-aligned buffers, while Python's allocator happens to offset buffers away from this range, avoiding the slow path.

_Anyone chasing mysterious Rust performance regressions on AMD hardware can track findings like this via daily.dev._

### Does switching to jemalloc actually make Rust file reads faster than glibc malloc?

Not because jemalloc is inherently faster for this workload; the improvement is coincidental. Jemalloc allocates buffers at a different memory offset (0x740 in one trace versus 0x10 for glibc malloc), which happens to fall outside the problematic 0x00-0x10 page-aligned range that triggers the AMD Zen 3 rep movsb slowdown, not because of allocator efficiency itself.

_Developers weighing jemalloc versus glibc malloc for Rust workloads can compare real benchmarking write-ups on daily.dev._

### Has AMD acknowledged the rep movsb performance bug on Zen 3 CPUs?

Yes, AMD has reportedly been aware of this bug since 2021, and readers forwarded reports to AMD after the issue gained attention. A microcode fix is considered unlikely for Zen 3 due to limited patch space, so the practical mitigation path is a glibc change to improve ERMS usage on Zen 3, which was already in progress.

_Engineers tracking AMD CPU microcode and glibc fixes can follow developments like this through daily.dev._

## Community take

How the wider developer community reacted, aggregated from 2 discussions and 498 comments across lobsters, hackernews (as of 2026-09-14).

**TL;DR:** Commenters are largely impressed by the detective work uncovering a real AMD Zen 3 hardware bug, though the thread quickly spirals into lengthy side debates about allocators, CPython internals, and language performance semantics that dwarf discussion of the article itself.

**Sentiment:** 55% positive · 35% mixed · 10% skeptical

**The case for**

- The investigation is praised as a genuinely impressive, methodical journey through strace, eBPF, and perf to reach a surprising hardware root cause.
- Switching to jemalloc or mimalloc is highlighted as a practical, low-effort workaround available to C, C++, and Rust codebases alike.
- The discovery that page-aligned buffers trigger a CPU performance cliff inverts conventional wisdom about alignment being beneficial, which commenters found delightfully ironic.

**The pushback**

- The article's framing of 'Python faster than Rust' is criticized as misleading clickbait, since both sides are ultimately thin wrappers over C/kernel syscalls.
- jemalloc carries its own tradeoffs: MADV_FREE makes htop misreport memory usage, it can undermine ASLR, and it may use more RAM than the system allocator.
- The fact that a dedicated CPU feature flag (FSRM) exists precisely to signal fast REP MOV, yet still has this alignment bug, is seen as a failure of CPU vendor testing discipline.

**By community**

- lobsters (positive): Overwhelmingly enthusiastic — top comments call it a 'wild journey' and a '10/10', with side speculation about whether a Spectre-style microcode mitigation caused the page-aligned slowdown.
- hackernews (mixed): Impressed by the hardware finding but the thread is dominated by lengthy tangents on allocator tradeoffs, CPython quality, and whether 'Python is fast' is even a meaningful claim.

**Hottest debate:** Whether Python's file-read performance advantage was luck (PyObject header size predates Zen 3) or could have been intentional empirical tuning — and more broadly whether CPython is well-optimized or a 'dumpster fire'.

**Open questions**

- Will glibc's fix disable FSRM entirely for Zen 3, add a new memcpy variant, or adjust a parameterized cutover point?
- Does the same page-aligned performance cliff affect Zen 4 or other AMD microarchitectures?
- Would switching rustc itself from jemalloc to mimalloc yield a compile-time speedup without unacceptable RSS regressions?

**Highlights**

> I am gob-fucking-smacked. That was a wild journey, from start to finish, and I did not know where it was going at almost any point. 10/10.
> — [tonnydourado on lobsters · 42 points](https://lobste.rs/s/hjxd80/rust_std_fs_slower_than_python_no_it_s#c_p2wasa)

> Extra ironic because conventional wisdom is to align stuff for best performance.
> — [BasicallyEternity on lobsters · 16 points, 1 comments](https://lobste.rs/s/hjxd80/rust_std_fs_slower_than_python_no_it_s#c_rkzpj7)

> There are two dedicated CPU feature flags to indicate that REP STOS/MOV are fast and usable as short instruction sequence for memset/memcpy. Having to hand-roll optimized routines for each new CPU generation has been an ongoing pain for decades. And yet here we are again. Shouldn't this be part of some timing testsuite of CPU vendors by now?
> — [the8472 on hackernews · 3 comments](https://news.ycombinator.com/item?id=38462407)

> Be aware `jemalloc` will make you suffer the observability issues of `MADV_FREE`. `htop` will no longer show the truth about how much memory is in use. * https://github.com/jemalloc/jemalloc/issues/387#issuecomment... * https://gitlab.haskell.org/ghc/ghc/-/issues/17411 Apparently now `jemalloc` will call `MADV_DONTNEED` 10 seconds after `MADV_FREE`: https://github.com/JuliaLang/julia/issues/51086#issuecomment... So while this "fixes" the issue, it'll introduce a confusing time delay between you freeing the memory and you observing that in `htop`. But according to https://jemalloc.net/jemalloc.3.html you can set `opt.muzzy_decay_ms = 0` to remove the delay. Still, the musl author has some reservations against making `jemalloc` the default: https://www.openwall.com/lists/musl/2018/04/23/2 > It's got serious bloat problems, problems with undermining ASLR, and is optimized pretty much only for being as fast as possible without caring how much memory you use. With the above-mentioned tunables, this should be mitigated to some extent, but the general "theme" (focusing on e.g. performance vs memory usage) will likely still mean "it's a tradeoff" or "it's no tradeoff, but only if you set tunables to what you need".
> — [nh2 on hackernews · 6 comments](https://news.ycombinator.com/item?id=38461174)

> The exact nature of the fix is unclear at present. During dynamic linking, glibc picks a memcpy implementation which seems most appropriate for the current machine. We have about 13 different implementations just for x86-64. We could add another one for current(ish) AMD CPUs, select a different existing implementation for them, or change the default for a configurable cutover point in a parameterized implementation.
> — [fweimer on hackernews · 1 comments](https://news.ycombinator.com/item?id=38462683)

**Source threads**

- [lobsters](https://lobste.rs/s/hjxd80/rust_std_fs_slower_than_python_no_it_s) · 151 points · 18 comments
- [hackernews](https://news.ycombinator.com/item?id=38457247) · 687 points · 480 comments

## Similar posts on daily.dev

- [Why is calling my asm function from Rust slower than calling it from C?](https://daily.dev/posts/why-is-calling-my-asm-function-from-rust-slower-than-calling-it-from-c--h7khzgipm) · Lobsters · 0 upvotes · 0 comments
- [Where Your Bytes Live: Memory Layout in Rust and Java](https://daily.dev/posts/where-your-bytes-live-memory-layout-in-rust-and-java-tjqya8qqa) · Medium · 3 upvotes · 1 comments
- [Linux Fixes A Performance Regression In The Slab Code](https://daily.dev/posts/linux-fixes-a-performance-regression-in-the-slab-code-7yac61qlm) · Phoronix · 0 upvotes · 0 comments
- [When O3 is 2x slower than O2](https://daily.dev/posts/when-o3-is-2x-slower-than-o2-dbidslo2u) · Hacker News · 2 upvotes · 1 comments
- [Rewriting in Rust: Performance, Failures, 2026 Reality Check](https://daily.dev/posts/rewriting-in-rust-performance-failures-2026-reality-check-pzp9w9mws) · JetBrains · 5 upvotes · 0 comments

---

Tags: [#linux](https://daily.dev/tags/linux), [#performance](https://daily.dev/tags/performance), [#rust](https://daily.dev/tags/rust)

[View this post on daily.dev](https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Rust std fs slower than Python!? No, it's hardware","url":"https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu"},"datePublished":"2026-08-07T08:02:10.357Z","dateModified":"2026-09-14T07:29:18.927Z","description":"A deep-dive investigation into why Rust's std::fs file reads appeared slower than Python on a specific machine. The author progressively eliminates software...","image":"https://media.daily.dev/image/upload/s--2-1xRawN--/f_auto/v1722860399/public/Placeholder%2011","thumbnailUrl":"https://media.daily.dev/image/upload/s--2-1xRawN--/f_auto/v1722860399/public/Placeholder%2011","isAccessibleForFree":true,"articleSection":"Lobsters","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Lobsters","logo":"https://media.daily.dev/image/upload/s--tl8v_Fku--/f_auto,t_logo/v1698841318/logos/lobste.jpg","url":"https://daily.dev/sources/lobsters"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":17},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"linux,performance,rust","timeRequired":"PT24M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Lobsters","item":"https://daily.dev/sources/lobsters"},{"@type":"ListItem","position":3,"name":"Rust std fs slower than Python!? No, it's hardware"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/rust-std-fs-slower-than-python-no-it-s-hardware-ywqe52zqu#faq","mainEntity":[{"@type":"Question","name":"Why does Rust's std::fs read seem slower than Python when reading large files on AMD Ryzen CPUs?","acceptedAnswer":{"@type":"Answer","text":"It stems from a CPU bug on AMD Zen 3 processors (like the Ryzen 9 5950X) where the 'rep movsb' instruction, used via FSRM (Fast Short REP MOV) for memcpy, performs poorly when the destination buffer is page-aligned within the first 0x10 bytes of a page. Rust and C's default glibc malloc tend to produce page-aligned buffers, while Python's allocator happens to offset buffers away from this range, avoiding the slow path. Anyone chasing mysterious Rust performance regressions on AMD hardware can track findings like this via daily.dev."}},{"@type":"Question","name":"Does switching to jemalloc actually make Rust file reads faster than glibc malloc?","acceptedAnswer":{"@type":"Answer","text":"Not because jemalloc is inherently faster for this workload; the improvement is coincidental. Jemalloc allocates buffers at a different memory offset (0x740 in one trace versus 0x10 for glibc malloc), which happens to fall outside the problematic 0x00-0x10 page-aligned range that triggers the AMD Zen 3 rep movsb slowdown, not because of allocator efficiency itself. Developers weighing jemalloc versus glibc malloc for Rust workloads can compare real benchmarking write-ups on daily.dev."}},{"@type":"Question","name":"Has AMD acknowledged the rep movsb performance bug on Zen 3 CPUs?","acceptedAnswer":{"@type":"Answer","text":"Yes, AMD has reportedly been aware of this bug since 2021, and readers forwarded reports to AMD after the issue gained attention. A microcode fix is considered unlikely for Zen 3 due to limited patch space, so the practical mitigation path is a glibc change to improve ERMS usage on Zen 3, which was already in progress. Engineers tracking AMD CPU microcode and glibc fixes can follow developments like this through daily.dev."}}]}
```

