What transpired when Glauber Costa (Turso co-founder), Jarred Sumner (developer of Bun.js and CEO of Oven) and Carl Lerche (developer of Tokio and major Rust contributor) got together for an impromptu “coding for speed” panel at P99 CONF
Rust has been the darling of the performance-obsessed P99 CONF community since the conference’s inception three years ago. Even when we featured case studies of crazy-impressive performance achievements with C++, Go, and even Java, the discussion inevitably veers to “But why not Rust?”
This year, we thought: why not shake things up a bit? In addition to having expert engineers present traditional tech talks, let’s bring some luminaries together for a free-flowing discussion on Rust vs. its rising competitor: Zig. No pre-seeded questions. No pre-meet. Truly candid conversation.
We invited Glauber Costa, Turso co-founder/CEO and longtime P99 CONF supporter, to lead this panel. As a new disruptor in the database field, Turso recently wrestled with what programming language was best for their blazing fast edge database – as well as for the self-proclaimed “bunch of performance nerds” building it. Glauber and team have lived this debate and continue to revisit it with every new component they roll out.
Watch the full discussion below:
The core discussion covered topics such as:
- Glauber’s Rust vs Zig deliberations for the code added to Turso’s fork of SQLite
- Carl’s take on why Rust is so well-suited for high-performance systems and applications
- Jarred’s experiences implementing Bun in Zig, focusing on performance and productivity
- Why Jarred didn’t end up writing Bun in Rust
- The time, place, and tradeoffs of dropping down into Unsafe Rust
- The massive Rust learning curve (beyond Jarred’s atypical 2 weeks!)
Then, it came time for audience Q & A. As a tease, here’s a written look at the discussion sparked by just one part of one audience question (though to be fair, it was a question by the one-and-only Bryan Cantrill, who led a Corporate Open Source Antipatterns panel the next day):
Glauber: One of the great things about the world we live in is that both these languages are entirely open and can borrow ideas from one another. What ideas do you see Zig borrowing from Rust or vice versa? What ideas do you see in one that you would like to see in the other? Jarred, let’s start with you.
Jarred: One of the things I’d love for Zig to borrow from Rust is some limited compile-time notion, some amount of borrow checker in various scoped-like cases. Zig does not yet have enough safety features. For example, you can return a pointer to stack memory, like to a stack-allocated buffer. You just shouldn’t be able to do that. I think that’s partly just due to the fact that the language is still pretty new. One of the things that Zig borrowed from Go that I really like is defer, that you defer the keyboard and language. A difference versus the Go implementation is that it’s per scope, instead of per function. In Go, defer will append it to the end of the function, while for Zig it’s at the end of the scope. That’s often how you do resource cleanup. Sometimes I do wish there were constructors and destructors…but I have mixed feelings.
Glauber: I wish Zig at least had some form of destructors because it’s so easy to forget.
Jarred: Yeah, defer isn’t quite good enough.
Glauber: Carl, what would you like to see in Rust borrowing from Zig?
Carl: I don’t know if it’s “borrowing,” but Zig definitely compiles a lot faster. I’ve spent a lot of time sitting, wishing for Rust to compile faster. Rust could definitely benefit there. Once you get off of the borrow checker into unsafe code with Rust it’s far from ergonomic, and there are a lot of improvements that could make writing unsafe code nicer. Maybe I have a unique opinion there from working on the tokio library. We write a lot more unsafe code than typical application developers because we’re building those kinds of primitives. But, I would like it to be nicer and there’s stuff like that which could probably be borrowed from Zig.
Glauber: There are two things from Zig that I think Rust could benefit a lot from. Number one is comptime. Comptime is absolutely genius, absolutely great. I wish Rust had a feature like that – I wish every language did, to be honest. The templating system in C++ compared to comptime… it’s just not in the same league. And the second one – and this is the thing that annoys me the most about Rust – cross-compile to different platforms is such a pain. This is something that Go does really well, and Zig does a lot better than Rust. Jarred, I’m curious about those two features. How much do you use them? And do you agree they’re nice things in Zig?
Jarred: Yeah, they’re great. One example of where we use comptime: we generate the lookup table for sourcemap parsing. Sourcemaps use this encoding VLQ. If we generate this lookup table, it makes it something like 18% faster encoding the sourcemaps than before. (Originally, we were doing it at runtime). Zig makes it super easy because you can just pass the keyword. Anything that’s in the top level scope is comptime, otherwise, you pass it in the keyword comptime in a scope. So yeah, we use lots of comptime. And then for cross compilation…Right now in Bun CI, we build each object file on a Linux machine for all the different platforms, for each Zig part. That’s because each machine has a bunch of memory to make it compile faster. So we build all the Zig code on Linux, even if it’s targeting Mac OS.
Carl: At a high level, what is comptime, for those who aren’t familiar with Zig?
Jarred: Comptime lets you evaluate arbitrary code at compile time. A lot of languages have templating-like syntax, and then you have some other variation, some other way to have compile time flags and features and arguments. In Zig, it uses the same language – it’s just Zig. That’s also how the type system works. For example, the ArrayList type in the standard library receives a comptime type argument, then you have a slice that is of that type. It’s sort of like duck-typing at compile time.
Curious? Just watch it. Eavesdropping on this gathering of the minds is 20-some minutes well-spent.
Continuing the Rust/Zig conversation
We didn’t have any Bun tech talk submissions this year – but if you’re working with it, please do consider sharing your experiences with the community next year!
We were fortunate enough to have an abundance of brilliant Rust talks, plus a Zig talk that’s been lighting the socials on fire. If you enjoyed the panel discussion with Glauber, Carl, and Jarred, here are a few other tech talks that should be on the top of your P99 CONF watch list:
Expanding Horizons: A Case for Rust Higher Up the Stack
This is the talk that Carl delivered immediately before the panel. His take:
Historically associated with systems programming due to its roots in Mozilla, Rust’s promise of safety, speed, and concurrency has led to its widespread adoption at the infrastructure level. This rise to prominence raises an intriguing question: Does Rust have a place higher up the stack, an area traditionally dominated by dynamic languages? Conventional wisdom suggests that these upper-tier domains prioritize productivity over raw performance. However, this talk will challenge this notion and explore Rust’s potential benefits to application backend development.
A Deterministic Walk Down TigerBeetle’s main() Street
Aleksei Kladov dives into how TigerBeetle used Zig to implement a fully deterministic distributed system that will never fail with an out of memory error, for predictable performance and 700x faster tests!
Ingesting in Rust at Sentry
Armin Ronacher shares Sentry’s experience building a Rust based ingestion service that handles hundreds of thousands of events per second with low latency globally.
High-Level Rust for Backend Programming
Adam Chalmers explains why Rust is a great language for writing API servers and backends, based on his experiences at Cloudflare and KittyCAD.
5 Hours to 7.7 Seconds: How Database Tricks Sped up Rust Linting Over 2000X
Predrag Gruevski offers a case study in using database ideas to build a linter that looks for breaking changes in Rust library APIs.