(X) Rust Backend vs. Go Backend in Web Development
(X) Rust Backend vs. Go Backend in Web Development
Go Backend in Web
Development
Rust and Go are two of the industry’s biggest successes when it comes to developing
modern programming languages. Both languages compete in terms of backend web
development, and it’s a fierce competition. Golang and Rust are new languages, have
growing communities, and are fast and efficient. When it comes to microservice
architectures, frameworks, and apps, Rust and Go are household names on the backend.
Similarities
Rich Standard Libraries
Rust and Go share many traits, especially when it comes to web development. They both
have rich standard libraries, though Go tends to have more internet-focused protocols
such as HTTP supported of out the box.
Open-Source
Both languages are open-source, meaning no company will be yanking the source code
out from under us anytime soon, though it is worth noting that Google drives the
development of Go, while Rust is more of a community project. There are pros and cons
of company support. Go benefits from the resources and PR of a major tech company,
while Rust will never have the risk of Google-specific agendas being pushed on the
project.
Performance
Performance metrics generally put Rust squarely ahead of Go, but not by a lot. The Rust
compiler and language design allow developers to easily take advantage of optimizations
that achieve speeds comparable to the likes of C. On the other hand, Go trades a small
amount of speed for simplicity and elegant syntax.
benchmarksgame
Memory Management
Both languages claim the title of “memory-safe” but take different approaches to achieve
it. Rust catches memory errors at compile-time while Go uses a garbage collector at
runtime.
While both approaches have their pros and cons, generally speaking Rust’s compiler
optimizations result in more performant programs. Alternatively, Go’s application code is
cleaner because memory management is fully handled by the runtime.
benchmarksgame
Development Speed
There are times during the development of a web application that development speed is
more important than app speed. Python is a great example, it is one of the slowest
languages but has some of the cleanest syntax. While Go is generally faster and uses
less memory than languages like Java, C#, JavaScript, Python, and Ruby, it makes a
performance trade-off to allow for fast and simple development.
It’s also worth noting that Go and Rust are both growing in popularity. If you want to read
more on that, take a look this related article, “Rust vs Go - Which is More Popular?”.
Code Comparison
Now that we’ve compared and contrasted Rust and Go conceptually, let’s take a look at
what a simple HTTP server would look like in both languages.
fn handle_client(stream: TcpStream) {
handle_read(&stream);
handle_write(stream);
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
println!("Listening for connections on port {}", 8080);
As you’ll notice in the code above, we can spin up a fairly simple HTTP server without
anything more than the standard library, though we have to implement some of the HTTP
protocol ourselves. Notice that we include the HTTP/1.1 200 OK response directly in the
data stream we are responding with. This isn’t to say there aren’t other crates that would
make our lives easier, but out-of-the-box Rust forces us to do more of the heavy lifting
ourselves.
If you take a look at the standard HTTP create, you’ll see that it’s an intentional choice not
to standardize an implementation.
You will notably not find an implementation of sending requests or spinning up a server
in this crate. It’s intended that this crate is the “standard library” for HTTP clients and
servers without dictating any particular implementation. Note that this crate is still early
on in its lifecycle so the support libraries that integrate with the http crate are a work
in progress! Stay tuned and we’ll be sure to highlight crates here in the future.
http - Rust
import (
"encoding/json"
"net/http"
)
func main() {
http.HandleFunc("/hello", hello)
http.ListenAndServe(":8080", nil)
}
With Go, on the other hand, it’s extremely easy to spin up a production web server, we
even get support for JSON, headers, and status codes right from the standard library.
Concurrency
Concurrency is a necessity in backend applications. Some languages run in single-
threaded environments which means they use some clever tricks to simulate concurrency
without achieving true parallelism. Both Rust and Go have elegant solutions to build fully
parallel applications, but Go takes the cake again in terms of simplicity, with
the go keyword being the only syntax necessary to spin up a new thread:
go someFunc()
The Winner
As usual, there is no outright winner, the results are more nuanced than that.
Rust is Favored For…
Computation Speed
Memory usage
Fine-tuning and control over the final executable
Go is Favored For…
Simple syntax
Beginner-friendly
Developer speed
Concurrency mechanisms
One mark of a successful computer scientist, even a self-taught one, is being able to
choose good tools for a given project. It doesn’t mean you need to be an expert with every
language, database, technology, and framework under the sun, but it does mean you
need to be familiar with enough of them to make informed decisions. Being capable to
make those decisions will set you apart and give you more opportunities to advance
your programming career.