# sirupsen/napkin-math: Latency and Throughput Numbers for Back-of-the-Envelope Estimates

> A Rust repository of memorizable performance numbers and benchmark harnesses for estimating system capacity from first principles. Useful for capacity planning interviews and design reviews, but the numbers are deliberately rounded and the harness is mid-migration.

**sirupsen/napkin-math** — Techniques and numbers for estimating system's performance from first-principles

- Repository: https://github.com/sirupsen/napkin-math
- Website: https://www.youtube.com/watch?v=IxkSlnrRFqc
- Stars: 5,763 · Forks: 238
- Language: Rust
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/sirupsen-napkin-math

## What napkin-math is for, and who actually needs it

The README states the goal directly: to collect software, numbers, and techniques to quickly estimate the expected performance of systems from first-principles. The example it gives is reading 1 GB of memory, then composing such figures into a larger question, such as the storage cost of logging for an application at 100,000 RPS. That composition step is the point. A single latency figure is trivia; chaining memory bandwidth, serialization rate, and cross-region network throughput into one estimate is the skill.

The audience is engineers who have to answer capacity questions before they have a benchmark. That includes people sizing a logging pipeline, choosing between fsync and buffered writes, or deciding whether a cross-region replication design can meet a latency budget. The README points to a SRECON talk as the best introduction to the technique, and to a newsletter with practice problems. If you want a reference table you can hold in your head, this is the shape of it. If you want a tool that produces authoritative measurements of your own hardware, it is not that, and the README says as much.

## The numbers table and why the rounding is deliberate

The core artifact is a table of operations with latency and throughput columns, plus derived columns for 1 MiB and 1 GiB. Rows run from sequential memory read/write at 0.5 ns latency and 20 GiB/s single-threaded, through random memory access at 20 ns, system calls at 300 ns, context switches at 10 μs, and on to blob storage operations in the tens to hundreds of milliseconds. Cross-region network rows are listed per pair, from NA Central to East at 25 ms up to NA West to Singapore at 180 ms, all at 25 MiB/s.

The README states the numbers are rounded for memorization, not faux precision, and adds two notes. The first says some throughput and latency numbers do not line up, and that this is intentional for ease of calculation. The second says to take the numbers with a grain of salt, naming fio as the state of the art for I/O. That is an honest framing and it changes how you should use the table: it is a tool for order-of-magnitude reasoning, not a source of truth for a specific machine. The README also says the rows the repo can refresh on a single host were re-measured on fresh GCP c4-standard-48-lssd instances on March 8, 2026, on Intel Xeon 6985P-C hardware with 48 vCPU and 180 GB RAM running Ubuntu 22.04.5 LTS. Rows outside that set carry older provenance.

Two footnoted rows deserve attention. Fast serialization and deserialization are listed at 1 GiB/s, while standard serialization and deserialization are listed at 100 MiB/s. The footnote explains that the fast case is typically a simple wire protocol that dumps bytes, and that standard serialization such as JSON falls in the slower category. Treat that split as the single most useful distinction in the table, because serialization format choices move an estimate by an order of magnitude.

## How the benchmark harness is structured, and the migration in progress

The repository layout has benches/, src/, script/, go/, newsletter/, a run wrapper, and a Cargo.toml. The README describes the active benchmark path as Criterion.rs in benches/, and says src/main.rs is still the older ad hoc harness that remains the source of truth for benches not yet fully migrated and revalidated. That is a real constraint on anyone who wants to reproduce a number: you need to know which harness owns the row you care about.

The Criterion suite currently includes blob_storage, memory_read, memory_random, hash, syscall, sort, serialization, compression, and compressed_memory_read. The README notes the SSD rows were refreshed from the older harness with NAPKIN_BENCH_FILE pointed at a RAID0 local-SSD mount, which is a good example of how environment-dependent these measurements are. The compressed_memory_read bench is described as a BitPacker integer-unpack microbenchmark, and the README warns it should not be used as a proxy for general compressed memory reads.

Cargo.toml declares a single bench target named napkin_math with harness set to false, which is the Criterion convention. The dependency list is broad and includes redis, mysql, libc, jemallocator, core_affinity, bitpacking, and sha2, with rio gated to Linux targets. Several dependencies are pinned to wildcard versions, which is worth noting before you assume a reproducible build across time. The release profile keeps debug information and disables overflow checks.

## Installing it and running the benchmark suite

The repository is a Rust crate, so the toolchain route is Cargo. You need a checkout of the repository first, then the bench target is invoked through the run wrapper rather than directly, because the wrapper sets optimization levels and Linux tuning. The README gives this exact command:

```bash
./run --bench napkin_math
```

The README states the wrapper already uses sudo internally, and warns that you will not get the right numbers when compiling in debug mode. On locked-down cloud images it says to run this once before invoking the wrapper:

```bash
sudo sysctl -w kernel.perf_event_paranoid=-1
```

That setting lowers the kernel's restriction on performance event access, which the benchmark needs. If you skip it on a hardened image, expect the run to fail rather than to produce quietly wrong output. The README also mentions NAPKIN_BENCH_FILE as the variable used to point SSD benchmarks at a specific mount, which is how the SSD rows were refreshed against a RAID0 local-SSD mount.

The README invites contributions in the form of new suites and filling out the blanks in the table. That is the honest state of the project: some cells are empty, marked with a question mark, because they have not been measured or the measurement does not generalize.

## Where the numbers mislead you

The biggest failure mode is treating a rounded figure as a measurement of your workload. The README's own note that throughput and latency numbers do not line up intentionally means you cannot cross-check one column against another and expect consistency. If you multiply a 1 GiB throughput by a latency and get a different answer than the table's own 1 GiB column, that is by design, not a bug to report.

The second failure mode is hardware drift. The re-measured rows are tied to a specific instance type and CPU generation as of March 8, 2026. A row measured on that machine may be off by a factor on a different cloud, a different core count, or a machine with different storage. The README acknowledges this by saying it continuously updates the numbers as hardware improves, which means any number you memorize has a shelf life.

The third is the harness split. If you try to reproduce an SSD figure by running the Criterion suite alone, you may be looking at a row that was refreshed through the older src/main.rs harness with a specific NAPKIN_BENCH_FILE mount. The README does not document a rollback path or a way to pin a historical measurement, so once a row is refreshed you have no in-repo record of the previous value unless it survives in git history. For a reference table that people memorize, that is a genuine gap.

Finally, the project is a set of techniques and figures, not a capacity-planning tool. There is no CLI that takes your workload description and returns an estimate. The composition is done by you, on paper or in a spreadsheet.

## Alternatives and how they differ in approach

The README itself points to fio as the state of the art for I/O measurement. The difference in approach is fundamental: fio measures the machine in front of you with configurable job files, queue depths, and I/O patterns, producing numbers specific to that hardware and that run. napkin-math gives you memorizable numbers that transfer between machines at the cost of precision. If you are sizing a specific fleet, fio answers the question. If you are in a design discussion and need to know whether a plan is off by 10x or 2x, the table is faster.

For the practice-problem side, the README points to the newsletter and an archive of problems at sirupsen.com/napkin, with solutions in the following issue. That is a different delivery mechanism for the same skill: the repository is the reference, the newsletter is the drill. Neither replaces the other, and the README says the best way to practise is to work on your own problems.

Within the repository, the Criterion suite and the older src/main.rs harness are effectively two alternatives for the same measurements, and the README's own guidance is that Criterion is the active path while the older harness still owns the unmigrated rows.

## Maintenance, licence, and what a fork costs you

The repository is not archived and the last push was on 2026-03-21. The README describes ongoing re-measurement and an active migration to Criterion, and it asks for contributions to fill in blanks and add suites. The maintenance burden for a user is low if you only read the table, because there is nothing to run. If you want to refresh numbers on your own hardware, you inherit the dependency list in Cargo.toml, which includes several wildcard-pinned crates and a Linux-only rio dependency. That means a non-Linux build will not include the same I/O path, and a future build may resolve different versions than the ones used for the published numbers.

The licence is MIT, which permits use, modification, and redistribution with the licence and copyright notice preserved. That is permissive enough for copying figures into internal documentation, though the usual caveat applies: check with your own legal function if you plan to redistribute the table as part of a product. Nothing in the repository suggests a separate licence for the numbers themselves versus the code, but the README does not address that distinction explicitly.

## Conclusion

Adopt it if you need a shared, memorizable set of performance figures for capacity arguments, and you are willing to read the README's caveats about rounding and about which harness still owns which row. Do not adopt it as a benchmark suite for procurement decisions, because the project itself says to take the numbers with a grain of salt. Verify first that the row you plan to quote is in the Criterion suite under benches/ rather than in the older src/main.rs harness, and check the Cargo.toml dependency list before you build on a machine without Linux-specific crates.

## FAQ

### What does napkin math mean in the context of sirupsen/napkin-math?

The README describes it as collecting software, numbers, and techniques to quickly estimate the expected performance of systems from first-principles, using rounded figures you can memorize and compose into larger estimates.

### What are napkin calculations according to sirupsen/napkin-math?

They are order-of-magnitude estimates built from the repository's latency and throughput table, such as reading 1 GB of memory or estimating storage cost for an application at 100,000 RPS.

### What does back of the napkin math mean for sirupsen/napkin-math?

The README frames the numbers as rounded for memorization rather than faux precision, so back-of-the-napkin here means composing approximate figures to answer capacity questions quickly instead of measuring a specific machine.

### Is sirupsen/napkin-math free?

The repository is licensed under MIT, which permits use, modification, and redistribution with the licence and copyright notice preserved. The README does not mention a paid tier for the repository itself.

## Sources

- [Issues](https://github.com/sirupsen/napkin-math/issues)
- [License: MIT](https://github.com/sirupsen/napkin-math/blob/master/LICENSE)
- [Project website](https://www.youtube.com/watch?v=IxkSlnrRFqc)
- [README](https://github.com/sirupsen/napkin-math/blob/master/README.md)
- [sirupsen/napkin-math on GitHub](https://github.com/sirupsen/napkin-math)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sirupsen-napkin-math
