Hi! I’m Amos, better known as @fasterthanlime.

I make articles and videos about how computers work. My content is long-form, didactic and exploratory — and often an excuse to teach Rust!

I also co-host Self-Directed Research with James.

You can read more about me, if you insist.

Feed View all

The science of loudness

My watch has a “Noise” app: it shows dB, for decibels.

My amp has a volume knob, which also shows decibels, although.. negative ones, this time.

And finally, my video editing software has a ton of meters — which are all in decibel or decibel-adjacent units.

Summer fasterthanlime update

There are news!

Cool bear Cool Bear's hot tip

TL;DR: If you’re a patron or sponsor, check your Profile page to get detailed explainers of every perk. You’ll need to log in. Duh.

Here are all the changes I’m implementing, summarized as a table:

BeforeAfter
📚 Articles remain exclusive for 6 monthsEarly access (couple weeks) for Silver tier
🎞️ No early access for video

All color is best-effort

I do not come to you with answers today, but rather some observations and a lot of questions.

The weird glitch

Recently I was editing some video and I noticed this:

A screenshot of the video, there are visible circles at various places in the image. Some of them are black, some of them are white. The image itself shows some blue and white text composited on some blurry background, which doesn’t really matter for this, and there’s a red line horizontal up in the image. It’s very confusing.

Not what the finger is pointing at — the dots.

Here are the separate layers this image is made up of: the background is a stock image I’ve licensed from Envato Elements:

A picture of a canyon, darker than you’d expect.

Because I use it as a background image, I’ve cranked down the exposition in the Color tab:

Introducing facet: Reflection for Rust

I have long been at war against Rust compile times.

Part of the solution for me was to buy my way into Apple Silicon dreamland, where builds are, like… faster. I remember every time I SSH into an x86_64 server, even the nice 64-core ones.

And another part was, of course, to get dirty with Rust itself.

I wrote Why is my Rust build so slow?, which goes in-depth into rust build performance, down to rustc self-profiling even!

The virtue of unsynn

Addressing the rumors

There have been rumors going around, in the Reddit thread for facet, my take on reflection in Rust, which happened a bit too early, but here we are, cat’s out of the bag, let’s talk about it!

Rumors that I, podcaster/youtuber fasterthanlime, want to kill serde, serialization / deserialization framework loved by many and which contributed greatly to Rust’s success, and I just wanted to address those rumors and say that…

Open sourcing the home CMS

I’ve been bragging about my website software for years! For… whew, it’s been 5 years!

A screenshot of github commits for the beginning of my website. It has commit messages like 'learning rusqlite', 'walk stuff', 'import input files', 'parse frontmatter and stuff', and 'do stuff in parallel'.

I didn't want to make a CMS! I did it out of spite!

I’ve been teasing folks about the cool things I did from the beginning — here are all the articles and series I’ve written that mention it:

The promise of Rust

The part that makes Rust scary is the part that makes it unique.

And it’s also what I miss in other programming languages — let me explain!

Rust syntax starts simple.

This function prints a number:

fn show(n: i64) { println!("n = {n}"); }

And this program calls that function — it looks like any C-family language so far, we got parentheses, we got curly brackets, we got, uhh…

That health is mental

Disclaimer:

Trigger warning: depression, talk of suicide.

It’s been a while since I wrote a mental health piece — but I think it’s important to occasionally stop, take a breather, and think about how we feel.

So.

deep breath

I’m okay, I think? Just a little restless.

A bit of personal context

For those keeping score, I went through major life events in 2023 — a divorce, a move, and the news that I might need a second round of jaw surgery.

More devops than I bargained for

Background

I recently had a bit of impromptu disaster recovery, and it gave me a hunger for more! More downtime! More kubernetes manifest! More DNS! Ahhhh!

The plan was really simple. I love dedicated Hetzner servers with all my heart but they are not very fungible.

You have to wait entire minutes for a new dedicated server to be provisioned. Sometimes you pay a setup fee, et cetera. And at some point to server static websites and serve as a K3S server, it’s simply just too big, and approximately twice the price that I should pay.

Impromptu disaster recovery

Background

im-promp-tu (im-ˈpräm(p)-(ˌ)tü)

  1. made, done, or formed on or as if on the spur of the moment: improvised

  2. composed or uttered without previous preparation: extemporaneous

Merriam-Webster

On March 18th, 2025, I thought I would look into self-hosted project management solutions — something kanban-y, but.. better?

A screenshot of WeKan, the open-source Kanban. It looks.. from another age.

This one does not spark joy.

The case for sans-io

The most popular option to decompress ZIP files from the Rust programming language is a crate simply named zip — At the time of this writing, it has 48 million downloads. It’s fully-featured, supporting various compression methods, encryption, and even supports writing zip files.

However, that’s not the crate everyone uses to read ZIP files. Some applications benefit from using asynchronous I/O, especially if they decompress archives that they download from the network.

Catching up with async Rust

In December 2023, a minor miracle happened: async fn in traits shipped.

As of Rust 1.39, we already had free-standing async functions:

pub async fn read_hosts() -> eyre::Result<Vec<u8>> { // etc. }

…and async functions in impl blocks:

impl HostReader { pub async fn read_hosts(&self) -> eyre::Result<Vec<u8>> { // etc. } }

Highlighted code in slides

I have obsessed about this long enough, I think it’s only fair I (and you!) get some content out of it.

When I started writing this article, I was working on my P99 CONF slides. Those slides happen to include some bits of code. And because I’m a perfectionist, I would like this code to be syntax highlighted, like this:

let addr: SocketAddr = config.address.parse()?; let ln = TcpListener::bind(&addr).await?; info!("🦊 {}", config.base_url);

ktls now under the rustls org

What’s a ktls

I started work on ktls and ktls-sys, a pair of crates exposing Kernel TLS offload to Rust, about two years ago.

kTLS lets the kernel (and, in turn, any network interface that supports it) take care of encryption, framing, etc., for the entire duration of a TLS connection… as soon as you have a TLS connection.

For the handshake itself (hellos, change cipher, encrypted extensions, certificate verification, etc.), you still have to use a userland TLS implementation.

State of the fasterthanlime 2024

It’s time for some personal and professional news!

TL;DR: I started a podcast with James, I’m stable on antidepressants, I’m giving a P99 CONF about my Rust/io_uring/HTTP work, I’m trying on “they/them” as pronouns, I’m open-sourcing merde_json, rubicon and others, I got a divorce in 2023, I found a new business model.

Now that we’re on the same page: let’s unpack this a bit!

Face cams: the missing guide

I try to avoid doing “meta” / “behind the scenes” stuff, because I usually feel like it has to be “earned”. How many YouTube channels are channels about making YouTube videos? Too many.

Regardless, because I’ve had the opportunity to make my own mistakes now for a few years (I started doing the video thing in earnest in 2019), and because I’ve recently made a few leaps in quality-of-life re: shooting and editing video, I thought I’d publish a few notes, if only for reference for my future self.

Just paying Figma $15/month because nothing else fucking works

My family wasn’t poor by any stretch of the imagination, but I was raised to avoid spending money whenever possible.

I was also taught “it’s a poor craftsman that blames their tools”, which apparently means “take responsibility for your fuckups”, but, to young-me, definitely sounded more like “you don’t deserve nice things”.

I was also taught from an early age that I was born a sinner, incapable of doing good by myself, and that all the earthly things were temptations, sent by the devil to corrupt me (further I guess?) but also temporary, and that I shouldn’t attach myself.

Cracking Electron apps open

I use the draw.io desktop app to make diagrams for my website. I run it on an actual desktop, like Windows or macOS, but the asset pipeline that converts .drawio files, to .pdf, to .svg, and then to .svg again (but smaller) runs on Linux.

So I have a Rust program somewhere that opens headless chromium, and loads just the HTML/JS/CSS part of draw.io I need to render my diagrams, and then use Chromium’s “print to PDF” functionality to save a PDF.

Extra credit

We’ve achieved our goals already with this series: we have a web service written in Rust, built into a Docker image with nix, with a nice dev shell, that we can deploy to fly.io.

But there’s always room for improvement, and so I wanted to talk about a few things we didn’t bother doing in the previous chapters.

Making clash-geoip available in the dev shell

Generating a docker image with nix

There it is. The final installment.

Over the course of this series, we’ve built a very useful Rust web service that shows us colored ASCII art cats, and we’ve packaged it with docker, and deployed it to https://fly.io.

We did all that without using nix at all, and then in the last few chapters, we’ve learned to use nix, and now it’s time to tell docker build goodbye, along with this whole-ass Dockerfile:

Making a dev shell with nix flakes

In the previous chapter, we’ve made a nix “dev shell” that contained the fly.io command-line utility, “flyctl”.

That said, that’s not how I want us to define a dev shell.

Our current solution has issues. I don’t like that it has import <nixpkgs>. Which version of nixpkgs is that? The one you’re on? Who knows what that is.

Also, we haven’t really seen a mechanism to use .nix files from elsewhere.

Learning Nix from the bottom up

Remember the snapshot we made allll the way back in Part 1? Now’s the time to use it.

Well, make sure you’ve committed and pushed all your changes, but when you’re ready, let’s go back in time to before we installed anything catscii-specific in our VM.

This should emulate the experience of a colleague onboarding onto the project well enough!

(I didn’t actually use VirtualBox’s snapshot feature for this, I actually set up a Ubuntu 22.10 VM on another computer entirely, but the effect should be much the same).

Doing geo-location and keeping analytics

I sold you on some additional functionality for catscii last chapter, and we got caught up in private registry / docker shenanigans, so, now, let’s resume web development as promised.

Adding geolocation

We kinda left the locat crate stubby, it doesn’t actually do any IP to location lookups. It doesn’t even have a dependency on a crate that can do that.

Using the Shipyard private crate registry with Docker

Cool bear

Wait wait wait, so we’re not talking about nix yet?

Well, no! The service we have is pretty simple, and I want to complicate things a bit, to show how things would work in both the Dockerfile and the nix scenario.

And because I don’t like contrived examples, we’re going to do something somewhat real-world: we’re going to geo-locate visitors, and track how many visits we get from each country.

Deploying catscii to fly.io

In the previous chapter, we’ve written a Dockerfile to build the catscii service inside Docker. The result is a container image that can be pushed to production!

There's more where that came from! Check out all articles ever.

Latest series View all

Building a Rust service with Nix

I often give bits and pieces of advice on how to build Rust stuff the comfy way. But it can be hard to see how everything comes together, especially when it comes to, say, deploying a web service in production.

So, let’s start from the very beginning (setting up a Linux VM), and march together towards the objective: a production-grade Rust web service, built with Nix.

Advent of Code 2022

Let’s use the Advent of Code 2022, a series of programming challenges of increasing difficulty, to learn more about the Rust programming language.

Updating fasterthanli.me for 2022

In 2020, I switched from a static site generator to something homemade.

And, as tradition commands, I did a whole write-up about it.

Since writing articles and making videos is now my full-time occupation, I took some time to upgrade futile, my server software, to the latest and greatest the Rust ecosystem has to offer.

Don't shell out!

In this series, I change a critical component of this website’s asset pipeline from “just calling a bunch of external tools” to statically linking with everything I need to process assets. It involves autoconf, CMake, Meson, CI, pkg-config, and some code crimes.

Making our own executable packer

In this series, we’ll attempt to understand how Linux executables are organized, how they are executed, and how to make a program that takes an executable fresh off the linker and compresses it - just because we can.

Advent of Code 2020

Let’s use the Advent of Code 2020, a series of programming challenges of increasing difficulty, to learn more about the Rust programming language.

Technology, as seen on TV

Enhance! In this series, we’re looking at TV depictions of technology, and reviewing how realistic they are. Of course, they’re very rarely accurate, but it’s still interesting to take a look and try to figure out what they could’ve been thinking of, and just reminisce in general.

Making our own ping

When I launched my Patreon, I vowed to explain how computers work. But in 2019, computers rarely work in isolation. So let’s take the time to write a few articles about how computers talk to each other.

Check out even more series, if you will.

Ever wonder who's behind all this content?