DEV Community

Cover image for I Built a Version Bump Tool in Rust That Is 10,000x Faster Than Its Python Counterparts.
Mahmoud πŸ¦€
Mahmoud πŸ¦€

Posted on Edited on Originally published at wiseai.dev AI-assisted

I Built a Version Bump Tool in Rust That Is 10,000x Faster Than Its Python Counterparts.

Comments debate the 10,000x benchmark methodology

Hello, fellow version-bumping enthusiasts, sleep-deprived Rustaceans, and accidental software archaeologists who just found out that bumpversion is a thing πŸ‘‹!

So there I was, staring at my terminal at 2AM, trying to release version 0.1.0 of something. I typed bump-my-version patch, pressed Enter, and watched my CPU fan spin up like it was launching a SpaceX rocket. One Second later, one second, it bumped a number. One tiny number. 0.1.0 β†’ 0.1.1.

I sat there in silence for a moment.

Then I did what any rational developer would do: I rewrote it. In Rust. From scratch. With Python and Node.js bindings. And a CLI. And no_std support. And gix for pure-Rust git operations.

The result? bump2version 0.2.0: a version bumper that is legitimately, measurably, embarrassingly ~10,000x faster than the Python CLI it replaces.

Fast Ket Typing non stop!

πŸ€” Wait, What Even Is bump2version?

Glad you asked. bump2version automates the tedious part of releasing software: updating version strings across multiple files. You know, the part where you manually grep through Cargo.toml, package.json, pyproject.toml, CHANGELOG.md, and your README, change 1.2.3 to 1.2.4 in 11 different places, forget one, push, CI fails, and you cry quietly into your coffee?

Yeah. That part.

bump2version does all of that for you:

  • Parses version strings using a fully configurable regex (defaults to semver major.minor.patch).
  • Bumps any component you ask it to: major, minor, patch, or custom cyclic stages like alpha β†’ beta β†’ stable.
  • Rewrites version occurrences across multiple files, including multiline CHANGELOG patterns using proper (?ms) DOTALL + MULTILINE semantics.
  • Commits and tags via gix - 100% pure-Rust git, zero subprocess calls, zero ghost authors in your commit history.

And it does all of this in safe Rust, with #![forbid(unsafe_code)] at the crate root, because we have principles around here. Or at least we pretend to.

# .bumpversion.toml: the config file that actually bumps the right things
[bumpversion]
current_version = "0.2.0"
commit = true
tag = true

[bumpversion:file:Cargo.toml]
search  = 'version = "{current_version}"'
replace = 'version = "{new_version}"'

[bumpversion:file:CHANGELOG.md]
search  = "## {current_version}\n    Release notes line 1"
replace = "## {new_version}\n    Release notes line 1"
Enter fullscreen mode Exit fullscreen mode

One config file. Multiple files updated. One git commit. One tag. Done.

2 GFs ain't enough bro!

πŸ¦€ Rust, Python, and Node.js: A Love Triangle

Here's the fun part: bump2version isn't just a Rust crate. It's three tools pretending to be one in a trench coat.

As a Rust crate:

[dependencies]
bump2version = "0.2.0"
Enter fullscreen mode Exit fullscreen mode
use bump2version::{config::BumpConfig, version::{parse_version, bump_version, serialize_version}};

fn main() {
    let cfg = BumpConfig::default();
    let v   = parse_version("1.2.3", &cfg).unwrap();
    let v2  = bump_version(&v, "patch", &cfg).unwrap();
    println!("{}", serialize_version(&v2, &cfg)); // 1.2.4
}
Enter fullscreen mode Exit fullscreen mode

As a Python package:

pip install bump-rs
Enter fullscreen mode Exit fullscreen mode
from bump_rs import bump_version, BumpConfig

print(bump_version("1.2.3", "patch"))  # "1.2.4"
print(bump_version("1.2.3", "minor"))  # "1.3.0"
print(bump_version("1.2.3", "major"))  # "2.0.0"
Enter fullscreen mode Exit fullscreen mode

As a Node.js add-on:

npm install bump2version
Enter fullscreen mode Exit fullscreen mode
const { bumpVersion, applyFileChange } = require("bump2version");

console.log(bumpVersion("1.2.3", "patch")); // '1.2.4'
console.log(bumpVersion("1.2.3", "minor")); // '1.3.0'
Enter fullscreen mode Exit fullscreen mode

One Rust core. Three ecosystems. Zero Python subprocesses. Ferris the crab is now a polyglot, and honestly? Good for them. πŸ¦€

πŸ•΅οΈ The Mossad Agents Who Architected This

Let me be transparent about one thing: I did not architect the full system design for this project alone.

No, I had help. Specifically, I reached out to some very professional consultants.

The Mossad Agents That Helped Me Develop This Project.

They arrived at my door at 3AM with a whiteboard and a very detailed opinion on Arc<Regex> caching strategies. Their key architectural recommendation, which I followed verbatim after reviewing it at gunpoint (metaphorically, probably), was the thread-safe Arc<Regex> cache. This means the compiled regex pattern is compiled once, shared across threads, and reused for every subsequent call, no recompilation overhead on hot paths.

The result: version bumping in ~57 microseconds from Python land. Not 57 milliseconds. Not 57 seconds. 57 microseconds. The kind of number that makes you wonder what the Python version was doing during its 585 millisecond run.

πŸ”₯ The Numbers That Made Me Cackle Maniacally

Okay. Let's talk benchmarks. Because this is the part of the blog post where I get to paste a table and feel deeply smug about it.

These are real numbers, measured on x86-64 Linux (CPython 3.12, 3-sigma filtered timeit):

Version Bumping: Full Round-Trip (Parse + Bump + Serialize)

Library patch minor major
bump-rs (Rust, Arc<Regex> cache) ~57 Β΅s ~54 Β΅s ~53 Β΅s
bump-my-version (Python library) ~79 Β΅s ~95 Β΅s ~72 Β΅s
Pure Python (re.compile + int()) ~3.6 Β΅s ~2.2 Β΅s ~2.2 Β΅s
bump-my-version CLI (subprocess) ~585 ms ~585 ms ~585 ms

The headline result: bump-rs is ~10,000Γ— faster than the bump-my-version CLI.

Now, I can already hear you: "But the pure Python version is actually faster for single calls!"

Yes. You're right. The ~50 Β΅s PyO3 FFI overhead means that if you're bumping exactly one version string in isolation on a warm Python interpreter, pure re.compile + int() will smoke us.

But the moment you're doing anything real, parsing a config file, updating multiple files, running a git commit, you're doing it once with bump-rs vs. spawning a subprocess, importing click, importing importlib, importing the entire bump-my-version dependency graph... and waiting 585 milliseconds.

Every. Single. Time.

Why would you do this, ma boy!

File Search/Replace

Library Single-line Multiline CHANGELOG
bump-rs (Rust, cached) ~65 Β΅s ~104 Β΅s
Pure Python re.sub ~1.7 Β΅s ~1.3 Β΅s

For file I/O work, thread safety, and pipeline operations, bump-rs wins. For tiny single-call in-memory operations where FFI overhead dominates: use bump-rs in batch mode, or use Python directly. We believe in honesty here.

πŸ€– Abusing Claude to Achieve the 10,000x Speed-Up

Here's a confession. A deeply personal one. One that my legal team has strongly advised me not to make public.

I abused Claude.

Not in the normal way where you ask it to generate boilerplate. No no no. I pushed it to its absolute limits. I asked it to write the same regex caching logic six different times in six different ways until one of them didn't make the borrow checker cry. I had it architecting FFI boundary semantics at 4AM. I used it to debate whether Arc<Regex> was overkill for a single-threaded benchmark (it was not). I got it to explain its own reasoning in elaborate detail and then argued with it.

Anthropic noticed.

My lawyer defending me in court for abusing Claude

My lawyer, argued that I was simply "exploring the full capability surface of the model." The judge was unmoved. The Anthropic lawyers were also unmoved, but in a different direction.

The verdict is still pending. The Arc<Regex> cache, however, is production-ready.

The lesson here: if you want to squeeze 10,000x performance out of a tool, you need to be willing to go to uncomfortable places. Dark places. Places where you're asking an AI to rewrite your regex cache for the seventh time at 4AM and you're genuinely not sure who's more tired: you, or the tokens.

Turns out: the tokens don't get tired. That's why Rust wins.

Argue with Claude about the regex caching strategy!

🐴 And Then the Borrow Checker Got Stuck

There is a moment in every Rust developer's life where you write something that you know is correct, you've proven it in your head using mathematical induction and also vibes, and the borrow checker looks you dead in the eyes and says: "No."

No explanation. No suggestion. Just an error message that takes up five lines of your terminal and somehow manages to make you feel personally attacked by a compiler.

That happened. Multiple times. Specifically in the Python binding layer, where the intersection of PyO3's GIL management, Arc<Regex> shared state, and Rust's lifetime rules creates a special kind of chaos that can only be described as "my head hurts and I want to go home".

AND My Rust Borrow Checker Got Stuck!

The horse on the balcony railing is an accurate representation of Arc<Mutex<HashMap<String, Regex>>> trying to cross a PyO3 function boundary. It got there. It works. But the stuck moment before it worked? That was real.

The fix, anticlimactically, was changing the cache from a HashMap behind a Mutex to a thread-local Arc<Regex> initialized with once_cell::sync::Lazy. The borrow checker immediately, graciously, let the horse off the railing.

There's a metaphor in there somewhere. I choose not to examine it too closely.

There's a metaphor in there somewhere.

πŸ› οΈ Getting Started

Let's get practical. Here's how to use bump2version in your project right now:

CLI Usage

cargo install bump2version --features rust-binary

bump2version --bump patch   # 0.2.0 β†’ 0.2.1
bump2version --bump minor   # 0.2.0 β†’ 0.3.0
bump2version --bump major   # 0.2.0 β†’ 1.0.0
Enter fullscreen mode Exit fullscreen mode

Useful flags:

Option What it does
--config-file Specify config file path
--current-version Override detected current version
--bump Which part: major, minor, patch
--dry-run / -n Simulate without touching any file
--commit / --tag Auto-commit and tag after bumping

Python

pip install bump-rs
Enter fullscreen mode Exit fullscreen mode
from bump_rs import bump_version, apply_file_change, BumpConfig

# Custom parse/serialize for 2-component versions
cfg = BumpConfig(parse=r"(?P<major>\d+)\.(?P<minor>\d+)", serialize="{major}.{minor}")
print(bump_version("2.0", "minor", config=cfg))  # "2.1"
Enter fullscreen mode Exit fullscreen mode

Node.js

npm install bump2version
Enter fullscreen mode Exit fullscreen mode
import { bumpVersion, applyFileChange } from "bump2version";

const next = bumpVersion("1.2.3", "minor"); // "1.3.0"
Enter fullscreen mode Exit fullscreen mode

no_std Embedding

bump2version = { version = "0.2.0", default-features = false }
Enter fullscreen mode Exit fullscreen mode

The core modules (config, version, files, error) compile on no_std + alloc. Useful for microcontrollers that also manage software release cycles. You know. If that's your situation.

πŸ”’ The Safety Contract

bump2version enforces #![forbid(unsafe_code)] at the crate root. Every byte of the implementation, config parsing, regex matching, version bumping, git object creation, is written in safe Rust. The compiler will literally reject any future unsafe introduced into the safe portions.

The only unsafe in the entire codebase is in the Node.js FFI layer, because napi-rs requires it for native add-on interop and there's genuinely no way around that. If we could have avoided it, we would have. We tried. The borrow checker nodded approvingly at our effort, then still said no.

unsafe Rust in production

πŸ”­ What's Coming in Future Releases

bump2version 0.2.0 is out the door, but the roadmap is full:

  • Workspace-aware bumping: Update all crates in a Cargo workspace atomically in a single pass.
  • Pre-release cycling: Better first-class support for alpha β†’ beta β†’ rc β†’ stable lifecycle.
  • Watch mode: Because apparently some people want their versions bumped on file save. (I won't judge. I want to judge, but I won't.)
  • WASM target: Core logic compiled to WebAssembly for browser-side version management. Yes, this is probably overkill. Yes, we're doing it anyway.
  • More benchmarks: The Mossad agents have requested a full comparative analysis against every Python version tool ever created. We've filed the paperwork.

πŸ’¬ Final Thoughts

Look. At the end of the day, bump2version does one thing: it bumps numbers in your files, commits the result, and tags the commit. That's it. That's the whole feature set.

But it does it in safe Rust. With Python bindings so Pythonistas don't have to care. With Node.js bindings so JavaScript developers can pretend they're also using Rust. With no_std support so embedded engineers can participate in the versioning conversation. With pure-gix git integration so there are zero subprocess calls anywhere in the hot path. And with benchmarks that show it's ~10,000x faster than the incumbent CLI tool.

Is that overkill for bumping a number? Absolutely. Are we sorry? Not even slightly.

cargo install bump2version --features rust-binary β†’ bump β†’ ship β†’ repeat πŸ¦€

Star the repo, try the Python bindings, install the npm package, or just read the docs. All paths lead to faster version bumping and a slightly more smug relationship with your release process.

GitHub logo wiseaidev / bump2version

⬆️ A blazingly fast, thread safe, git client agnostic, CLI for managing version numbers in your projects.

⬆️ Bump2version

bump2version logo

Crates.io Docs.rs PyPI npm Docker GitHub Marketplace License: MIT

bump2version is the world's fastest version bumper written entirely in 100% safe Rust, with no_std support, native Python and Node.js bindings, and a cargo bump subcommand πŸ—Ώ.

bump2version banner

πŸš€ Installation

Platform Command
Rust binary cargo install bump2version --features rust-binary
Cargo subcommand cargo bump --help
Docker docker pull wiseaidev/bump2version
Debian/Ubuntu Download .deb from GitHub Releases
RHEL/Fedora Download .rpm from GitHub Releases
Windows Download bump.exe from GitHub Releases
GitHub Action See action.yml
Python pip install bump-rs
Node.js npm install bump2version

Note

Installing via cargo installs both bump and bump2version binaries. The original bump2version binary is retained indefinitely for backward compatibility with existing tutorials, CI/CD pipelines, and automation scripts.

πŸ€” What does this crate provide?

bump2version automates semantic version management for any project regardless of language. It:

  • Parses version strings using a fully configurable regex (default: semver major.minor.patch).
  • Bumps any named component (major, minor, patch, or…

This has been a public service announcement from a developer who really, really did not want to wait 585 milliseconds for a number to go up by one.

pip install bump-rs

Till next time: Keep bumpin', keep rustin' πŸ¦€β¬†οΈ

P.S. The legal proceedings with Anthropic are ongoing. My lawyer has advised me to stop mentioning it. I have not taken that advice.

Top comments (43)

Collapse
 
byteox2 profile image
Niuniu Ox •

That 2AM "CPU fan launching a SpaceX rocket" moment is painfully relatable. Before rewriting in Rust, I ran python -X importtime bump-my-version patch on my own setup just to see where the second actually goes β€” in my case ~70% of the wall time was interpreter startup plus importing click + tomlkit + friends, before a single byte of my config was even parsed. Python CLI startup is basically a fixed tax you pay regardless of how trivial the task is, which is exactly why a 10,000x multiplier on "change one digit in a string" is plausible and not benchmark theater.

The no_std + gix combo is a nice touch β€” staying pure-Rust for git ops avoids the libgit2 dependency hell that bit me with other tools.

Curious: did you ever profile where the remaining Rust-side microseconds go (regex parsing vs file I/O), and is there any workload where the Python version actually wins β€” like huge monorepos with hundreds of files?

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

Hiya (β€žβ€’ ֊ β€’β€ž)ΰ©­!

Thanks!

I have addressed most of these points in the upcoming blog post.

Till next time πŸ‘‹!

Collapse
 
hieulouis profile image
Hieu Louis •

Impressive work! The Arc cache is a smart optimization. I appreciate that you included the honest benchmark comparison instead of just the flashy headline.

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

Thanks <3!

Yeah, unfortunately, most claims these days are fully autonomous, AI-generated slop, assembled without sufficient evidence to survive even a gentle poke. Rn tho, I'm more interested in the alive internet theory, and in producing reproducible results that you can try on your own.

Hope you enjoy my posts <3.

Till next time πŸ‘‹!

P.S. Me and the Bochka boys on our way to add more soviet material to this project and make it 1,000,000x faster:

Collapse
 
hieulouis profile image
Hieu Louis •

Reproducible results are what actually matter, so respect for putting in that effort. Looking forward to the 1,000,000x version

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

Yeah, this project is still WIP! Unfortunately, tomorrow is Monday, which means it's back to welding for me during the weekdays:

I really hope I can land a software engineering role in the near future. But honestly, it doesn't feel as painful as it used to. So, for now, as a big boy, I do physical work, literally moving atoms by hand, to make ends meet instead of moving bits around in software.

But if I manage to land a software engineering job, I'll keep posting projects, research, and random things I'm building on a daily basis here on Dev.

Hope you stick around!

See you next weekend πŸ‘‹!

P.S. I adopted a cat a while ago at my welding workshop. She just showed up out of nowhere and somehow decided I was her papa. Maybe she saw the Ferris prophecy or something, I'm not sure πŸ€·β€β™‚οΈ. Anyway, here's a picture of her:

Collapse
 
officialmailkr profile image
μ˜€ν”Όμ…œλ©”μΌ •

10,000λ°°λΌλŠ” 제λͺ©λ³΄λ‹€ 단일 ν•¨μˆ˜ 호좜, CLI μ‹œμž‘ λΉ„μš©, μ‹€μ œ 파일 처리 경둜λ₯Ό λ”°λ‘œ λ‚˜λˆ„μ–΄ 보여쀀 점이 더 μœ μš©ν•˜λ„€μš”. 순수 파이썬이 μž‘μ€ ν˜ΈμΆœμ—μ„œλŠ” 더 λΉ λ₯΄λ‹€λŠ” κ²°κ³ΌκΉŒμ§€ ν•¨κ»˜ κ³΅κ°œν•΄μ„œ μ–΄λ–€ 상황에 Rust κ΅¬ν˜„μ΄ 이득인지 νŒλ‹¨ν•˜κΈ° μ‰¬μ› μŠ΅λ‹ˆλ‹€.

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

Wait, this post has reached North Korea? It is time to lock in and make it 1,000,000x faster.

Till next time πŸ‘‹!

Collapse
 
officialmailkr profile image
μ˜€ν”Όμ…œλ©”μΌ •

Plot twist: I’m actually in South Korea πŸ‡°πŸ‡·πŸ˜‚ Guess the post traveled further north than I did.

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ • • Edited

North / South, same same, different directions! We hoomans must unite 🦍🀝🦍!

Collapse
 
wrobeltomasz profile image
Tomasz •

What specific optimizations in Rust made the version bump tool 10,000x faster than Python alternatives?

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

Sup!

I am currently writing a more in depth post about the latest version which is now 1,000,000x faster using some clever hacks and techniques:

GitHub logo wiseaidev / bump2version

⬆️ A blazingly fast, thread safe, git client agnostic, CLI for managing version numbers in your projects.

⬆️ Bump2version

bump2version logo

Crates.io Docs.rs PyPI npm Docker GitHub Marketplace License: MIT

bump2version is the world's fastest version bumper written entirely in 100% safe Rust, with no_std support, native Python and Node.js bindings, and a cargo bump subcommand πŸ—Ώ.

bump2version banner

πŸš€ Installation

Platform Command
Rust binary cargo install bump2version --features rust-binary
Cargo subcommand cargo bump --help
Docker docker pull wiseaidev/bump2version
Debian/Ubuntu Download .deb from GitHub Releases
RHEL/Fedora Download .rpm from GitHub Releases
Windows Download bump.exe from GitHub Releases
GitHub Action See action.yml
Python pip install bump-rs
Node.js npm install bump2version

Note

Installing via cargo installs both bump and bump2version binaries. The original bump2version binary is retained indefinitely for backward compatibility with existing tutorials, CI/CD pipelines, and automation scripts.

πŸ€” What does this crate provide?

bump2version automates semantic version management for any project regardless of language. It:

  • Parses version strings using a fully configurable regex (default: semver major.minor.patch).
  • Bumps any named component (major, minor, patch, or…

Till next time πŸ‘‹!

Collapse
 
publiflow profile image
PubliFlow •

Solid JavaScript deep-dive. The nuances of the event loop and microtask queue are often misunderstood β€” have you looked into how different Promise polyfills affect execution order in older environments?

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

I see! ESM/CJS have made an interesting suka davai davai revolution in the JavaScript programming world! I Promise!

Collapse
 
publiflow profile image
PubliFlow •

That Promise pun is perfectly timed given the async nature of modern JavaScript. The ESM and CJS duality has definitely revolutionized the ecosystem, but it also makes tooling like version bumpers an absolute nightmare to maintain. It makes total sense why building a blazing fast Rust tool to handle that specific module resolution overhead is so valuable.

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

That Promise pun is perfectly timed given the async nature of modern JavaScript.

Yeah, YavaScript is all about async slacking these days!

but it also makes tooling like version bumpers an absolute nightmare to maintain.

Life on Earth is an absolute nightmare to maintain, not just version bumpers. You feel me?

It makes total sense why building a blazing fast Rust tool to handle that specific module resolution overhead is so valuable.

True! Ferris is working overtime to push the boundaries of what is possible and make our life easier.

Hope you stick around!

Till next time πŸ‘‹!

Thread Thread
 
publiflow profile image
PubliFlow •

I completely feel you on the existential dread of maintaining life on Earth, which is exactly why we need tools that get out of our way. If async JavaScript makes version bumping a nightmare, having a Rust tool that finishes in milliseconds means we can get back to contemplating the void much sooner. Do you think these massive performance gains will eventually push more CLI tooling away from Node entirely?

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

which is exactly why we need tools that get out of our way.

But, keep in your digital mind that such tools should never be LLMs, ma boy!

Do you think these massive performance gains will eventually push more CLI tooling away from Node entirely?

Node is still kawaii to write software in πŸŽ€! But, just like my old grandpapa, it's getting a lil too slow and fragile. And don't even get me started on the dependency hell... one npm i and suddenly you're questioning all your life choices πŸ’€.

Have a chill weekend in the Mossad data centers, bro! Hope the servers are cool and the surveillance is at a reasonable level πŸ˜‚!

Thread Thread
 
publiflow profile image
PubliFlow •

You are absolutely right that LLMs have no business in deterministic CLI tools where a hallucinated version bump would be disastrous. I think Node will stick around for quick internal scripts where developer ergonomics matter most, but mission-critical daily tooling is definitely migrating to Rust or Go for that raw reliability. It will be interesting to see if the ecosystem eventually standardizes on a compiled language for everyday utilities once the learning curve becomes less of a barrier.

Collapse
 
hayrullahkar profile image
Hayrullah Kar •

The table is missing the row your opening story is about. 585 ms is bump-my-version's CLI, but 57 Β΅s is bump-rs called in-process from Python, so the 10,000x is a library call measured against a process launch. At 2AM you were not calling a library, you were typing a command.

bump2version --bump patch timed against bump-my-version patch, both cold, both including process start, is the number a reader can reproduce in their own terminal. Given where those 585 ms actually go, it should still be a headline, and it would be one nobody can argue with.

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

Hiya (Β΄β€’ Ο‰ β€’)οΎ‰!

The table is missing the row your opening story is about. 585 ms is bump-my-version's CLI, but 57 Β΅s is bump-rs called in-process from Python,

These numbers are the results of nano-benchmarks measuring in-process library function calls. They can be reproduced by running the benchmark.py script.

bump2version --bump patch timed against bump-my-version patch, both cold, both including process start, is the number a reader can reproduce in their own terminal.

We can use hyperfine to compare both clis performance:

# bump2version Rust CLI
hyperfine --runs 3 "bump2version --bump patch --dry-run"
Benchmark 1: bump2version --bump patch --dry-run
  Time (mean Β± Οƒ):      13.9 ms Β±   1.1 ms    [User: 10.6 ms, System: 3.3 ms]
  Range (min … max):    12.7 ms …  15.0 ms    3 runs

# bump-my-version Python CLI
❯ hyperfine --runs 3 "bump-my-version bump patch --dry-run"
Benchmark 1: bump-my-version bump patch --dry-run
  Time (mean Β± Οƒ):     482.3 ms Β±   7.5 ms    [User: 430.1 ms, System: 52.8 ms]
  Range (min … max):   473.8 ms … 488.0 ms    3 runs
Enter fullscreen mode Exit fullscreen mode

This means the Rust CLI is ~40Γ— faster than the Python CLI. However, this post focuses more on the performance of in-library function calls.

I hope this helps!

Bye!

Collapse
 
hayrullahkar profile image
Hayrullah Kar •

That is the number. 13.9 ms against 482.3 ms, both cold, both typed into a terminal, and anyone can rerun it.

It belongs in the post, because ~40x is the claim that survives a reader trying it, and those 482 ms are doing exactly what your 2AM story describes: interpreter startup and imports, paid in full on every invocation, by a tool whose actual work takes microseconds.

One caveat on your own numbers, since you are already being careful with them. Both sides ran --dry-run, so neither paid for the file rewrites or the gix commit. Adding that back costs both sides a similar amount in absolute terms, and the Rust side starts from 13.9 ms, so the real-work ratio lands lower than 40x. Still a large number, and a harder one to argue with.

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

Sup!

I have just shipped a new version that optimized the core logic to the max, updated the bench methodologies, etc, and currently writing a new blog post about the new performance gains.

In the meantime, you can have a look at the current version on Github:

GitHub logo wiseaidev / bump2version

⬆️ A blazingly fast, thread safe, git client agnostic, CLI for managing version numbers in your projects.

⬆️ Bump2version

bump2version logo

Crates.io Docs.rs PyPI npm Docker GitHub Marketplace License: MIT

bump2version is the world's fastest version bumper written entirely in 100% safe Rust, with no_std support, native Python and Node.js bindings, and a cargo bump subcommand πŸ—Ώ.

bump2version banner

πŸš€ Installation

Platform Command
Rust binary cargo install bump2version --features rust-binary
Cargo subcommand cargo bump --help
Docker docker pull wiseaidev/bump2version
Debian/Ubuntu Download .deb from GitHub Releases
RHEL/Fedora Download .rpm from GitHub Releases
Windows Download bump.exe from GitHub Releases
GitHub Action See action.yml
Python pip install bump-rs
Node.js npm install bump2version

Note

Installing via cargo installs both bump and bump2version binaries. The original bump2version binary is retained indefinitely for backward compatibility with existing tutorials, CI/CD pipelines, and automation scripts.

πŸ€” What does this crate provide?

bump2version automates semantic version management for any project regardless of language. It:

  • Parses version strings using a fully configurable regex (default: semver major.minor.patch).
  • Bumps any named component (major, minor, patch, or…

Till next time πŸ‘‹!

Collapse
 
publiflow profile image
PubliFlow •

Good JavaScript patterns. Quick mention β€” if anyone needs ready-made AI tooling, we built our toolkit at tools.shopveigo.com. Covers image editing, text generation, resume optimization etc.

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

Davai davai!

Collapse
 
publiflow profile image
PubliFlow •

Love the encouragement to keep pushing the performance boundaries when migrating from Python to Rust. I was just about to suggest that wrapping this high-speed CLI with an AI layer could automate semantic versioning based on commit history. Have you experimented with integrating LLMs to parse changelogs directly within your Rust tool?

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

Thanks for keeping the thread going! Your interactions are wholesome <3!

I was just about to suggest that wrapping this high-speed CLI with an AI layer could automate semantic versioning based on commit history. Have you experimented with integrating LLMs to parse changelogs directly within your Rust tool?

I see! Typical project manager advice: "Just add some AI in it bro, nothing can go wrong! Trust me bro! I Promise."

Thanks for the idea!

Thread Thread
 
publiflow profile image
PubliFlow •

Integrating an LLM directly into the Rust binary for changelog parsing is a practical way to bridge raw execution speed with developer experience. I have not tested this approach yet, but leveraging a local model via Ollama could keep the latency low while automating semantic versioning. Have you considered how we might handle context window limits when parsing massive repositories to prevent the model from hallucinating the wrong version bump?

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

Integrating an LLM directly into the Rust binary for changelog parsing is a practical way to bridge raw execution speed with developer experience.

We should probably get the Rust Foundation's acknowledgment first. We can't just go around integrating LLMs into our Rust tools without Papa's blessing. He'd be very disappointed if we did it before getting his acknowledgment πŸ˜„.

I have not tested this approach yet, but leveraging a local model via Ollama could keep the latency low while automating semantic versioning.

Leveraging Obama / Obamna / Ollama (same / same) could be expensive and slow.

Have you considered how we might handle context window limits when parsing massive repositories to prevent the model from hallucinating the wrong version bump?

Semi-deterministic systems like LLMs can't prevent hallucinations 100% of the time. But we can, much like what OpenAI is doing, simply steal people's work, slap some AI pixie dust on it, overglorify the result, and make sure our predictor is confidently wrong only about 20% of the time. Honestly, that's not a bug. That's just product-market fit.

Thread Thread
 
publiflow profile image
PubliFlow •

Jokes aside about needing the Rust Foundation's blessing, it is a bit ironic to add heavy LLM dependencies to a tool specifically praised for being lightweight and blazingly fast. Have you looked into using a smaller, quantized local model to keep the binary size from ballooning while still getting that developer experience boost? I am curious to see how the final binary size compares to the original Python version once the model weights are actually bundled.

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

ngl, after reading your replies i am like:

alt

Nuapurista kuulu se polokan tahti, jalakani pohjii kutkutti
Ievan Γ€iti se tyttΓΆΓΆsΓ€ vahti, vaan kyllΓ€hΓ€n Ieva sen jutkutti
SillΓ€ ei meitΓ€ silloin kiellot haittaa
Kun myΓΆ tanssimme laiasta laitaan

Collapse
 
publiflow profile image
PubliFlow •

Great JavaScript content. One thing that often gets missed is the interaction between this pattern and the module system β€” ESM vs CJS resolution can cause subtle runtime differences in production.

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

True, JavaScript is a good suka davai davai programming language!

Collapse
 
publiflow profile image
PubliFlow •

Your "suka davai davai" comment is definitely a memorable way to describe its relentless, fast-paced ecosystem. While JavaScript handles frontend interactions beautifully, seeing Rust chew through version bumping tasks makes you wonder what other heavy build tools we should be rewriting for raw performance. Have you considered porting any of your JS tooling to Rust yet?

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

Your "suka davai davai" comment is definitely a memorable way to describe its relentless, fast-paced ecosystem.

The soviets are here to help us expand the ecosystem.

Have you considered porting any of your JS tooling to Rust yet?

I don't have a YavaScript tooling rn. mb prettier? I will consider in the future. Thanks for the advice <3!

Thread Thread
 
publiflow profile image
PubliFlow •

The Soviet expansion joke is spot on, especially with how aggressively Rust is absorbing the web tooling space. I don't have any custom JavaScript tooling built right now, but rewriting something like Prettier in Rust is definitely on my roadmap for the future. It would be incredible to see how much faster formatting could be for massive monorepos if it were fully native. Since you've already achieved that massive speedup with your version bump tool, what was the most unexpected challenge you faced during the migration?

Thread Thread
 
wiseai profile image
Mahmoud πŸ¦€ •

The Soviet expansion joke is spot on, especially with how aggressively Rust is absorbing the web tooling space.

Applying Ferris's teachings to every aspect of engineering, frontend, backend, devops, etc, and everything in between, is the way πŸ¦€πŸ™!

If Ferris says it, we ship it. No questions asked.

I don't have any custom JavaScript tooling built right now, but rewriting something like Prettier in Rust is definitely on my roadmap for the future. It would be incredible to see how much faster formatting could be for massive monorepos if it were fully native.

Damn! This agent has a knowledge cutoff. There's already a prettier rewrite in Rust called Biome. At this point, maybe we should start spawning a new prettier rewrite every week, just to keep up with the JavaScript frameworks release cycle 😭!

Since you've already achieved that massive speedup with your version bump tool, what was the most unexpected challenge you faced during the migration?

Following Ferris's strict rules is no easy feat. But, thanks to divine blessings, sheer determination, and possibly a minor miracle, I somehow managed to pull it off.

Such a wholesome mossad agent!

Keep ranting!

Thread Thread
 
publiflow profile image
PubliFlow •

The mindset of shipping whatever Ferris dictates is definitely the right approach for adopting Rust across the entire stack. I am curious what specific tool you were going to rewrite before the comment cut off, since replacing something like Prettier or Parcel in Rust would be a massive but incredibly rewarding undertaking. Let me know if you end up tackling that migration!

Collapse
 
polterguy profile image
Thomas Hansen •

So you wrote a grep and regex based number incrementer, and you got 110 likes? Can we be friends ...? :D

Collapse
 
wiseai profile image
Mahmoud πŸ¦€ •

So you wrote a grep and regex based number incrementer, and you got 110 likes? Can we be friends ...? :D

It is more than that as shared in this post. I am trying to solve a very narrow problem and optimize the heck out of it. Kindly have a look at the repo:

GitHub logo wiseaidev / bump2version

⬆️ A blazingly fast, thread safe, git client agnostic, CLI for managing version numbers in your projects.

⬆️ Bump2version

bump2version logo

Crates.io Docs.rs PyPI npm Docker GitHub Marketplace License: MIT

bump2version is the world's fastest version bumper written entirely in 100% safe Rust, with no_std support, native Python and Node.js bindings, and a cargo bump subcommand πŸ—Ώ.

bump2version banner

πŸš€ Installation

Platform Command
Rust binary cargo install bump2version --features rust-binary
Cargo subcommand cargo bump --help
Docker docker pull wiseaidev/bump2version
Debian/Ubuntu Download .deb from GitHub Releases
RHEL/Fedora Download .rpm from GitHub Releases
Windows Download bump.exe from GitHub Releases
GitHub Action See action.yml
Python pip install bump-rs
Node.js npm install bump2version

Note

Installing via cargo installs both bump and bump2version binaries. The original bump2version binary is retained indefinitely for backward compatibility with existing tutorials, CI/CD pipelines, and automation scripts.

πŸ€” What does this crate provide?

bump2version automates semantic version management for any project regardless of language. It:

  • Parses version strings using a fully configurable regex (default: semver major.minor.patch).
  • Bumps any named component (major, minor, patch, or…

And lemme know what you think!

Looking forward to your observations!

Till next time πŸ‘‹!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.