Skip to content

perf(bin): add an opt-in mimalloc global allocator - #954

Open
parsnips wants to merge 1 commit into
ExtendDB:mainfrom
parsnips:feat/mimalloc-allocator
Open

parsnips wants to merge 1 commit into
ExtendDB:mainfrom
parsnips:feat/mimalloc-allocator

Conversation

@parsnips

@parsnips parsnips commented Nov 11, 2026 •

Copy link
Copy Markdown

What

Adds an opt-in mimalloc feature to the bin crate. With it, mimalloc::MiMalloc is the process's #[global_allocator] in place of the system allocator.

  • crates/bin: optional mimalloc dependency, a mimalloc = ["dep:mimalloc"] feature, and a #[cfg(feature = "mimalloc")] #[global_allocator] in main.rs.
  • Root Cargo.toml: mimalloc = { version = "0.1", default-features = false } in [workspace.dependencies]. The crate's secure feature stays off.
  • docs/adr/0030-optional-mimalloc-allocator.md: the measurements and why the feature is off by default.
  • docs/manuals/04-quickstart-setup-guide.md: the build command.
  • .github/workflows/clippy.yml: extenddb/mimalloc joins the test-hooks clippy run, so CI builds the feature.

Default builds do not change.

Why

Closes #953

Measured on the PostgreSQL build of main at 9c3fbfb plus this feature only, on glibc 2.36. The load is conditional inserts with unique keys, sent as PutItem with attribute_not_exists and as PartiQL INSERT, with 32 requests in flight:

Operation Allocator Throughput (ops/s), per measurement Server CPU per request (µs)
PutItem glibc malloc 15,092, 15,099, 14,992 257, 257, 251
PutItem mimalloc 15,679, 15,065, 15,415 226, 222, 227
INSERT glibc malloc 14,613, 6,616*, 14,058 297, 319*, 287
INSERT mimalloc 14,909, 14,595, 15,134 259, 263, 253

* The host also ran other work, which disturbed this window.

  • Server CPU for each request fell by about 12% for both operations.
  • Throughput rose by about 2% to 4%, which is close to the variation between measurements.
  • Peak resident memory of the server was higher with mimalloc: 398 to 428 MB against 309 to 359 MB after about 600,000 inserts.
  • In a perf profile under the PutItem load, libc.so.6 took 16% of the server's samples with glibc malloc and 5% with mimalloc.

An earlier revision of this description gave figures from a fork build that carried two unrelated write-path changes (28% of CPU in libc.so.6, 8.6% more throughput, 23% less CPU). The figures above replace them. The ADR describes the workload and the host.

Testing done

  • cargo fmt --check: clean.
  • cargo build -p extenddb and cargo build -p extenddb --features mimalloc: both build. nm shows mi_malloc_aligned and mi_free in the feature build only.
  • cargo test -p extenddb --features mimalloc: 3 passed.
  • cargo clippy -p extenddb --features mimalloc -- -W clippy::pedantic -W clippy::unwrap_used -W clippy::expect_used: no new warnings in crates/bin. The two warnings there are missing backticks on doc lines 4 and 10 of main.rs, and they are on main too.
  • I did not run cargo test --workspace. The library crates and their test binaries do not see the feature, because the allocator is set only in the bin crate.
  • Benchmark: the table above. Both builds came from this branch, cargo build --release --locked -p extenddb with and without --features mimalloc, in a Debian 12 container with frame pointers on.
  • The checks above ran on the first revision. Since then the changes are a code comment, the ADR and the clippy workflow line. I have not run the new clippy command locally.

Checklist

  • I have read CONTRIBUTING.md
  • All tests pass (cargo test --workspace): not run; only the bin crate changes (see above)
  • Code is formatted (cargo fmt --check)
  • Clippy is clean (cargo clippy -- -W clippy::pedantic): no new warnings in the changed crate
  • I have added or updated tests for new functionality: none; a global allocator has no unit-testable behaviour here
  • I have updated documentation if behavior changed
  • Breaking changes are noted below (if any)
  • If this changes the wire protocol, Storage trait, auth model, on-disk
    format, or public CLI surface, an RFC has been accepted or is linked
    below. Otherwise, an ADR captures the decision (link below).

ADR / RFC: ADR-0030. The number 0030 is the next unused one after the index's 0029. Renumber it if 0028 or another number is reserved.


By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache License 2.0 and I agree to the Developer Certificate of
Origin (DCO). See CONTRIBUTING.md for details.

🤖 Generated with Claude Code

@LeeroyHannigan LeeroyHannigan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the measurements and the ADR. I read the change against main at 9c3fbfb. Default builds do not change, and the allocator applies only to the bin crate. The CI runs for this PR wait for a maintainer to approve them, so no check has run yet.

Comment thread crates/bin/Cargo.toml Resolved
Comment thread crates/bin/src/main.rs Resolved
A new `mimalloc` feature on the bin crate makes mimalloc the global
allocator in place of the system allocator. Default builds do not change.
The clippy workflow builds the feature.

Measured on the PostgreSQL build of main at 9c3fbfb on glibc, under
conditional PutItem and PartiQL INSERT load with 32 requests in flight:
with mimalloc, server CPU for each request fell by about 12% and throughput
rose by about 2% to 4%. Peak resident memory was higher. ADR-0030 records
the measurements and why the feature is off by default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: michael parsons <michael@twisp.com>
@parsnips
parsnips force-pushed the feat/mimalloc-allocator branch from 82079fe to 83320bb Compare November 11, 2026 05:34

@LeeroyHannigan LeeroyHannigan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read 83320bb. The clippy run at clippy.yml:39 now builds extenddb/mimalloc, and the comment in main.rs points at ADR-0030. The ADR now measures main at 9c3fbfb. It reports about 12% less server CPU per request and a throughput change close to the noise. It also reports higher peak resident memory with mimalloc. Clippy, with the new feature run, and Licenses pass at this head.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Opt-in mimalloc global allocator for the server binary

2 participants