Library / SDK
microsoft/snmalloc avatar
microsoft/snmalloc

snmalloc: a message-passing allocator for cross-thread frees

Message passing based allocator

1,982 stars138 forksC++MIT

At a glance

What is it?
snmalloc is a C++ allocator that can be embedded as a header-only library or preloaded on ELF platforms. Its remote-free mechanism is designed for workloads that free allocations on different threads or process memory in large batches.
Who is it for?
Engineers should consider snmalloc when concurrent workloads repeatedly free memory on a different thread from the allocator, especially when large deallocation batches are common. Projects that need a documented turnkey installation command, allocator telemetry interface or compatibility guarantee should first review `docs/BUILDING.md`, the platform porting instructions and the allocator paths described in `docs/AddressSpace.md`.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • microsoft/snmalloc1,982 ★ · +7
Star history
Repository2026-10-162026-10-23
microsoft/snmalloc2k2k

7 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Why snmalloc targets remote deallocation

snmalloc addresses a specific allocation pattern: one thread allocates an object, while another thread eventually frees it. That pattern is routine in threaded services, parallel queues and workloads that transfer ownership between workers. It becomes less routine when every remote free requires the allocator to use a shared lock or otherwise coordinate with the allocator that owns the memory. The README identifies cross-thread freeing as one of two difficult scenarios for which snmalloc is designed.

The second scenario is batched deallocation. Applications may accumulate many free operations and release them together, but a conventional allocator can still pay synchronization or metadata costs for the individual objects in that batch. snmalloc returns remotely freed memory through a message-passing mechanism to the allocator associated with the original thread. The README says this path uses no locks and can perform thousands of remote deallocations with a single atomic operation. That is a design claim from the project documentation, not an independent performance result.

The intended users are engineers working in C++ or Rust who can either replace allocation calls in their application or place snmalloc beneath a running process through `LD_PRELOAD`. The project is a poor fit as a drop-in decision based only on the label “high performance.” Its value depends on whether the workload actually contains cross-thread frees, batched reclamation or both. The repository does not document a fixed workload-size threshold at which snmalloc becomes preferable.

The message-passing path behind snmalloc

The central mechanism is asymmetric ownership. A local free can proceed without synchronizing operations when the freeing thread is also the thread that allocated the memory, according to the README. A remote free takes another route. snmalloc places the freed memory into a message-passing structure that sends it back to the original allocator, where it can be recycled.

This arrangement avoids putting a lock on the documented remote-free path. The README attributes its scaling with core count to the fact that many remote deallocations can be enabled through a single atomic operation. It is important not to interpret that statement as a promise that every operation is free of coordination or that total application performance always improves. Queueing, delayed reuse, cache behavior and platform implementation still matter. The README also warns that the implementation has evolved since `snmalloc.pdf`, while the remote-memory return mechanism remains. For the current metadata arrangement, it directs readers to `docs/security/README.md` and `docs/AddressSpace.md`.

The allocator also manages large ranges of pages. That design reduces metadata requirements compared with allocator designs that track many smaller address ranges, as the project states in general terms. Its fast allocation path is described as two branches when compiled on Linux with Clang. Platform dependencies are abstracted to support ports, but the existence of `ports/` does not by itself confirm support for every operating system or compiler a prospective adopter uses.

Header-only C++, ELF preloading and Rust access

snmalloc offers three documented access paths. In C++, it can be used directly as a header-only library. That makes it possible to integrate the allocator at source level without treating the repository as only a system-wide preload component. The README does not include the required compiler flags, include paths, build-system settings or code needed to replace an existing allocator, so this article cannot present a verified first-allocation example.

On ELF platforms, including Linux and BSD examples given by the README, snmalloc can be loaded with `LD_PRELOAD`. This approach addresses applications where source integration is unavailable. It also shifts adoption into a deployment and compatibility question: the operator must obtain a compatible build, place it where the runtime loader can find it and pass the required loader option through the actual process environment. The README does not provide a release artifact name or a universal command for that build.

For Rust, the repository points to the `snmalloc-rs` crate on crates.io. Its workspace includes `snmalloc-rs`, `snmalloc-rs/snmalloc-sys` and `snmalloc-rs/xtask`, which corresponds with the repository layout. The crate's dependency declaration and initialization code are not included in the README, so adding a version number or showing a `Cargo.toml` fragment would risk inventing installation details. The README is explicit that a Rust crate exists, but it leaves the precise dependency and allocator setup to the crate documentation.

A conservative first-use tutorial

The first step is to decide which integration mode matches the application. For a C++ source tree that permits allocator replacement, the README identifies direct header-only use as the supported approach. Before changing build flags or allocator hooks, open `docs/BUILDING.md`. The README names that file as the authoritative build guide, but its instructions are not reproduced here.

For an executable on an ELF platform, the documented deployment mechanism is `LD_PRELOAD`. Build snmalloc according to `docs/BUILDING.md`, locate the resulting library from the user's own build, and configure the process to load it through the loader. The README does not give the library filename, so no `LD_PRELOAD=/path/to/example.so` example can be copied accurately from it. The observable result should be a process started with that library loaded; the README does not document a command for checking replacement behavior.

For a Rust application, follow the `snmalloc-rs` crate documentation linked by the README and inspect the repository's `Cargo.toml` workspace before selecting dependencies. The workspace file lists members only. It does not state which snmalloc release a consuming application should request.

A practical first review should then trace one allocation and one remote free through `docs/AddressSpace.md`. That file is specifically identified as an overview of allocation and deallocation paths. This review is important because the current metadata layout differs from the initial paper, so the PDF should not be used as the sole description of the present implementation.

Hardening choices and operational boundaries

snmalloc includes a hardened version with four documented changes. It randomizes allocations' relative locations, stores most metadata separately from allocations, protects separated metadata with guard pages, and protects in-band metadata with an encoding that can detect corruption. It also provides a `memcpy` that checks bounds relative to the underlying `malloc`. The README points to `docs/security/README.md` for the detailed security design.

These mechanisms should not be described as a general guarantee against memory corruption or exploitation. The README names particular layout and checking features but does not state a threat-model boundary, supported compiler matrix, production certification or compatibility policy. It also does not explain whether the hardened version is enabled by default. Engineers choosing it for a specific security property need to read `docs/security/README.md` and the build configuration rather than infer activation from the feature list.

A second limitation is operational. The project abstracts platform dependencies, but porting instructions are separate from normal build instructions. Supporting a new platform is a porting task documented in `docs/PORTING.md`, not an automatic consequence of the abstraction. Likewise, the README's Linux and Clang fast-path statement does not establish equivalent branch counts for every compiler, platform or hardened configuration. Performance-oriented evaluation must therefore remain tied to the actual target toolchain.

Maintenance, licensing and upgrade work

The repository is not archived, and its last push was on 2026-10-14. Recent releases include 0.7.6 on 2026-10-02, 0.7.5 on 2026-06-22 and 0.7.4 on 2026-03-24. These dates show recent repository and release activity. They do not prove that every platform, compiler or configuration receives fixes at the same rate.

The repository identifies its license as MIT. The `LICENSE` file is present at the repository root. An adopter must retain and comply with the license text when using or redistributing the software. The MIT identifier alone does not answer questions about the dependencies, Rust crates, build tools or organizational policies that may apply to a particular distribution. This is a licensing inventory point rather than legal advice.

Upgrading requires more care than treating every release as a drop-in dependency. The README says that metadata layout has changed substantially since the initial paper, and the project is currently at the 0.7.x release series. Applications should review release changes, rebuild under their real compiler and platform settings, and recheck the allocation and deallocation paths when moving versions. No migration command or compatibility matrix is provided in the README.

Alternatives and adoption fit

A real alternative is to keep the platform or language runtime's standard allocator and manage cross-thread ownership at the application layer. That approach differs in mechanism: ownership stays explicit in queues, worker-local pools or lifetime-managed objects, and memory returns through application synchronization instead of snmalloc's message-passing path. The standard allocator may be operationally simpler, particularly for small applications or platforms that snmalloc does not support, but its remote-free costs will depend on the runtime implementation.

Another alternative is another specialized allocator, although the repository does not name a competitor or establish its locking or remote-free behavior. It would be misleading to claim that snmalloc is uniquely suitable for cross-thread frees without comparing a named allocator against the same workload. The defensible comparison here is architectural: snmalloc offers source-level C++ use, ELF preloading and a Rust crate, while an ordinary runtime allocator may already be installed and require no separate preload.

The adoption boundary is therefore clear. snmalloc is most relevant when ownership frequently crosses thread boundaries, deallocations arrive in batches and the team can manage integration and build validation. It is less suitable when the team expects an undocumented universal installation procedure, requires verified support for an unlisted platform, or cannot evaluate allocator-specific behavior. Its implementation choices must be judged against the documented current paths, not only the older design paper.

Editorial conclusion

Engineers should consider snmalloc when concurrent workloads repeatedly free memory on a different thread from the allocator, especially when large deallocation batches are common. Projects that need a documented turnkey installation command, allocator telemetry interface or compatibility guarantee should first review `docs/BUILDING.md`, the platform porting instructions and the allocator paths described in `docs/AddressSpace.md`. For its intended use, the message-passing free path and large-range page strategy are the decisive features to validate.

Frequently asked questions

How can snmalloc be integrated into a C++ project?

The README says snmalloc can be used directly as a header-only C++ library. It refers users to `docs/BUILDING.md` for build instructions, but does not show the required source or build configuration.

Can snmalloc be loaded without changing application source?

On ELF platforms such as Linux and BSD, the README says snmalloc can be used with `LD_PRELOAD`. The README does not provide a built library filename or a complete deployment command.

How does snmalloc handle frees from a different thread?

The README says remotely freed memory is returned to the original allocator through message passing, without locks, and is then recycled. It states that many remote deallocations can be enabled with a single atomic operation.

Does snmalloc provide a Rust integration?

Yes. The README links to the `snmalloc-rs` crate, and the repository contains a Rust workspace with `snmalloc-rs` and `snmalloc-sys` members.

Official sources

  1. Issues
  2. License: MIT
  3. microsoft/snmalloc on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/microsoft-snmalloc.svg)](https://hysenlabs.com/projects/microsoft-snmalloc)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/microsoft-snmalloc.svg)](https://hysenlabs.com/projects/microsoft-snmalloc)

Was this useful?