# Aleksey Kladov - A Tale of Four Fuzzers (Highlights) ![rw-book-cover|256](https://tigerbeetle.com/blog/2025-11-28-tale-of-four-fuzzers/banner.webp) ## Metadata **Review**:: [readwise.io](https://readwise.io/bookreview/56544479) **Source**:: #from/readwise #from/reader **Zettel**:: #zettel/fleeting **Status**:: #x **Authors**:: [[Aleksey Kladov]] **Full Title**:: A Tale of Four Fuzzers **Category**:: #articles #readwise/articles **Category Icon**:: 📰 **URL**:: [tigerbeetle.com](https://tigerbeetle.com/blog/2025-11-28-tale-of-four-fuzzers/) **Host**:: [[tigerbeetle.com]] **Highlighted**:: [[2025-11-30]] **Created**:: [[2025-12-06]] ## Highlights - Picking the Route ([View Highlight](https://read.readwise.io/read/01kb7sfyb6x3j7rscaangba9dg)) ^961976573 - A different approach, inspired laterally by the [PCC](https://www.usenix.org/system/files/conference/nsdi15/nsdi15-paper-dong.pdf) paper, is to avoid modeling altogether, and instead to just go and *do* something, and then measure the relevant result directly, Grace Hopper style. ([View Highlight](https://read.readwise.io/read/01kb7rq05a58826ths8grak85w)) ^961968902 - You don’t first build a system, and then add a fuzzer. The process is almost the reverse — the starting point is sketching minimal interfaces that yield themselves to efficient fuzzing. ([View Highlight](https://read.readwise.io/read/01kb7s5cbxtf98ecvh838hh030)) ^961973964 - We only care about the time difference between a `.prepare` and the corresponding `.prepare_ok`s, which you can get, simply, by accepting an `Instant` — a `u64` number of nanoseconds since an unspecified start of the epoch. This is a *major* simplification for fuzzing, as time is notoriously tricky to model, and here we get it essentially for free. ([View Highlight](https://read.readwise.io/read/01kb7s9ezn4m378ckmp6yf7kfs)) ^961975539 - The trick to making the code more easily fuzzable is to minimize the interface. You want to get rid of accidental dependencies and leave only the essential ones. And to do that, it helps to apply data-oriented design principles — thinking in terms of input data, output data, and the fundamental data transformation that the system implements. ([View Highlight](https://read.readwise.io/read/01kb7sf50z9sdn6j12rj1hv9v7)) ^961975852 - For effective fuzzing, you want to test the *boundary*: you want to check a valid code, and a code which is *almost* the same, but invalid. ([View Highlight](https://read.readwise.io/read/01kb9gpy3fcrng9mzy0rbtz3d7)) ^962161054 - I see that often people try to avoid randomness in tests at all costs, and always initialize PRNG with a hard-coded seed of 42. I don’t like that, for two reasons. ([View Highlight](https://read.readwise.io/read/01kb9gv0323pmek783w6mcjxtx)) ^962161299 #opinion - Zig I think has the best design in this space. It provides you with the `std.testing.random_seed` value, which is a ready-to-use random seed that is different per run. Crucially, the seed is generated outside of the test process itself and is passed to it on the CLI. ([View Highlight](https://read.readwise.io/read/01kb9gy9a2sdza2twxj92hwn85)) ^962161526 - A nice pattern here is to run the test twice: once with a hard-coded seed to capture the “average” distribution and assert statistics, and once with a truly random seed for coverage ([View Highlight](https://read.readwise.io/read/01kb9h0ywdcyfc913ap63dza89)) ^962161602 Use determinic seed to ensure the test itself is not broken on regression. - This is our third fuzzer. It is a whole subsystem positive space fuzzer. It’s actually an exuberantly optimistic fuzzer, as it sets up an ideal lab environment with extremely predictable network latencies. While not realistic, this setup ensures that there’s a clear answer to the question of which route is the best, and that allows us to verify that the algorithm is exactly correct, and not merely crash free. ([View Highlight](https://read.readwise.io/read/01kb9hbtv5vxa01qwfdm0tghv6)) ^962163318 - Finally, the fourth fuzzer. You might guess it, we’ll go for negative space this time. We no longer care about how the Routing *should* be used by the replica, we are trying to break it. ([View Highlight](https://read.readwise.io/read/01kb9hcb2wyqpaxgs6h0nfsf0p)) ^962163334 - Now we won’t be trying to model anything in particular. We’ll have just a single instance of `Routing` and will be calling all public methods in random order, only obeying the documented invariants ([View Highlight](https://read.readwise.io/read/01kb9hcz3enr8w05y8yy0yx965)) ^962163354