DEV Community

jamilxt
jamilxt

Posted on

Goose vs Rust: Can a New Language Beat Rust at Memory-Safe Performance?

A new programming language can attract attention by promising to be faster than Rust. That claim is easy to make and hard to evaluate. The more interesting question is what the language changes in order to get its results, and whether that change fits the software you need to build.

Goose is a systems language from Wouter van Oortmerssen, also known for Lobster. Its current benchmark summary reports that, across sixteen large benchmark cases, Goose's selected implementations run at a geometric-mean 1.13x to 1.19x the speed of the best safe Rust rows, depending on the C compiler backend. The same summary says Goose uses less peak memory in aggregate. Those are meaningful results, but they are not proof that Goose is a drop-in, faster replacement for Rust.

The central idea is not a magic optimizer. Goose makes compact, flat, pointer-light data layouts a natural way to represent programs. Rust can express similar layouts, but often with more explicit arena indices or other trade-offs. That difference is what makes Goose worth examining. It is also why the headline comparison needs more context.

This is a source-based comparison, not a report from a hands-on migration. I did not run the benchmark suite or build a production application in Goose. The practical verdict below is based on the language reference, the published benchmark notes, and Rust's ownership model.

The useful question is not “Is Goose faster?”

A language benchmark compresses several choices into one number: the algorithm, data representation, compiler, flags, memory strategy, and the skill of the person writing each version. A result can be valid and still answer a narrower question than its headline suggests.

The Goose benchmark summary is unusually helpful because it describes some of those choices. Its October 16, 2026 run covers sixteen benchmark programs at large sizes. The reported geometric means compare the fastest Goose implementation for each benchmark against specified C++ and Rust rows. The page also lists cases where Goose loses or comes close to Rust, rather than presenting only the wins. The benchmark summary says the aggregate favors Goose on the selected rows, while calc and some lru and scene comparisons remain losses or near-ties, depending on compiler.

That changes how to read the claim. It is evidence that Goose's design can perform well on this benchmark suite. It is not evidence that a random Rust service, command-line tool, or web backend becomes faster when rewritten in Goose.

A fair comparison should ask three things:

  • Are the workloads relevant? A compact tree, graph, or record-processing benchmark may resemble a game engine or parser more than a typical CRUD service.
  • Are the representations equivalent? If one version stores references and another stores integer handles, the benchmark is partly about the data model.
  • Can the result be reproduced? Compiler versions, build flags, generated code, and measurement procedure matter as much as the language name.

The benchmark page provides substantial row-level detail, but a reader should still inspect the source and run a workload that resembles their own application before making an adoption decision.

Goose and Rust make different memory trade-offs

Rust's defining constraint is ownership: values have clear ownership, references have lifetimes, and the compiler rejects many unsafe memory patterns before a program runs. The Rust Book's ownership chapter explains the model and the compile-time errors it prevents. This is powerful, especially when a project has many contributors and long-lived maintenance needs.

Goose makes a different set of choices. Its language reference describes roots, stores, writability, reusable pools, and relative references as part of the model. Instead of making the programmer manually manage every object with general-purpose heap allocation, Goose encourages allocating related data into typed regions and using references that fit that allocation structure. The language reference and specification define the rules.

This design aims to make compact layouts and stable typed references convenient. It can avoid the overhead of separately allocated objects and can keep related data close together. In some benchmark comparisons, the Goose author contrasts typed references into growing storage with safe Rust versions using integer indices into an arena. That is not an apples-to-apples language-only contest: it is a comparison between two ways of representing and navigating data. It is still useful, because representation is a major part of performance engineering.

The practical difference is about what the language asks you to reason about. Rust makes ownership and borrowing visible throughout the code. Goose asks you to understand allocation regions, reference validity, and the constraints of its storage model. Neither is free complexity. One may fit a particular program's shape better than the other.

What the benchmark does show

The report's best argument is not a single multiplier. It is the variety of workloads and the presence of wins, losses, and caveats.

For example, the report says Goose's records benchmark is 2.02 to 2.26 times faster than the Rust row while using 3.98 times less memory. It attributes this to variable-mode enums that store each record's payload, including inline text. In the interp case, it reports a smaller but still notable speed advantage and about half the memory use. Those results support a specific thesis: data structures that can be represented compactly and contiguously may benefit from Goose's design.

The same report also explains that the headline aggregate selects the fastest Goose implementation separately for each comparison tier, and the smallest implementation separately for memory. So the aggregate speed and memory figures do not necessarily describe one single implementation configuration. That's reasonable for a survey of best achievable results, but it should not be mistaken for the performance of one default program.

It also documents cases where Goose is not ahead. The calc row is slower than the Rust arena version in the listed run. lru loses under MSVC and wins under clang. scene loses under MSVC and is approximately level under clang. The flat blur case illustrates another important point: proving that a function is free of bounds checks does not guarantee the backend will generate the fastest code. Compiler optimization still matters.

These details make the benchmark more credible as an engineering report, not as a universal verdict. Readers should preserve the distinctions the report itself makes: compiler backend, benchmark row, memory layout, and selected implementation.

Where Rust still has the safer adoption profile

Rust's advantage is not only language safety. Its ecosystem, tooling, documentation, package conventions, and community experience reduce the risk of building and maintaining ordinary production software. Goose's reference is extensive and gives a direct goose example.goose workflow, but a language reference is not the same thing as a mature third-party library ecosystem or years of operational experience.

That matters for teams. A language is a long-term dependency on compilers, build tools, debuggers, libraries, contributors, and future maintainers. If a project depends on a rare database driver, cryptography library, operating-system binding, or deployment target, benchmark speed may not be the bottleneck. Missing integrations or unfamiliar failure modes can cost far more than a few milliseconds saved in a benchmark.

There is also a safety nuance. Goose's own specification and design claims need to be read carefully rather than translated into “same guarantees as Rust.” A language can prohibit certain unsafe behaviors and still differ in how it achieves that result, how its compiler is tested, and what guarantees its users can rely on. The project README says Goose compiles to one C file, so it is sensible to inspect generated-code behavior and the language specification before treating the safety story as equivalent to Rust's established model. This is a review question, not a claim that Goose is unsafe.

For a small project or a performance-sensitive component, evaluating Goose may be worthwhile. For a safety-critical system, a large team, or a product whose dependencies are already Rust-native, the burden of proof should be higher.

A practical decision checklist

Use this checklist before choosing between Goose and Rust:

  • Start with the bottleneck. Profile the application first. If time is spent in network waits, database queries, serialization, or inefficient algorithms, a language rewrite may not help.
  • Match the workload. Reimplement one representative hot path, not just a benchmark toy. Include input validation, allocations, error handling, and realistic data sizes.
  • Compare equivalent designs. Record whether each implementation uses arenas, indices, inline values, or separate allocations. The representation may explain more than the language label.
  • Measure more than runtime. Track peak memory, binary size, build time, compile errors, debugging effort, and the cost of integrating required libraries.
  • Review the safety contract. Read the language specification and generated-code strategy. Test boundary cases, invalid inputs, concurrency, and memory growth behavior.
  • Estimate ecosystem risk. Confirm that the language has the platform support, library coverage, and maintenance outlook your project needs.
  • Set a stop condition. Decide in advance what improvement would justify migration and what missing capability would end the experiment.

For most teams today, Rust is the lower-risk default. Goose is an interesting candidate when compact data representation is central to the workload and the project can tolerate ecosystem risk. The benchmark numbers justify curiosity and a controlled evaluation, not a wholesale rewrite.

The takeaway

Goose is not best understood as “Rust, but faster.” It is a language that makes a different memory layout strategy central, then demonstrates that strategy on a set of benchmark programs. The reported advantages are strongest where the data structures can stay compact and contiguous. The report also records losses, compiler-dependent results, and implementation choices that shape its aggregate.

If you maintain a system where memory layout is already a major performance concern, Goose deserves a small, reproducible experiment. If your priority is broad tooling, library availability, and a well-established safety model, Rust remains the more practical choice for now. The responsible next step is not to trust either camp's headline. It is to test both approaches on the same workload, with equivalent requirements and transparent measurements.

I write practical software comparisons and engineering guides. If that is useful, subscribe for the next one. It's free.

Have you tried Goose or another Rust alternative? Which workload would you trust a new language with first?

Save-worthy takeaway: Benchmark results are a reason to profile and prototype, not a migration plan. Compare data layouts, safety guarantees, ecosystem costs, and real application workloads before choosing a language.

Top comments (0)