

Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- good article points, but what's a good alternative Docker Image with a small footprint and a package manager to Alpine Linux, if you need to install something on it and powered by glibc?by madduci
- Ops here. Don't use musl if you care about disk size or compatibility either. For reference:
docker.io/node:26-alpine - 61MB
docker.io/node:26-trixie-slim: 84MB
gcr.io/distroless/nodejs26-debian13: 55MB
Before this post, we have issues with different, slower DNS resolution in musl.
In 2026, there in no reason other than self-inflicted compatibility and performance pain to use musl in production services.
It has it's place, for binary cross-OS distribution, and generally having an alternate C STL. But avoid for SaaS.
by rdsubhas - I swear "bifrost" has to be the most overused name in computing, possibly only behind "yggdrasil." I'm not sure what's so magnetic about those names but I've seen at least 10 different things called that.by superdisk
- I feel with Rust I try and avoid re-allocations in most cases anyway, so I'm not sure that musl's allocator being slow would significantly affect performance (though I haven't benchmarked it). I feel like part of the appeal of Rust is that you can do imperatively-style mutation-heavy code comparatively risk-free, so despite me normally being the "Functional Programming Nerd", I generally write Rust in a style that's a bit closer to C.
I use musl for my Rust stuff because I have noticed that for the stuff I write it appears to have a lower memory footprint; since a lot of what I do is IO-bound anyway, I care more about using less memory than raw performance.
by tombert - Funny thing is that the major reason most people use musl is because glibc make it (artificially) hard to do completely static linking.
- Are there other options if I want to ship a 'FROM scratch' image with just a single Rust executable, and everything compiled in?
That to me is the main driver for MUSL.
by OptionOfT - Same usecase here, I use musl for compiling self contained Nim utilities I use on containers and servers without having to deal with glibc hell.by nazgulsenpai
- You can do FROM scratch, and use still glibc; it’s just that you need to copy more than one file. I don’t really understand if you are already dealing with images why you still need the image to contain a single file.by kccqzy
- The best option would be the x86_64-unknown-linux-none target (https://doc.rust-lang.org/nightly/rustc/platform-support/x86...) however it currently a tier 3 with a single maintainer (so it is technically available but unsupported).
If this specific use case is of high interest to you and you have some available bandwidth, contributing to it, maybe becoming a maintainer, and eventually organising a tier 2 MCP would definitely be a good idea.
by masklinn - I really find complaints about the minimum viable placeholder malloc in musl confusing. Does anyone seriously try to use malloc-ng for performance critical use cases?
Our entire linux distro is musl based BUT we swap out the default malloc with mimalloc for high performance because why would you not? Best of both worlds.
https://codeberg.org/stagex/stagex/src/branch/main/packages/...
by lrvick - I think the size of linked binaries and simplicity were always the main features?by grep_it
- I haven’t dug into why, but for unknown-linux builds on x86, Rust binaries have been substantially smaller on musl than standard dynamic linking to glibc, for me. No idea if I’m doing something wrong or if the handful of cases I tried were all special in some way.by jdc-pub
- Yeah... I've recently had a chance to compare how fgets is implemented in both GNU libc and musl, and, well. With glibc, it was a challenge to even find where the fgets's code actually is.by Joker_vD
- Posted this the other day but the whole musl allocator thing seems to be well known [0]by mattrighetti
- Musl's allocator being awful is pretty well known, though mostly in that it's absolutely awful in multithreaded context. TFA points out that musl has a bunch of other noticeably slower functions, which is less well known (though they're also slower by a smaller factor, and they don't worsen as your parallelism increases).by masklinn
- This is only one aspect of "performance". glibc's allocator may be faster, but it also uses more memory.
For a much more technical discussion, see https://github.com/sharkdp/fd/issues/710
by bloppe - People have such different perspectives. 26% slower does not sound "terrible" to me; it sounds like quite a reasonable price one might choose to pay for the convenience musl offers. If musl's allocator were 2.6x slower, I might call that "not so great"... but in order to qualify as "terrible" I think the difference would have to be an order of magnitude!by marssaxman
- > for the convenience musl offers
... you're fine with trading an app running 26% slower, to save a dozen megabytes ? that sounds positively insane to me. That's accepting to go from e.g. 60fps to ~45 fps (e.g. completely unacceptable)
by jcelerier - Tell your employer a 26% pay decrease for you is acceptable.by fhn
- I'm curious. What convenience, specifically, are people benefiting from by using musl?by otterley
- 26% slower could turn into a huge hardware bill, and could render the library unusable for some purposes. There are many applications for which 26% is negligible, but it ain't nothing...by wakawaka28
- Ops here, I think if you NEED that convenience, sure, rock with MUSL BUT I also see a ton of devs crowing about using MUSL on my 128GB x86 Kubernetes hosts. I have plenty of Disk Space, you can ship glibc based container.by stackskipton
- The 26% slower appears to be for their whole application, not just the allocator. For some parts of the application to make the whole this much slower it must mean that those parts are quite a lot slower, likely much more than 2x.
Moreover the 26% is with mimalloc, with musl's allocator it's 144%, so there are likely other parts that are slower (likely the memcpy implementation)
by SkiFire13 - The 26% number at the top of the article is from using mimalloc (which is a high performance allocator, at least as fast as the glibc allocator) + musl for some task, and the slowdown is coming from (probably) slow musl implementations of memcpy/memset. The musl allocator is even worse.by loeg
- If your algorithm does a ton of small allocations to the point where the allocator is the bottleneck, you're already doing it wrong. The allocator necessarily comes with a lot of overhead because it needs to accommodate diverse use cases, avoid fragmentation, and ideally, implement a variety of security checks. If you're doing something alloc-intensive, you're probably allocating and freeing a lot of identical structures and you'd be better off grabbing some continuous memory and managing that yourself in a task-specific way.
But the reality is that almost no one actually cares about performance because compute is cheaper than expertise and labor, at least in the short haul. Everything is getting more bloated and slower and we just compensate by adding CPU cores, gigabytes and gigahertz.
by matherial - Also:
> these numbers are from 4 core EC2 VMs
Yeah, because that's the exact sort of hardware musl is aimed at.
Here's my counter-bogus-statistic: musl is infinitely faster than glibc on a Nios II processor because musl will fit into memory and glibc won't. Therefore, don't use glibc if you care about your code being able to run. QED.
- "But the reality is that almost no one actually cares about performance because compute is cheaper than expertise and labor, at least in the short haul."
Doesn't have to stay that way, with hardware prices soaring and development cost allegedly in free fall.
by weinzierl - That's an interesting viewpoint, but then, will the allocator's performance never matter for any use case that is not "wrong"? It doesn't feel right.by haolez
- No, musl's allocator is just bad even in completely normal programs, and it is especially awful if you are using even two threads much less a lot of them. It has no TLABs or arenas. It has a single global mutex over alloc/free paths. It does syscalls underneath that lock (mmap) meaning the few fast paths it has are rarely taken under contention and have to fall back to futex wakes, so even 2 threads with minor contention and allocation rate will have visible wait points in profiles, stuck waiting for the allocator. It returns mapped memory to the OS very eagerly when a size class is empty, so even single allocs followed by a single free can cause thrashing as it mmaps/unmmaps things repeatedly for a size class over and over. Etc. You quite literally have to limit your thread count when using musl, because it will tank the performance of actually highly threaded programs that can scale with core count, even at very modest allocation rates and small working set sizes.
Its string routines and memory copy routines are also similarly bad, as the article alludes to. They are just naive loops with nearly no optimization. These are not small insignificant functions where using them is "doing it wrong", they are the backbone of vast amounts of code and can be made multiple times faster. You can similarly see string routines pop up in profiles all the time in musl builds in my experience. And unlike the memory allocator these cannot be "fixed" systematically across the application at link time, so you are stuck with it.
Real programs have to often do things like allocate memory and use multiple threads and process strings. People have been optimizing these things for decades, there is vast amounts of prior art, the musl developers simply did not do so because they prioritize simplicity over nearly everything else (from what I can tell) including performance.
by aseipp