Rewrite a Rails service in Rust only when production evidence identifies a costly bottleneck or resource burden, a bounded service can address it, and the expected gain justifies rebuilding and maintaining its behavior. Rust’s reputation—or a benchmark from another application—is not enough. Measure the service, compare less disruptive fixes, and favor an incremental cutover when its boundaries allow one.
Start with a measured problem, not a language preference
Use production telemetry to determine whether the service actually misses its latency or reliability objectives, runs out of capacity, or consumes an unjustifiably large share of infrastructure. Separate time spent in application code from time waiting on databases, networks, queues, and external services: a Rust rewrite may not fix a bottleneck that is elsewhere.
As an Amazon Associate I earn from qualifying purchases.
If the service meets its objectives at an acceptable cost, there is no demonstrated rewrite benefit yet. If it does not, identify the specific constraint and its impact before choosing a remedy. A rewrite is a hypothesis to test, not a performance result to assume.
Recommended Free Tools
Compare the real alternatives
Evaluate four paths against the same observed problem. The right comparison is about this service and its workload, not abstract rankings of Ruby and Rust.
#1 Best Overall
| Option | What to establish | Main trade-off |
|---|---|---|
| Keep the current Rails service | Whether it meets service objectives at an acceptable operating cost. | Preserves existing behavior and avoids migration work, but leaves a demonstrated constraint unresolved if one exists. |
| Optimize Rails in place | Whether query behavior, caching, algorithms, background work, or deployment configuration can address the measured constraint. | May avoid a language migration; the benefit must be measured for the service rather than presumed. |
| Extract a bounded component into Rust | Whether a clear interface lets the team replace a small part, compare behavior, and expand safely. | Requires cross-language operation and compatibility work, but limits the initial cutover scope. |
| Replace the whole service with Rust | Whether the service boundary is clean and its full behavior can be inventoried and tested. | Can remove the old implementation as a whole, but makes parity, migration, and rollback more consequential. |
These are candidates, not guaranteed solutions. Measure the viable alternatives rather than treating any one of them as certain to work.
Choose a candidate with a boundary you can prove
A promising candidate has a clear interface, constrained behavior, enough traffic or resource use for a meaningful improvement, and manageable edge cases. A large, entangled Rails application is a riskier first target than a service whose inputs, outputs, and side effects can be enumerated.
Grab Engineering chose a high-QPS counter service with two main functions for its Go-to-Rust rewrite, and its authors cautioned that rewriting just to use Rust is not a strong business justification (Grab Engineering). That example illustrates candidate selection; it is not evidence that a Rails service will see the same result.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchRank #2
Benchmark your workload fairly
Compare the current service with a representative Rust implementation under equivalent hardware, input data, and traffic shape. Include the routes and background jobs that matter in production, not just a microbenchmark of an isolated function.
- Measure throughput and p50 and p99 latency under representative load.
- Record CPU and memory at idle and under load, plus cold-start behavior.
- Track database, queue, and external-service behavior so application gains are not confused with time spent waiting elsewhere.
- Measure deployment and operating cost alongside performance.
- Use equivalent seeds and hardware when comparing versions. Basecamp’s conversion plan calls out route, Action Cable, memory, cold-start, upload, and search measurements (Campfire conversion plan).
Published figures can illustrate why testing matters, but they are not forecasts for your system. Basecamp’s Campfire repository reports the following requests-per-second results for its own 2026 benchmark. It used 16 concurrent clients on an AMD Ryzen AI MAX+ 395, with four hardware threads allocated to each app (ONCE Campfire in Rust).
| Campfire page | Rails requests per second | Rust requests per second |
|---|---|---|
| Room page | 241 | 36,260 |
| Messages page | 413 | 40,872 |
| Search | 435 | 33,299 |
| Message post | 273 | 6,896 |
Those numbers describe this Campfire port and benchmark setup, not a general Rails-to-Rust ratio. A separate Grab Engineering report concerns Go, not Rails: at an indicative 1,000 QPS, its original Go service used 20 cores and its Rust version 4.5 cores; the report says shadowed p99 latency was similar or slightly worse (Grab Engineering). It demonstrates that resource savings can coexist with unimproved latency, not what a Rails rewrite will achieve.
Rank #3
Count the full cost and confirm the team can own it
Compare measured savings or product value over an explicit period with the cost of implementing the Rust service, building its parity tests, migrating traffic, running both versions, preparing rollback, training the team, handling incidents, and maintaining the result. The published case studies do not establish a universal budget, schedule, payback period, or cost reduction; calculate these for your own service.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Confirm that more than one person can review, operate, and maintain the new service, or define a credible path to that coverage. Grab Engineering identifies Rust learning and dependence on a single experienced developer as sustainability concerns (Grab Engineering). A performance gain is less valuable if the service becomes difficult to support.
Define behavioral parity before replacing Rails
Treat the existing Rails service as the behavioral reference. Inventory everything callers, users, and dependent systems can observe—not just the main response body.
Rank #4
- Status codes, headers, HTML and JSON output, authentication, and cookie behavior.
- Validation, error handling, database effects, and time-dependent behavior.
- Background jobs, uploads, and real-time events.
- Security properties, tested independently rather than inferred from matching outputs.
Use fixed reference outputs or differential comparisons to check the Rust version. Basecamp’s conversion plan describes generating golden vectors from the reference application and comparing outputs across HTML, DOM, accessibility trees, assets, Cable frames, and screenshots (Campfire conversion plan). As its authors put it, “We never port one from our reading of the docs”: they test compatibility against reference behavior.
Matching the main interface does not guarantee matching operational semantics. In the Campfire project, the Rust port kept the SQLite database, storage layout, and current cookie formats, while documenting deliberate differences. One example is replacing Redis/Resque jobs with in-process queues, which can lose queued work if the Rust process crashes. The project also documents limits involving CSRF expectations, media formats, request size, WebSocket limits, and selected legacy cookie paths (ONCE Campfire in Rust). These are project-specific trade-offs, not properties of Rails-to-Rust rewrites generally.
Cut over in stages when the service boundary permits
- Isolate a small component or endpoint. Specify its inputs, outputs, dependencies, and side effects before implementation.
- Build the Rust implementation and parity checks. Compare it with the Rails reference on representative cases, including errors and edge conditions.
- Shadow or replay traffic where safe. Compare outputs without allowing duplicate side effects; choose replay safeguards appropriate to the service.
- Route production traffic gradually. Watch the same latency, resource, error, and correctness measures used in the benchmark.
- Keep rollback available. Expand only after the new component behaves acceptably in production.
A full replacement may still be reasonable when the boundary is clean and the parity work is explicit. It raises the stakes for migration and rollback planning, so those need to be part of the decision rather than afterthoughts.
Best Value
Make the decision against evidence, not Rust’s reputation
JetBrains’ review of Rust rewrite experiences discusses both potential benefits and pitfalls, including staged migration and compatibility testing; it does not provide a controlled Rails-versus-Rust benchmark (JetBrains, “Blazingly Fast or Blazingly Hyped? A Reality Check on Rewriting in Rust”). Its early-2026 report that uutils had a 92.2% pass rate against the official GNU coreutils suite illustrates the role of compatibility testing, not Rails migration performance.
Decide based on your service’s measured bottleneck, benchmark results, complete migration cost, behavioral parity, and ability to support the Rust code. If those do not make a credible case, keep the Rails service and address the measured problem more directly.
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.




