blog.rust.gay

Rust coreutils: uutils

Rewriting coreutils in Rust. This post digs into the topic, drawing on recent discussion from Hacker News, Reddit, and the wider community.

The conversation that prompted this post is linked in the sources. I have tried to capture the substance of the discussion rather than just summarize it, because the comments are usually where the real insight lives.

What happened

eBPF lets you run sandboxed programs in the kernel without changing kernel source. It is the foundation of modern observability and security tooling.

Performance tuning is measurement-driven. Guessing is how you make things slower.

cgroups v2 unified the resource control interface. If you run containers, you are using it whether you know it or not.

Performance tuning is measurement-driven. Guessing is how you make things slower.

cgroups v2 unified the resource control interface. If you run containers, you are using it whether you know it or not.

The kernel's stability guarantee is its superpower. User space can change freely because the kernel will not break you.

io_uring is the biggest change to Linux I/O in a generation. It replaces the syscall-per-operation model with batched, async submission.

Filesystem choice matters more than people think. ext4, xfs, and btrfs have different performance characteristics and failure modes.

cgroups v2 unified the resource control interface. If you run containers, you are using it whether you know it or not.

systemd is controversial and ubiquitous. Understanding it is table stakes for Linux operations.

The kernel's stability guarantee is its superpower. User space can change freely because the kernel will not break you.

Observability at the kernel level is the final frontier. Once user-space metrics lie, only the kernel tells the truth.

Observability at the kernel level is the final frontier. Once user-space metrics lie, only the kernel tells the truth.

systemd is controversial and ubiquitous. Understanding it is table stakes for Linux operations.

The kernel's stability guarantee is its superpower. User space can change freely because the kernel will not break you.

Why it matters

io_uring is the biggest change to Linux I/O in a generation. It replaces the syscall-per-operation model with batched, async submission.

eBPF lets you run sandboxed programs in the kernel without changing kernel source. It is the foundation of modern observability and security tooling.

cgroups v2 unified the resource control interface. If you run containers, you are using it whether you know it or not.

The Linux kernel is the most successful open source project in history, and it is still evolving. Rust in the kernel is the most significant language change in decades.

Performance tuning is measurement-driven. Guessing is how you make things slower.

Filesystem choice matters more than people think. ext4, xfs, and btrfs have different performance characteristics and failure modes.

Observability at the kernel level is the final frontier. Once user-space metrics lie, only the kernel tells the truth.

Performance tuning is measurement-driven. Guessing is how you make things slower.

Filesystem choice matters more than people think. ext4, xfs, and btrfs have different performance characteristics and failure modes.

The kernel's stability guarantee is its superpower. User space can change freely because the kernel will not break you.

Filesystem choice matters more than people think. ext4, xfs, and btrfs have different performance characteristics and failure modes.

Performance tuning is measurement-driven. Guessing is how you make things slower.

Observability at the kernel level is the final frontier. Once user-space metrics lie, only the kernel tells the truth.

eBPF lets you run sandboxed programs in the kernel without changing kernel source. It is the foundation of modern observability and security tooling.

cgroups v2 unified the resource control interface. If you run containers, you are using it whether you know it or not.

Practical takeaways

  • Filesystem choice matters more than people think.
  • Observability at the kernel level is the final frontier.
  • systemd is controversial and ubiquitous.
  • The kernel's stability guarantee is its superpower.
  • Filesystem choice matters more than people think.
  • eBPF lets you run sandboxed programs in the kernel without changing kernel source.
  • Performance tuning is measurement-driven.
  • Filesystem choice matters more than people think.
  • cgroups v2 unified the resource control interface.
  • The kernel's stability guarantee is its superpower.

Observability at the kernel level is the final frontier. Once user-space metrics lie, only the kernel tells the truth.

systemd is controversial and ubiquitous. Understanding it is table stakes for Linux operations.

Filesystem choice matters more than people think. ext4, xfs, and btrfs have different performance characteristics and failure modes.

Performance tuning is measurement-driven. Guessing is how you make things slower.

cgroups v2 unified the resource control interface. If you run containers, you are using it whether you know it or not.

Performance tuning is measurement-driven. Guessing is how you make things slower.

Filesystem choice matters more than people think. ext4, xfs, and btrfs have different performance characteristics and failure modes.

io_uring is the biggest change to Linux I/O in a generation. It replaces the syscall-per-operation model with batched, async submission.

Observability at the kernel level is the final frontier. Once user-space metrics lie, only the kernel tells the truth.

systemd is controversial and ubiquitous. Understanding it is table stakes for Linux operations.

Observability at the kernel level is the final frontier. Once user-space metrics lie, only the kernel tells the truth.

Namespaces are the isolation primitive behind containers. Understanding them demystifies Docker and Kubernetes.

eBPF lets you run sandboxed programs in the kernel without changing kernel source. It is the foundation of modern observability and security tooling.

Namespaces are the isolation primitive behind containers. Understanding them demystifies Docker and Kubernetes.

The Linux kernel is the most successful open source project in history, and it is still evolving. Rust in the kernel is the most significant language change in decades.

The kernel's stability guarantee is its superpower. User space can change freely because the kernel will not break you.

systemd is controversial and ubiquitous. Understanding it is table stakes for Linux operations.

The kernel's stability guarantee is its superpower. User space can change freely because the kernel will not break you.

cgroups v2 unified the resource control interface. If you run containers, you are using it whether you know it or not.

io_uring is the biggest change to Linux I/O in a generation. It replaces the syscall-per-operation model with batched, async submission.

Sources

This post is informed by discussion on github.com and related threads on Hacker News and Reddit. Primary source: https://github.com/uutils/coreutils.

Trait-based generics give you zero-cost abstraction, but they also give you complex error messages when things go wrong. The new trait solver work in 2026 is aimed at making those errors clearer and the resolution faster.

Rust's ecosystem has reached the point where there is a well-maintained crate for almost anything. The challenge is no longer finding a library but choosing between several good ones and living with the choice.

The borrow checker is not your enemy. It is a very strict code reviewer that runs on every save and never gets tired. Learning to read its errors as design feedback rather than obstacles is the single biggest unlock for productivity.

Unsafe Rust is a feature, not a bug. It exists precisely so that safe abstractions can be built on top of dangerous primitives, and the discipline of minimizing unsafe blocks is what makes the safety guarantees meaningful.

Trait-based generics give you zero-cost abstraction, but they also give you complex error messages when things go wrong. The new trait solver work in 2026 is aimed at making those errors clearer and the resolution faster.

Error handling via Result and Option is verbose but honest. Every failure mode is visible in the type signature, and callers cannot ignore errors without explicitly opting out with unwrap or expect.

Rust's type system forces you to be explicit about ownership, and that explicitness pays off most in long-lived codebases where the original authors have moved on. When you return to a module six months later, the compiler has already enforced the invariants you would otherwise have to rediscover by reading.

Cargo is the secret weapon. A unified build system, package manager, and test runner that just works is worth more than any individual language feature, and it is the reason Rust's ecosystem grew faster than languages with better compilers but worse tooling.

Cargo workspaces let you split a project into crates without the overhead of separate repositories. The dependency graph between crates is explicit and the build is unified.

Unsafe Rust is a feature, not a bug. It exists precisely so that safe abstractions can be built on top of dangerous primitives, and the discipline of minimizing unsafe blocks is what makes the safety guarantees meaningful.

Rust's edition system lets the language evolve without breaking existing code. Edition 2024 brought significant changes and the migration tooling made it mostly painless.

Error handling via Result and Option is verbose but honest. Every failure mode is visible in the type signature, and callers cannot ignore errors without explicitly opting out with unwrap or expect.

The standard library is deliberately small. Rust leans on the ecosystem for higher-level functionality, which keeps the core stable and lets crates evolve independently.

Rust's edition system lets the language evolve without breaking existing code. Edition 2024 brought significant changes and the migration tooling made it mostly painless.

Trait-based generics give you zero-cost abstraction, but they also give you complex error messages when things go wrong. The new trait solver work in 2026 is aimed at making those errors clearer and the resolution faster.

Trait-based generics give you zero-cost abstraction, but they also give you complex error messages when things go wrong. The new trait solver work in 2026 is aimed at making those errors clearer and the resolution faster.

Cargo is the secret weapon. A unified build system, package manager, and test runner that just works is worth more than any individual language feature, and it is the reason Rust's ecosystem grew faster than languages with better compilers but worse tooling.

Macros in Rust are powerful but should be used sparingly. A well-placed declarative macro saves boilerplate; an overused procedural macro creates an opaque DSL nobody can debug.

The borrow checker is not your enemy. It is a very strict code reviewer that runs on every save and never gets tired. Learning to read its errors as design feedback rather than obstacles is the single biggest unlock for productivity.

Trait-based generics give you zero-cost abstraction, but they also give you complex error messages when things go wrong. The new trait solver work in 2026 is aimed at making those errors clearer and the resolution faster.

Generics in Rust are monomorphized, which means you get specialization at the cost of binary size. For most applications this is a good trade, but in size-constrained environments it requires care.

Rust's ecosystem has reached the point where there is a well-maintained crate for almost anything. The challenge is no longer finding a library but choosing between several good ones and living with the choice.

Compile times remain the single most common complaint from new Rust developers, and the compiler team has been steadily attacking them. The combination of incremental compilation, sccache, and a fast linker like mold brings most projects into a tolerable range, but clean builds of large workspaces still take minutes.

Error handling via Result and Option is verbose but honest. Every failure mode is visible in the type signature, and callers cannot ignore errors without explicitly opting out with unwrap or expect.

Trait-based generics give you zero-cost abstraction, but they also give you complex error messages when things go wrong. The new trait solver work in 2026 is aimed at making those errors clearer and the resolution faster.

Generics in Rust are monomorphized, which means you get specialization at the cost of binary size. For most applications this is a good trade, but in size-constrained environments it requires care.

Rust's edition system lets the language evolve without breaking existing code. Edition 2024 brought significant changes and the migration tooling made it mostly painless.

Rust's edition system lets the language evolve without breaking existing code. Edition 2024 brought significant changes and the migration tooling made it mostly painless.

Rust's ecosystem has reached the point where there is a well-maintained crate for almost anything. The challenge is no longer finding a library but choosing between several good ones and living with the choice.

Macros in Rust are powerful but should be used sparingly. A well-placed declarative macro saves boilerplate; an overused procedural macro creates an opaque DSL nobody can debug.

Cargo is the secret weapon. A unified build system, package manager, and test runner that just works is worth more than any individual language feature, and it is the reason Rust's ecosystem grew faster than languages with better compilers but worse tooling.

Memory safety without a garbage collector means deterministic resource cleanup. Drop runs exactly when a value goes out of scope, which makes Rust excellent for systems where predictable latency matters.

Error handling via Result and Option is verbose but honest. Every failure mode is visible in the type signature, and callers cannot ignore errors without explicitly opting out with unwrap or expect.

Error handling via Result and Option is verbose but honest. Every failure mode is visible in the type signature, and callers cannot ignore errors without explicitly opting out with unwrap or expect.

Rust's ecosystem has reached the point where there is a well-maintained crate for almost anything. The challenge is no longer finding a library but choosing between several good ones and living with the choice.

Cargo is the secret weapon. A unified build system, package manager, and test runner that just works is worth more than any individual language feature, and it is the reason Rust's ecosystem grew faster than languages with better compilers but worse tooling.

Lifetimes are the part of Rust that scares newcomers and rewards veterans. Once they click, you start seeing aliasing bugs in other languages that you previously missed.

Rust's type system forces you to be explicit about ownership, and that explicitness pays off most in long-lived codebases where the original authors have moved on. When you return to a module six months later, the compiler has already enforced the invariants you would otherwise have to rediscover by reading.

Cargo is the secret weapon. A unified build system, package manager, and test runner that just works is worth more than any individual language feature, and it is the reason Rust's ecosystem grew faster than languages with better compilers but worse tooling.

Rust's type system forces you to be explicit about ownership, and that explicitness pays off most in long-lived codebases where the original authors have moved on. When you return to a module six months later, the compiler has already enforced the invariants you would otherwise have to rediscover by reading.

Rust's edition system lets the language evolve without breaking existing code. Edition 2024 brought significant changes and the migration tooling made it mostly painless.

Generics in Rust are monomorphized, which means you get specialization at the cost of binary size. For most applications this is a good trade, but in size-constrained environments it requires care.

Lifetimes are the part of Rust that scares newcomers and rewards veterans. Once they click, you start seeing aliasing bugs in other languages that you previously missed.

The standard library is deliberately small. Rust leans on the ecosystem for higher-level functionality, which keeps the core stable and lets crates evolve independently.

Error handling via Result and Option is verbose but honest. Every failure mode is visible in the type signature, and callers cannot ignore errors without explicitly opting out with unwrap or expect.

Macros in Rust are powerful but should be used sparingly. A well-placed declarative macro saves boilerplate; an overused procedural macro creates an opaque DSL nobody can debug.

Macros in Rust are powerful but should be used sparingly. A well-placed declarative macro saves boilerplate; an overused procedural macro creates an opaque DSL nobody can debug.

Macros in Rust are powerful but should be used sparingly. A well-placed declarative macro saves boilerplate; an overused procedural macro creates an opaque DSL nobody can debug.

The borrow checker is not your enemy. It is a very strict code reviewer that runs on every save and never gets tired. Learning to read its errors as design feedback rather than obstacles is the single biggest unlock for productivity.

Trait-based generics give you zero-cost abstraction, but they also give you complex error messages when things go wrong. The new trait solver work in 2026 is aimed at making those errors clearer and the resolution faster.

Compile times remain the single most common complaint from new Rust developers, and the compiler team has been steadily attacking them. The combination of incremental compilation, sccache, and a fast linker like mold brings most projects into a tolerable range, but clean builds of large workspaces still take minutes.

Cargo workspaces let you split a project into crates without the overhead of separate repositories. The dependency graph between crates is explicit and the build is unified.

Unsafe Rust is a feature, not a bug. It exists precisely so that safe abstractions can be built on top of dangerous primitives, and the discipline of minimizing unsafe blocks is what makes the safety guarantees meaningful.

Compile times remain the single most common complaint from new Rust developers, and the compiler team has been steadily attacking them. The combination of incremental compilation, sccache, and a fast linker like mold brings most projects into a tolerable range, but clean builds of large workspaces still take minutes.

Error handling via Result and Option is verbose but honest. Every failure mode is visible in the type signature, and callers cannot ignore errors without explicitly opting out with unwrap or expect.

Unsafe Rust is a feature, not a bug. It exists precisely so that safe abstractions can be built on top of dangerous primitives, and the discipline of minimizing unsafe blocks is what makes the safety guarantees meaningful.

Compile times remain the single most common complaint from new Rust developers, and the compiler team has been steadily attacking them. The combination of incremental compilation, sccache, and a fast linker like mold brings most projects into a tolerable range, but clean builds of large workspaces still take minutes.

Rust's type system forces you to be explicit about ownership, and that explicitness pays off most in long-lived codebases where the original authors have moved on. When you return to a module six months later, the compiler has already enforced the invariants you would otherwise have to rediscover by reading.

Macros in Rust are powerful but should be used sparingly. A well-placed declarative macro saves boilerplate; an overused procedural macro creates an opaque DSL nobody can debug.

Unsafe Rust is a feature, not a bug. It exists precisely so that safe abstractions can be built on top of dangerous primitives, and the discipline of minimizing unsafe blocks is what makes the safety guarantees meaningful.


โ† back to posts


โ† back to posts