Rewriting a live Spring Boot marketplace in Rust did not produce a dramatic latency win in this case study. Özkan Pakdil reports that the Rust version handled a home-page load test with latency percentiles close to those of the Spring Boot versions while using less resident memory on the tested machine. The harder work was reproducing behavior: preserving the PostgreSQL schema, URLs, redirects, caching, templates, and session behavior—and building tests to catch subtle mismatches.
What the marketplace rewrite set out to preserve
In his September 2025 account of mpazari.com, Özkan Pakdil frames the project around a practical question: “if we rewrote the whole application in Rust, what would we gain, what would we break, and how do we prove we broke nothing?” The goal was to replace the application engine while keeping the same database, URLs, and behavior—not to redesign the marketplace at the same time.
As an Amazon Associate I earn from qualifying purchases.
The previous application used Spring Boot and MVC, Thymeleaf, Spring JDBC, PostgreSQL, and Spring Session. The Rust implementation used Warp 0.3 with a hand-built filter chain, minijinja 2 templates, and sqlx 0.8 issuing plain SQL against the same PostgreSQL schema. It replaced Spring Session with a stateless cookie containing signed JSON, authenticated with HMAC-SHA256. Pakdil reports a 21 MB Rust deployment binary.
The site also had a longer history: old ASP.NET routes, including .aspx URLs, remained in circulation. The rewrite therefore retained a legacy redirect map, and the team tested its entries with Playwright. Old links and search results were part of the live product’s behavior, not disposable implementation details.
#1 Best Overall
What the reported load test does—and does not—show
Pakdil compared the implementations on the same Hetzner machine running Ubuntu 20.04 and against the same PostgreSQL data. To avoid proxy effects, k6 mapped the hostname directly to the application port. The scenario ramped to 50 virtual users over one minute, held at 50 for five minutes, then ramped down over one minute. Each iteration fetched the home page and slept for one second. The stated thresholds were p95 below 200 ms and p99 below 500 ms.
The figures below are the author’s reported results for that host, application path, database, and workload. They are not independently reproduced benchmarks or a general comparison of the languages.
| Implementation | Average | p95 | p99 | Requests | Failed | RSS under load | Artifact |
|---|---|---|---|---|---|---|---|
| GraalVM native | 158.58 ms | 172.57 ms | 178.64 ms | 15,570 | 0% | 134–154 MB | 112 MB |
| Spring Boot jar | 156.97 ms | 171.86 ms | 177.16 ms | 15,590 | 0% | 477–949 MB | 32 MB |
| Rust with Warp and sqlx | 160.89 ms | 179.45 ms | 191.91 ms | 15,545 | 0% | 20–40 MB | 21 MB |
For this test, the Spring Boot jar had the lowest reported average, p95, and p99 latency; Rust was close, but not fastest. Rust’s reported memory use under load was lower than either Java deployment. That makes the case study evidence for a memory difference in this particular setup, not evidence that Rust is inherently faster or that it will use less memory in every application.
Rank #2
Pakdil also reports idle RSS of about 4 MB for the native image before requests had touched more pages, about 477 MB for the Spring Boot jar, and 19 MB for Rust. He attributes the jar’s initial footprint to a configured 1 GB minimum heap. Those startup and load figures describe this project’s configuration and measurements, not fixed runtime requirements.
Why the first Rust run was much slower
The first Rust load test did not resemble the final numbers: Pakdil reports an average latency of 757 ms, p95 of 952 ms, and high CPU use. Profiling led to a request-path regex that was being compiled on every request. A Lazy value had been placed inside the request call instead of in a long-lived static. Moving the cache to a static removed the regex frames seen in the profile; the subsequent reported run was about 161 ms average and 179 ms p95.
The lesson is not that Rust requires a particular optimization, but that a rewrite can introduce performance problems unrelated to the choice of language. The request path must be profiled under a representative workload: code that looks inexpensive in isolation may become costly when repeated for every request.
Rank #3
Behavioral parity required matching the old application
Reproduce caches and query patterns
The Java application cached brand, city, category, and count data. The first Rust version instead queried related tables on every request. Pakdil reports porting the existing one-hour taxonomy cache and ten-minute counts cache behavior, bringing per-request SQL to about five queries. A port that preserves the schema but changes cache behavior can still put very different work on the database.
Check rendered data, not just successful responses
Some reports of blank pages came from mismatched context keys between handlers and templates, not database failures. A route can return a page successfully and still be wrong because the template received a missing or differently named value. Route checks should verify meaningful output and expected data, not only that the server returned a response.
Keep old URLs and query shapes working
Legacy routes, redirects, and query-string formats can be part of a marketplace’s compatibility contract. This project kept a redirect map for historical URLs and exercised its entries with Playwright. Dropping these details during a rewrite risks breaking bookmarks, links, and user flows even when the new routes work correctly.
How the team verified and deployed the replacement
Pakdil describes 31 acceptance tests and 150 end-to-end tests. The compatibility checks covered legacy URLs, query-string shapes, redirects, and pages vulnerable to empty results when handler and template context did not match. The deployment process was deliberately reversible: copy a same-named binary, restart, run a health sweep, and roll back if the sweep failed.
For another team considering a rewrite, this case suggests treating parity as a measurable deliverable rather than an assumption. Compare old and new implementations on the same host, database, request path, and workload; record latency percentiles, failures, resource use, and artifact size. In parallel, test route behavior, sessions, caching, query counts, redirects, template data, and the rollback path. A favorable benchmark cannot establish that users still get the same application.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Should you rewrite a Spring Boot application in Rust?
This marketplace example does not establish that a rewrite is worthwhile for other teams. It shows that this project achieved similar reported latency percentiles with lower reported RSS under one defined test, after resolving a request-scoped regex bottleneck and restoring caching behavior. The result to compare against is not just runtime speed: it is the resource profile you need, the behavior you must preserve, and the engineering effort required to prove that the replacement works.
A rewrite is most defensible when there is a specific, measurable constraint or capability gap, and when the team can afford comprehensive compatibility testing and a safe rollback. If the motivation is simply that Rust is presumed faster, this test is a warning against assuming the outcome: the Spring Boot jar edged Rust on the reported latency percentiles.
Learning Rust
For readers new to the language, The Rust Programming Language is an introductory book with a free online edition. It is a learning resource, not a prerequisite identified for this marketplace project.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problems




