Latest Posts (20 found)

2026.46: The End of Jensen

Welcome back to This Week in Stratechery! As a reminder, each week, every Friday, we’re sending out this overview of content in the Stratechery bundle; highlighted links are free for everyone . Additionally, you have complete control over what we send to you. If you don’t want to receive This Week in Stratechery emails (there is no podcast), please uncheck the box in your delivery settings . On that note, here were a few of our favorites this week. Presented by Agentic commerce purchases with Link, Stripe’s digital wallet that works surprisingly well for agents, grew 38x in September. The catalyst was consumer agents like Muse and Instinct. Filling out a web form is not a value-add activity for anyone. No one chooses to fill out web forms in their spare time. That’s why these agents have been particularly useful.  I’ve written about how these platforms are giving ordinary people an AI agent with a computer, enabling agents to do genuinely useful things on our behalf.  When one of those things is spending money, it needs a wallet that knows what it is, and isn’t, allowed to do. Stripe has learned that’s really about deciding how much freedom to give it. You might approve one purchase, or give it $500 for flights this week, and let it figure out the rest. The wallet’s job is to keep it within those lines while handling everything between “go buy this” and the purchase actually happening. That’s what Stripe is building with Link: You approve what it spends, it can come back to you if the final price changes, and eligible purchases can even come with protection if the agent makes a mistake. You can use Link on Muse, Instinct, as well as many other of the agents you might use already. This week’s Stratechery video is on AI on the Ballot . The Shocking Demise of Jensen Huang. This week’s coverage was dominated, unsurprisingly, by the shocking and sudden end of Jensen Huang’s 32 year tenure as CEO of Nvidia. The end came on Thursday morning, and just a few hours later, we recorded a Sharp Tech episode recounting Huang’s legendary history, figuring out what happened, and looked forward to what this might mean for Nvidia, the tech industry, and America going forward. Also see Andrew’s view from DC, Jensen Huang Was Always Going to Lose , and listen to Wednesday’s episode of Sharp China about the geopolitical angle, and Thursday’s Dithering about both the parallels and differences between Steve Jobs and Apple. — Ben Thompson Enterprise, Consumer and Intel.  The more things change, the more they stay the same: Intel remains on the back foot in the AI era, and the foundry dreams continue to flounder. On the heels of disappointing earnings and 2027 guidance that promises yet more letdowns, Ben’s Update on Wednesday examined the state of America’s would-be national champion by drawing comparisons to AMD, an Intel peer that’s red-hot right now. To understand why one company is capitalizing on skyrocketing enterprise demand while the other confronts flatlining consumer sales, the answer starts with chips chiplets and leads to more profound questions about culture, Intel’s nature, and its bifurcated strategy for the long-term (and, for subscribers, look forward to more on this topic in Sunday’s Sharp Tech mailbag episode).  — Andrew Sharp And Then There’s Professional Basketball. As a palate cleanser after a week of Jensen drama, this week’s Greatest of All Talk was a look at the top and bottom of the NBA after the first three weeks. On the euphoric side of the ledger we have Warriors fans (pre-Steph injury), Lakers fans, Spurs fans, and on the other end spectrum there is nothing positive to say in Brooklyn, a familiar malaise in Cleveland, and precisely one silver lining in Salt Lake City. All of it was a great time; we also hit Adam’s experience with the NBA in Mexico City last weekend, the hardest working players in NBA history, and an anxiety-inducing conversation about the number one pick, AJ Dybantsa.  — AS Jensen Huang’s Affair, The Culper Report, Huang’s Righteousness — Nvidia CEO Jensen Huang admitted to an affair with a Chinese spy, and that might not be the end of his troubles. I hope he survives, but his influence will never be the same. The Jensen Huang Story Gets Worse, Washington vs. New York, Silicon Valley — The Jensen Huang story got worse for him on Monday; the real risk for Huang is governance, even more than national security. Who benefits? Intel Earnings, AMD Earnings, Intel and AMD’s Divergence — Intel and AMD’s diverging earnings point to fundamental historical differences, and make me wonder if Intel needs to find a new (old) path. An Interview With Roblox CEO David Baszucki About Aggregating Play — An interview with Roblox CEO David Baszucki about how AI is transforming game creation, and why that opens up huge opportunities to both enable developers and make Roblox both an Aggregator and a platform. Jensen Huang Was Always Going to Lose — Jensen Huang spent four years substituting his own judgment for that of the U.S. government. His downfall was inevitable, and probably isn’t over. The Jensen Huang Affair Jensen Fired How Cisco Got Bullwhipped Indonesia’s Mega Rice Failure Jensen Huang Likely Out at Nvidia; The Megaspeed Maelstrom in D.C.; APEC in Seven Days; Legislation That May Come Next Agony and Ecstasy After Three Weeks, The “Earn Their Ice” All-Stars, Difficult Conversations About AJ and Season Ticket Holder Decorum Subscriber Mail: Twitter, Microsoft, Bending Spoons, Movie Reviews Nvidia After Jensen Huang, What Huang Meant to the AI Ecosystem, Washington Gets Its Revenge

0 views

Probabilistic data structures in Go

Probabilistic data structures give you approximate answers to questions about the data they handle. Does the set contain a certain item? How many unique items are in the collection? Which items appear most often? Unlike deterministic structures like sets and frequency tables, the answers might not be exact, but in return, you can drastically reduce memory usage. In this post, we'll talk about what probabilistic structures are, how they work, and what kinds of guarantees they provide. I'll also introduce unsure — a package that implements these structures in Go. It's simple (the core logic for each data structure is 100–300 LOC), fast (usually several times faster than other implementations), and has no dependencies except for the standard library. Bloom filter • Count-min sketch • HyperLogLog • T-digest • Top-k A Bloom filter is a set that trades certainty for space. It can tell you that an item is definitely not in the set, or that it probably is (which might be a false positive). The filter doesn't actually store the items, so it's much more compact than a regular set. For example, a regular set with 1,000,000 distinct 8-byte strings takes about 64 MB. A Bloom filter for the same strings, with a 1% false positive rate, uses only 1.24 MB (about 10 bits per item) — that's 50 times smaller. The size of the filter doesn't depend on the item size, so the difference gets even bigger with longer strings. A Bloom filter often resides in memory and helps minimize expensive I/O operations such as disk reads or network calls. You check if an item is in the filter, and if the answer is "no", you skip the costly lookup. If the answer is "yes", you still have to perform the lookup because it might be a false positive. The filter is sized for the given number of items with a given false positive rate. You can add more, but the false positive rate will go up. You can add an item to a Bloom filter and check if an item is in the filter, but you cannot delete an item, count the number of items, or iterate over them. Bloom filter 1 is a large array of m bits, all set to zero at first. To add an item, you compute k hash values for it and set the k bits at those positions: To check if an item is in the filter, you compute the same k hashes and check if all k bits are set: The k bits are randomly distributed throughout the entire array. When the filter is larger than the CPU cache, each bit access could result in a cache miss, so a lookup may wait on memory k times. Unsure uses a blocked Bloom filter 2 . The bit array is divided into 512-bit blocks, each matching the size of a CPU cache line. When you add or check an item, it is hashed once: part of the hash selects a block, and the rest selects k bits within that block. Each add or check only accesses one cache line, so the filter stays fast even when it's very large. In a blocked Bloom filter, some blocks end up with more items than others, which increases the false positive rate. To make up for this, the filter needs to be a bit larger. Compared to a standard Bloom filter, it uses about 3% more memory at a 1% false positive rate, 8% more at 0.1%, and 15% more at 0.01%. The filter uses the local wyhash 3 implementation for hashing. It performs roughly the same as xxh3 4 but has a much simpler implementation, without SIMD or assembly. Here's an excerpt from the full benchmarks 5 , comparing unsure to bits-and-blooms 6 (a classic Bloom filter) and gloom 7 (a blocked one) (ns/op, lower is better): Memory, bits per item at 10M items (lower is better): Unsure is about 4× faster than bits-and-blooms and 2× faster than gloom , using 1–8% more memory than bits-and-blooms and 4–10% less than gloom . A count-min sketch is a frequency table that trades accuracy for space. It tells you approximately how many times each item has appeared. The estimate is never less than the actual count, but it can be higher . The sketch doesn't actually store the items, so it's much more compact than a regular map of per-item counts. For example, a regular map counting 1,000,000 distinct 8-byte strings takes about 64 MB. A count-min sketch for the same strings, with estimates within 0.01% of the total count (with 99% probability), uses only 0.55 MB — that's 116 times smaller. The size of the sketch doesn't depend on the number of distinct items or their size, only on the accuracy you choose. So the difference gets even bigger with more or longer strings. A count-min sketch is useful when you want to track how many times an item shows up in a large stream of events. It's often used to check if something has happened a certain number of times, like rate-limiting an IP after X requests or sending an alert after an error happens Y times. A sketch can also help decide if a key is worth keeping in the cache given how often it was requested. The sketch uses two settings: epsilon ε and delta δ . If the actual count for any given item is X and the total of all counts is N, then the estimated count for this item will usually be between X and X+ε·N. However, rarely (with a probability of δ) the estimate could be even higher. For example, if ε is 0.001, δ is 0.01, and N is 1 million, then the estimate could be off by up to 1,000 (ε·N) with at least 99% probability (1−δ), and by more than 1,000 with at most 1% probability (δ). The counting error in a sketch depends on the total of all counts, not on each individual item. Therefore, frequent items are estimated more or less accurately relative to their count, but rare items are not — the absolute error is too high for them. You can increase the per-item counter in a sketch and get the estimated count for an item, but you cannot decrease a counter or iterate over the items. Count-min sketch 8 is a table of counters with d rows and w columns, all starting at zero. Each row uses its own hash function that maps an item to one of the w counters. To add an item, you increment its counter in each row: To estimate an item's count, you take the smallest value from its d counters: With w = e/ε columns, each counter's error is at most ε·N, with probability at least 1 − 1/e. If you use d = ln(1/δ) rows, the chance that all d of the item's counters exceed its true count by more than ε·N is ≤ δ. Unsure uses a conservative update . When you add n to an item, it first finds the current estimate E (the smallest counter), then increases only the counters that are below E+n, leaving the larger ones unchanged. This keeps the same accuracy guarantee, but the actual error is about 2× lower. The tradeoff is that counts can't be decreased. Counters are 32-bit instead of the usual 64-bit, so the sketch uses 2× less memory. The item is hashed once, and each row gets its own position from that hash by salting it (multiplying by a random per-row constant). The sketch uses wyhash for hashing. Here's an excerpt from the full benchmarks 9 , comparing unsure to BoomFilters 10 (a classic count-min sketch with 64-bit counters) (ns/op, lower is better): Accuracy at ε=0.0001, N=10M additions over 1M distinct items, mean overestimate (lower is better): Unsure is about 1.5× faster for Add and 4× faster for Count, using 2× less memory with 2–2.7× lower error. HyperLogLog is a unique items counter that trades accuracy for space. It tells you approximately how many distinct items it has seen, no matter how many times each one appeared. HyperLogLog (also called a sketch from here on) doesn't actually store the items, so it's much more compact than a regular set. For example, a regular set of 1,000,000 distinct 8-byte strings takes about 64 MB. A HyperLogLog sketch counting the same strings with about 0.8% error uses only 16 KB — that's almost 4,000 times smaller. The size of the sketch doesn't depend on the number of items or their size, only on the accuracy you choose. A 16 KB sketch counts a billion items as accurately as a thousand. HyperLogLog is useful when you need to count unique things in a large stream: unique visitors to a website, unique search queries per day, or distinct values in a database column. You can merge sketches to gather data from multiple machines or segments (like by hour, page, or region). When you merge two sketches, you get the total number of unique items from both, without counting shared items twice. The sketch has one setting: the precision p , which gives a relative standard error (stdErr) of 1.04/√(2^p). A common default is p=14, which gives 0.81% error. With p=14 and 1 million distinct items: The error is relative to the count, so the standard error is the same 0.81% for a thousand items or a billion. You can add items to a sketch, get the estimated count, and merge sketches. You cannot check if a specific item was added, remove items, or list them. HyperLogLog 11 is based on a simple observation. If you hash items to random bit strings, about half of them start with 1, a quarter with 01, an eighth with 001, and so on. Seeing a hash with k leading zeros suggests there were about 2^(k+1) distinct items. Duplicates hash to the same value, so they don't affect the result. A single observation is unreliable, so the sketch divides the items into m = 2^p groups, where p is the selected precision. The first p bits of the hash pick a group (a register ), and the register keeps the highest rank (leading zeros plus one) it has seen in the rest of the hash: The count is estimated from all the registers together, using a harmonic mean of 2^register. The standard error is about 1.04/√m. Merging two sketches is just taking the maximum value from each pair of registers. The original estimator is biased when dealing with small counts (up to a few times m), so in these cases it uses a different formula called linear counting . This switch creates a sudden change in error, and some implementations (like HyperLogLog++ 12 ) address it by using large tables of bias corrections based on real data. Unsure uses the improved estimator by Otmar Ertl 13 . Instead of a harmonic mean of the registers, it works from a histogram : how many registers have value 0, value 1, and so on. A formula applied to the histogram gives an accurate estimate for any number of items, from zero to billions, so there's no need for a separate formula for small counts or for correction tables. The sketch updates the histogram whenever registers change. Most adds don't change any registers, so this is almost free. Counting always takes the same amount of time, no matter how big the sketch is. Other implementations scan all the registers on every count, which takes from microseconds to milliseconds. Registers are one byte each, and the histogram has 64 four-byte counters (256 bytes). The item is hashed once with wyhash , and the 64-bit hash is split into the register index and the rank. Here's an excerpt from the full benchmarks 14 , comparing unsure to axiom 15 (HyperLogLog with LogLog-Beta estimator and sparse mode) (ns/op, lower is better): Accuracy at p=14 (0.81% standard error), relative RMSE over 100 sketches (lower is better): Memory at p=14 after adding the given number of distinct items (lower is better): Unsure adds about as fast as axiom , counts 270–83,000× faster, and merges 2.3–2.9× faster, with the same accuracy and memory for counts above the number of registers. When there are fewer items than registers, axiom 's sparse mode makes it more accurate and compact. A t-digest is a summary of a stream of numbers that trades accuracy for space. It can give you an approximate median, 99th percentile, or any other quantile of the data. It can also estimate what fraction of the numbers are below a certain value (the CDF). The digest doesn't actually store the numbers, so it's much more compact than a sorted list. For example, to find the exact 99th percentile of 1,000,000 numbers, you'd have to keep all of them. With 64-bit floats, that takes 8 MB. A t-digest estimates the same percentile within about 0.03% of the rank (between the 98.97th and the 99.03rd percentile) using only 8 KB — 1,000 times smaller. The size of the digest doesn't depend on the number of values, only on the accuracy you choose. An 8 KB digest summarizes a billion values as well as a million. A t-digest is useful when you need quantiles over a large stream: latency percentiles for a service, the distribution of request sizes or prices, or the outlier thresholds in sensor data. You can merge digests to gather data from multiple machines or segments (like by hour, endpoint, or region). A merged digest estimates the percentiles of all values, but with less accuracy than individual digests do. The digest has one setting: the compression δ , which limits the number of centroids (see How it works below) to δ+2. A common default is δ=100, which takes 8 KB. Increasing δ uses more memory but reduces estimation error. The error is measured in ranks: a rank error of 0.03% at quantile q=0.99 means the value returned by is somewhere between the 98.97th and the 99.03rd percentile of the actual values. Tail estimates, such as q=0.99 or q=0.999, are more accurate than the median (q=0.5). You can add numbers to a digest, estimate quantiles and the CDF, and merge digests. You cannot remove numbers or list them. T-digest 16 summarizes the numbers as a sorted list of centroids . Each centroid has a mean and a weight — the number of values it represents. To estimate a quantile, the digest finds the centroids around the requested rank and interpolates between their means. The trick is in how big the centroids are allowed to grow. A scale function k(q) maps a quantile q to a number from -δ/4 to δ/4, and each centroid may only span 1 unit of k: if a centroid covers the quantiles from q₁ to q₂, then k(q₂) − k(q₁) ≤ 1. The arcsine scale function, k(q) = δ/(2π)·asin(2q-1), is steep near q=0 and q=1 and flat near the median. This means the centroids it produces are larger in the center and smaller at the ends: With 1M values and δ=100, the centroids around the median hold about 27,000 values each, those around the 99th percentile about 5,000, and the outermost ones about 500. This keeps the error near the tails small. Unsure is the merging t-digest from the Dunning and Ertl paper. New values go to a buffer of 5·δ numbers. When the buffer is full, the digest sorts it and merges it with the centroids (already sorted) in a single pass, building new centroids from left to right as long as each one fits within its span of k. Every other pass goes right to left, so that neither tail ends up with fuller centroids. , and flush the buffer first. The centroids are kept in two fixed arrays of δ+2 entries (the current list and the next one being built), along with the cumulative weights for a binary search in and . With δ=100, that's 16·102·2 + 8·103 bytes for the centroids, and 8·500 bytes for the buffer, about 8 KB in total. Centroids with weight 1 are treated as exact values rather than spread around their mean, and the exact minimum and maximum are used at the ends. So digests with few values give exact results, and and are always exact. Here's an excerpt from the full benchmarks 17 , comparing unsure to influxdata 18 (merging t-digest with the same scale function) (ns/op, lower is better): Accuracy at δ=100, mean rank error over 1M normal values (lower is better): Memory at δ=100 (lower is better): unsure 8.5 KB, influxdata 14.4 KB. Unsure adds values about 1.8× faster than influxdata , queries at the same speed, merges 7–9× faster, and uses 40% less memory at about the same accuracy. A Top-k sketch finds the k most frequent items in a stream (the "heavy hitters"), along with their approximate counts. It uses a fixed amount of memory based only on k, no matter how many different items are in the stream. To find the exact top items, you'd have to count every unique item, for example with a map of per-item counts. With millions of distinct items, that takes tens or hundreds of megabytes. A Top-k sketch for the top 1000 items takes about 360 KB, and it usually finds all of them. A Top-k sketch is useful when you want to identify the "hottest" data: the most requested URLs, the most active users, or the most common search queries. Unlike a count-min sketch, it keeps the actual items, so it can list them. returns up to k items, from the most frequent to the least frequent. Counts are estimates: they're usually exact for the most frequent items, but may be slightly lower than the actual count for less common items. The sketch works best when the stream is skewed, meaning a few items appear much more often than the others. This is common in real situations. If all items are about equally frequent, there is no clear top k, and the results become less accurate. You can add items to the sketch and get the top items with their counts, but you can't decrease counts or check items that aren't in the top k. HeavyKeeper 19 is a table of buckets that estimates item counts. It has d rows and w columns, and each item maps to one bucket in each row. Each bucket holds a fingerprint of the item and a count. To add an item, you update its bucket in each row: The item's estimated count is the largest count among its buckets. Frequent items quickly reach counts that make decay very unlikely, so they keep their buckets. Rare items keep replacing each other without affecting the frequent ones. An item that becomes frequent later in the stream can still outnumber a less frequent owner and take over its bucket. Next to the table, the sketch keeps a min-heap with the k items that have the largest estimates so far. After an item's buckets are updated, if its estimate is larger than the smallest count in the heap, the item is added to the heap, and the smallest item is removed. If the item is already in the heap, its count is increased. Unsure uses d = 2 rows of max(16k, 256) buckets, and a decay base of b = 0.8. The probabilities b^count are precomputed as 64-bit thresholds, so decay is cheap: the count c decreases if a random number is below the c-th threshold. The original HeavyKeeper uses b = 1.08⁻¹ ≈ 0.93, and more rows. A smaller b lets frequent items lock their buckets faster, which makes the sketch more precise on flat streams. However, if b is too small (like 0.5), the first items to claim buckets keep them permanently, so items that become frequent later are never counted, even if they end up being the most frequent. Using b = 0.8 keeps most of the precision and still catches most late-arriving frequent items. As for the rows, two are enough to protect frequent items from collisions in a single row, and adding more rows only makes the sketch slower. The item is hashed once. The hash is mapped to a position in each row by salting it (multiplying by a random per-row constant). The fingerprint is the top 32 bits of the hash. The heap uses the 64-bit hash to identify items, so it doesn't compare the actual item bytes. Each bucket is 8 bytes (a 32-bit fingerprint and a 32-bit count), so the table takes 256·k bytes. The heap takes about 100 bytes per item plus the item itself. The sketch uses wyhash for hashing and wyrand for random numbers. Here's an excerpt from the full benchmarks 20 , comparing unsure to keiler 21 (HeavyKeeper with b = 0.9 and d = ln k) and dgryski 22 (Filtered Space-Saving 23 ) on the Zipf s=0.8 stream (time/op, lower is better): Precision is the fraction of the reported top k that is in the true top k (higher is better): Count error is the mean of |estimate − true| / true over the reported items (lower is better): Unsure is 2–4× faster than the others for Add and 1.8–4× faster for Top. On flat streams (s=0.6), it finds the true top k with 90–97% precision, while keiler drops to 38–70% precision with a count error of 62–94%, and dgryski to 19–52% with counts 18× or more too high. On skewed streams (s=1.0), all three are about equally accurate. As engineers, we usually want exact answers from our data. But sometimes, allowing a bit of uncertainty can cut memory usage by tens, hundreds, or even thousands of times. That's where probabilistic data structures come in: To use them in Go, try the nalgeon/unsure package: Space/time trade-offs in hash coding with allowable errors by Burton H. Bloom, 1970.  ↩︎ Cache-, hash-, and space-efficient Bloom filters by Felix Putze et al., 2009.  ↩︎ Reference wyhash implementation by Wang Yi.  ↩︎ Reference xxHash implementation by Yann Collet.  ↩︎ Bloom filter benchmarks .  ↩︎ bits-and-blooms/bloom by Daniel Lemire.  ↩︎ jcalabro/gloom by Jim Calabro.  ↩︎ An improved data stream summary: the count-min sketch and its applications by Graham Cormode and S. Muthukrishnan, 2005.  ↩︎ Count-min sketch benchmarks .  ↩︎ tylertreat/BoomFilters by Tyler Treat.  ↩︎ HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm by Philippe Flajolet et al., 2007.  ↩︎ HyperLogLog in practice by Stefan Heuleet et al., 2013.  ↩︎ New cardinality estimation algorithms for HyperLogLog sketches by Otmar Ertl, 2017.  ↩︎ HyperLogLog benchmarks .  ↩︎ axiomhq/hyperloglog by Axiom.  ↩︎ Computing extremely accurate quantiles using t-digests by Ted Dunning and Otmar Ertl, 2019.  ↩︎ T-digest benchmarks .  ↩︎ influxdata/tdigest by InfluxData.  ↩︎ HeavyKeeper: An Accurate Algorithm for Finding Top-k Elephant Flows by Junzhi Gong et al., 2018.  ↩︎ Top-k benchmarks .  ↩︎ keilerkonzept/topk by KEILERKONZEPT.  ↩︎ dgryski/go-topk by Damian Gryski.  ↩︎ Efficient Computation of Frequent and Top-k Elements in Data Streams by Ahmed Metwally et al., 2005.  ↩︎ If any of the bits is not set, the item definitely was never added. If all the bits are set, the item was probably added, but it's not guaranteed (the bits could have been set by other items). Other items might hash to the same counter, so each counter value is ≥ true count. The smallest counter is the one with the fewest collisions, so it's the best estimate. 68% of the time the estimate is within 0.81% (8,100) of the true count, 95% within 1.6% (2·stdErr), 99.7% within 2.4% (3·stdErr). If the bucket is empty or owned by the item, increase its count. If the bucket is owned by another item, decay it: decrease its count by 1 with probability b^count (b < 1). When the count reaches 0, the new item takes over the bucket with a count of 1. Bloom filter checks if an item might be in a set. Count-min sketch estimates how many times each item has occurred. HyperLogLog estimates the number of distinct items. T-digest estimates quantiles of a stream of numbers. Top-k sketch identifies the most frequent items in a stream. Space/time trade-offs in hash coding with allowable errors by Burton H. Bloom, 1970.  ↩︎ Cache-, hash-, and space-efficient Bloom filters by Felix Putze et al., 2009.  ↩︎ Reference wyhash implementation by Wang Yi.  ↩︎ Reference xxHash implementation by Yann Collet.  ↩︎ Bloom filter benchmarks .  ↩︎ bits-and-blooms/bloom by Daniel Lemire.  ↩︎ jcalabro/gloom by Jim Calabro.  ↩︎ An improved data stream summary: the count-min sketch and its applications by Graham Cormode and S. Muthukrishnan, 2005.  ↩︎ Count-min sketch benchmarks .  ↩︎ tylertreat/BoomFilters by Tyler Treat.  ↩︎ HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm by Philippe Flajolet et al., 2007.  ↩︎ HyperLogLog in practice by Stefan Heuleet et al., 2013.  ↩︎ New cardinality estimation algorithms for HyperLogLog sketches by Otmar Ertl, 2017.  ↩︎ HyperLogLog benchmarks .  ↩︎ axiomhq/hyperloglog by Axiom.  ↩︎ Computing extremely accurate quantiles using t-digests by Ted Dunning and Otmar Ertl, 2019.  ↩︎ T-digest benchmarks .  ↩︎ influxdata/tdigest by InfluxData.  ↩︎ HeavyKeeper: An Accurate Algorithm for Finding Top-k Elephant Flows by Junzhi Gong et al., 2018.  ↩︎ Top-k benchmarks .  ↩︎ keilerkonzept/topk by KEILERKONZEPT.  ↩︎ dgryski/go-topk by Damian Gryski.  ↩︎ Efficient Computation of Frequent and Top-k Elements in Data Streams by Ahmed Metwally et al., 2005.  ↩︎

0 views
Unsung Today

Linear’s login helper

One of the problems I encounter with modern login screens is remembering which sign in method I used for a particular service, and I was delighted to see Linear’s login screen help me out here: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/linears-login-helper/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/linears-login-helper/1.1600w.avif" type="image/avif"> I imagine this will only work on a machine I’ve used before – otherwise it’s a chicken-and-egg situation – so it doesn’t quite solve the entirety of the problem, but I still thought it was a nice gesture.

0 views
Unsung Today

“In the face of ambiguity, refuse the temptation to guess.”

Guido van Rossum shared a remembrance of Tim Peters , an important member of the Python community, who passed away earlier this year. I do not use Python all that much, and I wasn’t familiar with Peters’s work, but among his accomplishments was the Zen of Python , which consisted of 19 principles: (The links come from Wikipedia’s version . I kept them because they provide nice context for non-programmers.) I have always been wary of design principles. Most fall pretty to the classic saying “Everything simple is false. Everything complex is unusable.” I find the vague ones uninspiring, and the specific ones too rigid to be useful – a lot of design sooner or later arrives at “it depends,” and that’s hard to capture in a pithy one-liner. But there is something about (some of) these above that feels different, and Wikipedia entry suggests people actually found them useful . Perhaps they’re more pragmatic than usual, many expressed as “X over Y,” rather than fluffy stuff like “Move fast and break things” (evil), “Make it as simple as possible, but not simpler” (easy to abuse), or “Design is not how it looks, it’s how it works” (a perversion of Jobs’s “Design is not just what it looks like and feels like. Design is how it works.”) Or maybe they’re as bad and I see them as interesting only because they’re exotic, coming from the coding realm rather than the design one? Either way, they made me think what my own design principles would be. I arrived at a few of the first kind… …but I have to think about this all more carefully. Maybe more importantly, I’m interested in principles of those principles . Should each principle have a solid example showing you exactly how it’s been helpful before? You can sense there’s a real war story behind “Now is better than never. Although never is often better than right now.” and it would be great to read it. This is a thread in progress and I will report back. In the meantime, maybe Peters’s list would be useful for you to think about your list, too? Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested . Sparse is better than dense. Readability counts. Special cases aren’t special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity , refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you’re Dutch. Now is better than never. Although never is often better than right now. If the implementation is hard to explain , it’s a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea – let’s do more of those! 1fps or 60fps, but nothing in between. True UX delight is fiber, not sugar . Design assuming your every user will become a power user. You can ignore motor memory, but motor memory will never ignore you.

0 views

Sharp Tech on Video: Nvidia After Jensen Huang, Ominous News for American AI, D.C. Gets Its Revenge

Sharp Tech is, for the first time, available on video. You have three ways to consume it: YouTube, Spotify, and here on Stratechery

0 views
iDiallo Today

So you want to buy AI for your company

Where do I start? We have Gemini 4 Hydrogen. But it sounds like you could use Claude Sonnet 5.5. Or maybe 5.4; it really depends. Have you tried Opus? We have Opus 5.2 right now. It's similar to Fable 5.2, but better for day-to-day work. It's not quite as powerful as Mythos 5.2, though. I hear the gap will narrow eventually. Opus scores 94.8 on a benchmark, while Mythos gets 96.1. Fable is a respectable 92.7, assuming you don't ask it to do anything too ambitious. Have you tried the Chinese models? DeepSeek is pretty good. You might want to start with the R1 family to test the waters before moving on to V4. Personally, I'm a Flash kind of guy, but Pro is pretty good too. The crowd favorite is GLM these days. You've got to try 5.3 Flash. Its Mixture-of-Experts architecture is state of the art, in my opinion. It scores an impressive 87.3 on the Benchmark Performance Index. But let's be serious for a minute. You're probably looking for ChatGPT. Astra is overkill unless you want to do some damage. I'd stick with GPT-6.0 Terra, not Sol! That one ate through my budget in three days. Terra gets 98.2 on the Enterprise Productivity Benchmark, while Sol gets 99.1. That extra 0.9 will cost you $14,000 a month. So go with Luna if you must. If you're feeling more adventurous, you could go with Qwen, though. I'd stick with 3.8 MoE. Don't even think about 4 Plus. It's a nightmare. Kimi K is dear to my heart, though. You can't go wrong with it. I use it alongside Codex to complement my workflow. Really great. It scored 91.6 on SWE. Those are just some of the options. If you're a programmer, you probably don't need any of that. You just want to use Claude Code. Or get Cursor. Make sure to remove Grok from the auto-selection options. You don't want Grok. If you don't know why, then you don't need to know why. Anyway, I use Jules with Antigravity now. In VS Code, I use Continue with a local R1 Flash running on Ollama. I use Qwen3.5-397B-A17B for setting up machines, and Qwen-VL to read through my camera feeds. The latter is particularly good at detecting forklifts. And that's pretty much it. A fairly simple setup, really. For the layperson, though, it's much easier: they just use the free ChatGPT tier and call it a day... Or Argon. It depends really. Google 3.6 Flash has the lowest score, but it is great for email. I mean how mean do you need your email game to be? Anyway, that's it. Nano Banana! You probably need that too. It's great with Omni or Carbon. Or wait next week when Hydrocarbon comes out.

0 views
nathan.rs Yesterday

Eliminating Nondeterminism in LLM Inference with Integer-Only Arithmetic

A while back, Thinking Machines published Defeating Nondeterminism in LLM Inference , which explained why greedy decoding isn’t deterministic in production. In theory, at temperature 0 a model always picks its single most likely next token, so the same prompt gives the same answer every time. In practice, when they sent one prompt 1,000 times, they got 80 different answers. 1 The problem is that floating-point addition is not associative . $(a + b) + c$ and $a + (b + c)$ can round differently. A GPU sums thousands of numbers for every token, and the order it sums them in depends on things like how many other requests are in the batch. Change the order, change the rounding, and occasionally change which token wins.

0 views
spf13 Yesterday

Creativity in Negative Space

We talk a lot about what AI is getting good at, and the list is impressive. It can summarize research, write clean boilerplate, translate languages, and generate striking images. Because that curve has moved so fast, people naturally assume creative work is the next domino to fall. With a slightly bigger model or a longer context window, the thinking goes, AI will write a great novel, craft a stand-up comedy special, or create a movie that actually moves you. It won’t. Fluency was never what made work creative. Creative work starts with noticing what’s missing, and more data and more compute don’t add that. AI operates entirely in positive space . Human creativity lives in negative space . Rubin’s vase : two faces, or the shape between them. In visual art and design, negative space is the unmarked area around and between the subjects. It’s easy to mistake it for empty background, but it gives a composition tension, hierarchy, and meaning. Culture and ideas work the same way. Positive space is everything that already exists in the world: every trope, pattern, sentence structure, and convention that has been written down, repeated, and absorbed into training data. Negative space is the gap in the universe where nothing exists yet. When people misunderstand creativity, it’s usually because they confuse recombination in positive space with creation in negative space. A lot of what passes for “creative” work has always been derivative: taking last year’s hit movie, last year’s enterprise software, or a competitor’s product and making the next predictable iteration. Models excel at that because recombining what already exists is what neural networks are built to do. Real creativity is different. It’s looking at the world, noticing a gap that nobody has named yet, and putting something into that gap. You assemble it from your lived experience, your scars, and your influences, but the destination sits outside the map of prior art. Strip away the marketing and a neural network is a large stack of matrices. Text goes in as numbers, gets multiplied through layers of learned weights, and comes out as a probability distribution over the next token. Training sets those weights by fitting them to a body of existing human work. After that, the model is a fixed function: the same input gives the same distribution, every time. That doesn’t mean a model can only repeat what it has seen. With billions of parameters it can land on combinations no person has tried, and ML researchers will point out that by the strict definition, models in high dimensions almost never interpolate . They’re right, but producing something new was never the difficult part. Sampling randomness (temperature) shuffles which likely answer you get. It doesn’t add insight, any more than rolling dice adds taste. What a model can’t do is tell which of those new things matters. A gap nobody has named leaves no trace in the data, so nothing in the weights marks it as missing and nothing in training rewards finding it. No matrix multiplication calculates “this should exist and doesn’t.” A model can generate a million things nobody has seen before with no way of knowing which one the world needs. The obvious objection is that people learn from prior art too. Of course they do. Writers learn from other writers, and programmers learn by reading other people’s code. The difference is that people also bring things that were never written down anywhere, like the experience of using something every day and knowing it’s wrong. I don’t think an AI would have ever created Cobra . When I was building Hugo in 2013, I kept running into the limits of flags. Even a tool as simple as Hugo already let you combine flags that didn’t make sense together: Tools like , , and handled this with subcommands, each with its own set of flags, and that’s how I wanted Hugo to work: There were already plenty of CLI frameworks in lots of languages. I tried all of the existing Go ones, and every one of them felt wrong. Most were built from code pulled out of the tool, which was never meant to be a general-purpose library, and they only supported a single level of commands. I couldn’t point to one thing that was broken. It was a feeling. I knew what I wanted Hugo’s experience to look like, and none of them could create it. That was the negative space. Nothing was in its place. I had a strong conviction that Hugo needed to work a certain way for me to want to use it, so I wrote the framework that made it possible. It turns out a lot of other people thought that was the right way to do things too. Cobra ended up underneath Kubernetes, Docker, and the GitHub CLI, and it helped define how modern command-line tools work. Years later I wrote those conventions down at cli.style . The second principle is use subcommands, not mode flags and the third is make invalid combinations impossible , which are the same two problems I had with Hugo’s flags in 2013. A model trained on every CLI library that existed in 2013 would have given me a cleaner version of the libraries I had already rejected. What I had that the data didn’t was the sense that all of them were wrong. The same boundary shows up in every form that depends on tension, timing, and human truth rather than surface polish. Take stand-up comedy. A joke is almost pure negative space. It works because two people in a room share an unspoken truth they haven’t admitted out loud, and the comedian builds a bridge toward one expectation before snapping into that silence at the exact right beat. Ask an LLM to write a stand-up set and you get the rhythm and syntax of a joke (setup, punchline, callback), but completely hollowed out of surprise. It knows what jokes sound like in positive space, without ever having lived the awkwardness, pain, or observation that makes a room laugh. Storytelling works the same way in a novel or film. A model can generate grammatically flawless prose and plot beats that follow Joseph Campbell’s hero’s journey to the letter. Yet after three pages, your eyes glaze over. Great storytelling lives in the subtext, not the plot events. It’s the line of dialogue a character refuses to say, the scene that cuts three seconds early, the weird obsession that only makes sense four chapters later. In product design, the breakthroughs that delight people come from negative space. Steve Jobs didn’t invent the MP3 player. Plenty of companies shipped MP3 players before Apple, and every one of them was iterating in positive space, arguing over storage megabytes and file folders. Apple looked at the negative space around the device (how miserable it was to get music onto it and find a song in your pocket) and built the iPod into that gap. Competitors spent the next decade copying the positive-space artifact while missing the insight that created it. This is the intuition behind the famous (if apocryphal) line attributed to Henry Ford: “If I had asked people what they wanted, they would have said faster horses.” Ask people what they want and they point at things that already exist, only faster or cheaper. Nobody can ask for what they haven’t yet imagined. Spotting the gap takes someone willing to stand in the empty space, and that’s rare even among humans. A model trained on what people already said has no way to do it. What AI has actually done is strip away the illusion that fluency and creativity are the same thing. For decades, technical execution was so expensive that we conflated the ability to produce a polished surface with the ability to create something meaningful. Now the surface is cheap. Anyone can generate five thousand words of smooth prose or a slick product mock-up in thirty seconds. A model can remix the archive of everything humans have already said. It takes a human with taste, restraint, and a point of view to notice what is still missing, and to put something real into the gap. And when positive space floods with endless, cheap variations of what we already have, negative space becomes the only thing that matters.

0 views
Unsung Yesterday

“Both of these screens end with Dig Dug dying.”

A fun video by Power Pak about the “attract mode” in a vintage videogame Dig Dug: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/both-of-these-screens-end-with-dig-dug-dying/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/both-of-these-screens-end-with-dig-dug-dying/yt1-play.1600w.avif" type="image/avif"> The attract mode played on a loop when the game was left alone in the arcade, waiting for a customer. From the name, you might assume it was just there to lure a passerby – show a fun logo, a few snippets of the game, some signature special effects and occasionally even sounds. The video argues that for Dig Dug any many other games it was a lot more than that, with its recorded sample gameplay chosen very intentionally to achieve a few goals: The video then compares it to a few games that didn’t do such a great job, and even some modern games. Reaching you how to play Showing you advanced tactics Taunting you to do better

0 views

Building Barista—Part 2: Formal Verification and TLA+

☕ Welcome to The Coder Cafe! Part 1 of Building Barista covered the architecture. Today, we explore formal verification through a real bug my tests missed. You’ll learn what model checking is, how to read a bit of TLA+, and why it catches the bugs we never think about. I spent a lot of time on formal verification at Google; this time, I pointed it at my own system. Get cozy, grab a coffee, and let’s begin! One Email a Day A quick summary of Barista : it’s a system I built that fetches hundreds of sources, gets a unique prompt per user, and sends that user one email per day with the best sources for them. Making sure Barista sends a single email per user per day is something important to me. If Alice receives the same email twice on a random day, that’s a terrible user experience. As discussed in Part 1 , Barista is a set of independent stages coordinating through Postgres. The last one, , runs every 5 minutes, looks for the users whose send time has passed, and emails each of them the posts picked by the stage. The nominal scenario: The stage starts and notices an email has to be sent to Alice. Barista calls the email provider and receives an ACK. ✅ Barista writes back in Postgres that the email to Alice was sent that day. Now the worst-case scenario: The stage starts and notices an email has to be sent to Alice. Barista calls the email provider and receives an ACK. ❌ Before writing back in Postgres that the email was sent, Barista crashes. The stage starts again and notices an email has to be sent to Alice. Barista calls the email provider again and receives an ACK. ← Duplicate email ✅ Barista writes back in Postgres that the email to Alice was sent that day. How do you prevent that? I picked my email provider for it: Plunk. Why Plunk? Because it accepts an idempotency key. When calling Plunk, I pass a key like : the user and the day. If Plunk receives the same key again, it doesn’t send anything; it replies with a 409. My code reads that 409 as “these posts were already sent” and marks them as sent. No duplicate. It was a conscious decision. Plunk is 10x more expensive per email than AWS SES, which has no idempotency key. I was happy to pay for it. So here was the state: A business decision: no duplicates, even if it costs more. A sound design, with an email provider deduplicating for me. Unit tests, integration tests, end-to-end tests. All green. Great mental model of the code. Pure intellectual control . Now, what if I told you my code had a bug? One that none of my tests caught. I only managed to find it with something called formal verification. Let’s see how. Formal Verification Before becoming an SRE, I worked in Air Traffic Management (I talked about it in Reliability Explained ). It’s a so-called safety-critical domain. You can easily imagine why. In a safety-critical system, green tests aren’t enough. That’s the blind spot of intellectual control: tests only check the scenarios we thought about. And the bugs that hurt are, by definition, the ones we didn’t think about. In domains like this, green tests aren’t the end of the conversation. Some teams go further and prove that certain bugs can’t happen. Airbus, for example, used a static analyzer called Astrée to prove that the flight control software of the A340 and A380 is free of a whole class of runtime errors. So instead of picking scenarios one by one, what if we could check all of them? That’s the idea behind formal verification: describe the system precisely, write down the properties it must respect, and let a tool check that no possible execution breaks them. Note the word: verification . It answers “did we build the thing right?”, meaning does the design respect our properties. Not to be confused with validation : “did we build the right thing?”, meaning are these the properties we actually need. A tool can do the first. The second stays on us. There are several ways to verify a system, from mathematical proofs to running real code on generated inputs. The one I used is model checking . A model checker sees a system as states (a value for every variable) and actions (a step from one state to the next). It starts from the initial state, tries every possible action, then every possible action from each new state, and so on, until it has visited every reachable state. A test follows one path. A model checker walks all of them. That’s why it finds bugs nobody writes a test for. AWS described it in 2015, in a paper on how they use formal methods: one of their DynamoDB bugs had survived design reviews, code reviews, and testing. The shortest sequence of events to trigger it was 35 steps long. At each state, the model checker checks our properties. They come in two flavors: Safety : Something bad never happens (e.g., Alice never receives the same email twice) Liveness : Something good eventually happens (e.g., Alice eventually receives her daily email) When a property breaks, we get a counterexample : the exact sequence of steps that led there. The model checker I used is TLC. It reads models written in TLA+, a language created by Leslie Lamport to describe a system as states and actions. In other words: we describe the system in TLA+, and TLC explores every state it can reach. A TLA+ spec doesn’t look like code. There are no instructions executed one after the other. Instead, each action is a formula that says two things: when the step is allowed (a condition on the current state), and what the state looks like after it (the values in the next state). TLC then tries every allowed action, in every possible order. A few symbols are enough to follow the examples below: means “is defined as” is the value of in the next state and mean “for all” and “there exists” Let’s see it on a simple example. Imagine a cafe with one croissant left and two baristas. When a customer asks for a croissant, a barista does two things: first, they check the display case to see if there’s one left; then, they sell it. The property we want is a safety one (something bad never happens): the cafe never sells a croissant it doesn’t have. In other words, the stock never goes below zero. To model this cafe, we need two variables: : how many croissants are left. It starts at 1. : where each barista is. Each one starts , moves to after checking, and ends . Now, the two actions. The first one is checking the display case: The first two lines are conditions: can only happen if barista is idle and there’s a croissant left. The last two lines describe the next state: is now selling ( means “every other barista stays where they are”), and the stock stays the same. The second action is selling: And the property, written as an invariant that must hold in every state: That’s the whole model. TLC starts from the initial state (one croissant, two idle baristas) and tries every action, in every possible order. In most orders, everything is fine. For example, barista 1 checks and sells, then barista 2 can’t check anymore because the stock is zero. But TLC finds one order that breaks the invariant: Both baristas looked at the display case before either one sold. Both saw a croissant. Both sold it. That’s how to read a counterexample: find the step where it broke (5), then walk back to the decision that made it inevitable (3). The fix is to make checking and selling a single action, so nobody can slip in between. Re-run TLC, and it explores every state without finding a violation. In a cafe, we can merge two steps. Across a network call and a database write, we can’t, and that’s exactly why idempotency keys exist. Now, let’s do the same with Barista. Back to Barista. Years after leaving Air Traffic Management, I wondered: what if I applied the same rigor here? So I wrote a TLA+ spec of the stage. The model was tiny: one user, two posts, a clock with eight slots per day, and two days. The key idea is that it tracks two things separately: what was really delivered to the user, and what Barista believes was delivered. If Barista works, both always agree. The full spec also has a few actions I’m leaving out here: the clock ticks, Rank picks new posts, and moves the next send time forward. Here are the variables (simplified): : the clock. : when user ’s next email is due. : the posts picked for ’s next email. : the idempotency keys Plunk has already seen. : the list of emails really delivered. The truth. : the posts Barista has marked as sent to . What Barista believes. And a simplified version of the action at the time: A few new pieces: defines a local name (here, the key). is a pair, our . adds to a set, and adds to the end of a list. And is a record: an email to containing these posts. Read it line by line. can only run once the send time has passed. If Plunk already knows the key, it replies with a 409 and nothing is delivered. Otherwise, the email goes out. Either way, Plunk remembers the key, and Barista marks the posts as sent. That last line is the one to watch. The real action can also end badly: Plunk delivers the email, then Barista crashes before recording anything. TLC tries that outcome too. Now the property, in the same spirit as the cafe’s : In plain English: Barista’s belief must match the truth. If a post is marked as sent, an email really contained it. I ran TLC. Guess what? Despite all the tests, despite the idempotency key I was paying 10x for, it failed on the first run . Every configuration failed, even the simplest one: no crash, no settings change. Here’s one of the counterexamples, in real times. Alice gets her email at 22:00 UTC: An outage on May 20 eats Alice’s May 21 email. The catch-up send at 01:00 UTC uses key , so the regular send at 22:00 gets a 409, and its posts are marked as sent without being delivered. Alice never gets her May 21 email. Its posts are marked as sent, so Barista will never offer them again. No error, no alert. And it happens 21 hours after everything recovered. The fun part is that I never modeled an outage. Nothing in the spec says Barista can be down. But nothing forces to run on time either: in TLA+, the clock is just another action, and TLC is free to let it tick while waits. An outage, a slow deploy, a job stuck behind another one: for the model, it’s all the same. TLC tried every possible delay and found the one crossing midnight. So what went wrong? Plunk did exactly what it promised. A 409 doesn’t mean “these posts were sent.” It means “something was already sent under this key.” My key was the day of the attempt, not the day the email was for. As long as a send ran on the day it was due, it didn’t matter. The moment one slipped past midnight, it did. Should Barista skip the catch-up, then? No. Alice should still get her May 20 email. The catch-up was right; my reading of the 409 was wrong. Ironically, I was obsessed with sending too many emails, and the very thing I was paying 10x for made me send too few, silently. Would my tests have caught it? Honestly, no. I tested a crash after the ACK, and the idempotency key handled it. I would never have written a test where runs late, past midnight UTC, followed by a regular send the next evening. And that was exactly my fear in the first place. The fix? One key per email instead of one per day. I re-ran TLC. Green. In December 2025, Martin Kleppmann, the author of Designing Data-Intensive Applications , published a post with a bold prediction: AI will make formal verification go mainstream . His argument is mostly about cost. Formal verification has always been expensive. Proving that seL4, an OS kernel of about 8,700 lines of C, was correct took around 20 person-years. For most systems, a bug was cheaper than the proof that would have prevented it. But coding agents are getting good at writing proofs. And a wrong proof isn’t dangerous: the checker rejects it, and the agent tries again. One of the issues with TLA+ has always been making sure the spec is accurate. A TLA+ spec is a model, and a model is only as good as its abstraction. TLC checks the spec, not the code. The hard part is making sure the spec describes what the code actually does. But with the rise of coding agents, especially over the last few months, I feel like this gap is shrinking. An agent can read the code and draft the spec, keep both in sync when the code changes, and turn a counterexample into a failing test against the real code. At Google, I spent a lot of time exploring formal verification, especially on convoluted logic: loops with several paths, retries, error codes. On many occasions, I found bugs despite significant test coverage. Back then, though, writing and maintaining a spec was a real investment, so it was reserved for the parts that truly justified it. That’s what’s changing. When a spec costs an afternoon instead of weeks, the question is no longer “is this part critical enough to deserve a spec?” It becomes “why not?” Does it mean software will be bug-free? No. As Kleppmann also points out, the hard part moves to the specification itself: are we checking the properties we actually care about? That’s the validation question from earlier. But think about what it took to find Barista’s bug: a property of a few lines, and a tool patient enough to try every delay, every order, every midnight. Now extend that. Maybe that’s what software engineering becomes: less time on how the code achieves something, more time on what must hold no matter what. Alice never receives the same email twice. Alice eventually receives her daily email. We write those down; agents write the code and the spec; tools check that the properties hold. Kleppmann compares it to compilers: we don’t read the machine code they produce, and maybe one day, we won’t read the code agents produce either. Will we get there? I don’t know. But it might be worth exploring in your own system: write down its invariants, and see whether a model can show you where they break. If you want to see what this pipeline picks for you, give Barista a try. Describe what you like to read, and your first email lands in your inbox in seconds. It’s free (one post a day), and every new account gets 7 days of the paid plan to try more. Resources Sources How Amazon Web Services Uses Formal Methods, Newcombe et al., CACM, 2015 Systems Correctness Practices at AWS, Brooker and Desai, ACM Queue, 2024 The Astrée Static Analyzer Prediction: AI will make formal verification go mainstream How we continuously validate formal specifications in production - Datadog One Email a Day A quick summary of Barista : it’s a system I built that fetches hundreds of sources, gets a unique prompt per user, and sends that user one email per day with the best sources for them. Making sure Barista sends a single email per user per day is something important to me. If Alice receives the same email twice on a random day, that’s a terrible user experience. As discussed in Part 1 , Barista is a set of independent stages coordinating through Postgres. The last one, , runs every 5 minutes, looks for the users whose send time has passed, and emails each of them the posts picked by the stage. The nominal scenario: The stage starts and notices an email has to be sent to Alice. Barista calls the email provider and receives an ACK. ✅ Barista writes back in Postgres that the email to Alice was sent that day. The stage starts and notices an email has to be sent to Alice. Barista calls the email provider and receives an ACK. ❌ Before writing back in Postgres that the email was sent, Barista crashes. The stage starts again and notices an email has to be sent to Alice. Barista calls the email provider again and receives an ACK. ← Duplicate email ✅ Barista writes back in Postgres that the email to Alice was sent that day. A business decision: no duplicates, even if it costs more. A sound design, with an email provider deduplicating for me. Unit tests, integration tests, end-to-end tests. All green. Safety : Something bad never happens (e.g., Alice never receives the same email twice) Liveness : Something good eventually happens (e.g., Alice eventually receives her daily email) means “is defined as” is the value of in the next state and mean “for all” and “there exists” : how many croissants are left. It starts at 1. : where each barista is. Each one starts , moves to after checking, and ends . : the clock. : when user ’s next email is due. : the posts picked for ’s next email. : the idempotency keys Plunk has already seen. : the list of emails really delivered. The truth. : the posts Barista has marked as sent to . What Barista believes. An outage on May 20 eats Alice’s May 21 email. The catch-up send at 01:00 UTC uses key , so the regular send at 22:00 gets a 409, and its posts are marked as sent without being delivered. Alice never gets her May 21 email. Its posts are marked as sent, so Barista will never offer them again. No error, no alert. And it happens 21 hours after everything recovered. The fun part is that I never modeled an outage. Nothing in the spec says Barista can be down. But nothing forces to run on time either: in TLA+, the clock is just another action, and TLC is free to let it tick while waits. An outage, a slow deploy, a job stuck behind another one: for the model, it’s all the same. TLC tried every possible delay and found the one crossing midnight. So what went wrong? Plunk did exactly what it promised. A 409 doesn’t mean “these posts were sent.” It means “something was already sent under this key.” My key was the day of the attempt, not the day the email was for. As long as a send ran on the day it was due, it didn’t matter. The moment one slipped past midnight, it did. Should Barista skip the catch-up, then? No. Alice should still get her May 20 email. The catch-up was right; my reading of the 409 was wrong. Ironically, I was obsessed with sending too many emails, and the very thing I was paying 10x for made me send too few, silently. Would my tests have caught it? Honestly, no. I tested a crash after the ACK, and the idempotency key handled it. I would never have written a test where runs late, past midnight UTC, followed by a regular send the next evening. And that was exactly my fear in the first place. The fix? One key per email instead of one per day. I re-ran TLC. Green. The Future of Software Engineering? In December 2025, Martin Kleppmann, the author of Designing Data-Intensive Applications , published a post with a bold prediction: AI will make formal verification go mainstream . His argument is mostly about cost. Formal verification has always been expensive. Proving that seL4, an OS kernel of about 8,700 lines of C, was correct took around 20 person-years. For most systems, a bug was cheaper than the proof that would have prevented it. But coding agents are getting good at writing proofs. And a wrong proof isn’t dangerous: the checker rejects it, and the agent tries again. One of the issues with TLA+ has always been making sure the spec is accurate. A TLA+ spec is a model, and a model is only as good as its abstraction. TLC checks the spec, not the code. The hard part is making sure the spec describes what the code actually does. But with the rise of coding agents, especially over the last few months, I feel like this gap is shrinking. An agent can read the code and draft the spec, keep both in sync when the code changes, and turn a counterexample into a failing test against the real code. At Google, I spent a lot of time exploring formal verification, especially on convoluted logic: loops with several paths, retries, error codes. On many occasions, I found bugs despite significant test coverage. Back then, though, writing and maintaining a spec was a real investment, so it was reserved for the parts that truly justified it. That’s what’s changing. When a spec costs an afternoon instead of weeks, the question is no longer “is this part critical enough to deserve a spec?” It becomes “why not?” Does it mean software will be bug-free? No. As Kleppmann also points out, the hard part moves to the specification itself: are we checking the properties we actually care about? That’s the validation question from earlier. But think about what it took to find Barista’s bug: a property of a few lines, and a tool patient enough to try every delay, every order, every midnight. Now extend that. Maybe that’s what software engineering becomes: less time on how the code achieves something, more time on what must hold no matter what. Alice never receives the same email twice. Alice eventually receives her daily email. We write those down; agents write the code and the spec; tools check that the properties hold. Kleppmann compares it to compilers: we don’t read the machine code they produce, and maybe one day, we won’t read the code agents produce either. Will we get there? I don’t know. But it might be worth exploring in your own system: write down its invariants, and see whether a model can show you where they break. If you want to see what this pipeline picks for you, give Barista a try. Describe what you like to read, and your first email lands in your inbox in seconds. It’s free (one post a day), and every new account gets 7 days of the paid plan to try more. Resources Sources How Amazon Web Services Uses Formal Methods, Newcombe et al., CACM, 2015 Systems Correctness Practices at AWS, Brooker and Desai, ACM Queue, 2024 The Astrée Static Analyzer Prediction: AI will make formal verification go mainstream How we continuously validate formal specifications in production - Datadog

0 views
Martin Fowler Yesterday

Bliki: Generated Glossary

When we use LLMs in a specialized domain, such as the operations of any reasonably-large organization, there is a lot of specialized vocabulary. Such words and specialized meanings will be foreign to an LLM because they aren't in its training set, making it harder for the LLM to be effective when doing tasks in that domain. One technique to aid this is to use an LLM to generate a glossary of the terminology in that domain, and make this glossary available for any LLMs doing work in those circumstances. The sources for the LLM can be any material within the organization concerned such as documents, emails, and chat logs. In some cases getting transcripts of audio or video may be helpful, although most organizations generate enough text to do the job. The glossary-generating LLM should look for single words, and phrases of several words that regularly hang out together to form a meaningful term. The generator should be asked to identify terms that are new to it, but also known terms that are being used in unfamiliar ways. The latter can often cause the most confusion. Once we have a list of specialized vocabulary we can ask the agent to produce a glossary, with definitions for each term. Some terms may be used in different ways, in which case the LLM should provide alternative definitions, with a note as to what context the differences appear in. The LLM can be asked to follow the output format of a dictionary, with a focus on precision and conciseness. Once we have a draft glossary, then human experts in that domain should review it, and amend it for cases where the LLM has got the wrong ends of sticks. We then put the glossary somewhere where any other LLM can use it. It should be in a form that's easy for the LLM to consult, and minimize the tokens the LLM should consume in order to find meaning. We should set up a schedule to review and refresh the glossary at regular intervals, by agents and humans. We should keep it in version control, so we can see how it changes over time. Large organizations often have subtly different definitions in different places, essentially following the Domain Driven Design notion of Bounded Context . Source code can be a particularly interesting bounded context, allowing folks to understand how terminology is used within a code base. Sometimes a single glossary can span several of bounded contexts, but at other times it's better to have separate glossaries for each one, allowing LLMs to consult whichever glossaries that are relevant to what they are doing. I'd urge everyone to resist any temptation to create a single, standard, glossary - I've yet to see that work. Often the value of a glossary isn't to nail down a single definition of a term, but instead to highlight its different usage in different contexts. When there are different bounded contexts it can be interesting to compare different glossaries, or to get LLMs to compare glossaries and describe differences in usage. Comparing a source-code derived glossary to a human text can be particularly instructive. If the glossary is large, it can be worthwhile to only include the terms and links to definitions as part of the initial context. The model can then use the links for only the full definitions it needs while working. A glossary can be used in several ways within Agentic Engineering . Glossaries can inform generation of code, so that names within the generated software fit the particular vocabulary of the enterprise. Sensors in a harness can check for this usage, both in the internals of the software and in the user-interface. When generating code or documents, we may introduce new bounded contexts. For example, internal names that may be used within an organization should not be exposed in a customer-facing UI, because such internal terms are likely to be only confuse a customer. In this case a customer has a different bounded context to the part of the enterprise serving them. It's often useful for glossaries to include terms that should not be used, in which case it includes advice on what other term to use instead. Terms that are deprecated can be handled in this way, with glossary entries that indicate what period of time a term should be in effect. In my conversations with people working with agents in large organizations, a common theme is the difficulty of specialized language. This encourages the activities of domain modeling, building ontologies, and constructing explicit context layers in enterprise data . Getting LLMs to generate a glossary is a simple, but useful, part of this work. Eric Nagler and Unmesh Joshi related their experiences doing this activity and thus inspired this post. Amy Pellegrini, Annie Luxton, Arun Srinivasan, Chris Ford, Daniel Terhorst-North, Dave Farley, Eric Nagler, James Shore, Jason Yip, Jimmy Nilsson, Matteo Vaccari, Michaël Le Barbier, Pete Hodgson, Pramod Sadalage, Ravi Vats, Unmesh Joshi, and Valentyn Logvynskyi commented on drafts.

0 views

Against disliteracy

Books are mortal. They die. A book is an act; it takes place in time, not just in space. It is not information, but relation. Le Guin, Always Coming Home , page 370 Reading has been ending ever since it began. Everything ends: this is the one immutable fact of the universe. Books and people and trees are all mortal and the destiny of every great library is to become so much dust. But it’s gauche to sing the funeral dirge while the subject is still up and walking. And the question of whether or not reading is ending right this moment seems always a little too eager, an effort to transform probabilities into certainties, predictions into prophecies, to peek inside the box with the cat without getting caught in a murder. A more fruitful question is, what is reading for? Why do it at all? Poet and typographer Robert Bringhurst proposes that reading “simply means paying attention to what’s in front of you and trying to make sense of it.” 1 This is what he terms a “non-material” definition of reading, a reading that encompasses both books and texts but also pictures, rivers, your lover’s face. To read words and paragraphs trains you to read the rest of the world, the way a pugilist hits a bag the better to smash someone’s face. The attention reverberates: you read and receive the wisdom the writer has carefully carved, the river slicing through rock, the bag swings back. One of the ways—perhaps the primary way—that people of a modern, literate society practice attention is by reading. Ursula Le Guin writes that reading is active, an act of attention, an absorbed alertness—not all that different from hunting, in fact, or gathering….It won’t move your mind unless you give it your mind, or your heart unless you put your heart in it. It won’t do the work for you. Le Guin, Words are My Matter , page 72 Work—the movement of energy from one system to another, eye to page, hand to keyboard, paw to snapping branch. The work of writing depends on the work of reading; reading came first. Whomever it was who first scratched the bare shape of a goat into a clay tablet had some idea of what they wanted those marks to mean when they did it. Likely it didn’t turn out exactly as they expected it to, for that is every writer’s curse. But they had an intention, an effort that they bent hand and mind towards, and afterwards they could read what that intention brought forth. You must read before you learn to write. All your efforts at writing are efforts at reading, also. A writer requires a reader but a reader is not so dependent. They can read the dry soil at the base of a tree, a crowd as it throngs a detention camp in protest and grief, the clouds of smoke that blot the sun and clog the lungs. They can read the lies that pass over every smirking autocrat’s face. The writer covets the reader; the reader covets the whole world. [I]t is the reader who reads the sense; it is the reader who grants or recognizes in an object, place, or event a certain possible readability; it is the reader who must attribute meaning to a system of signs, then decipher it. We all read ourselves into the world around us in order to glimpse what and where we are. We read to understand, or to begin to understand. We cannot do but read. Reading, almost as much as breathing, is our essential function. Manguel, A History of Reading , page 7 No doing but reading. No doing without reading, without first noticing and attending to the world to make some sense of it, to see where we might fit, or where we need, with elbows and speech and fists, to make space. We read ourselves into the world, a world that includes us, that is ours to interpret and make. We read to become aware of reality—a reality that is so often at odds with our own thriving—and in that awareness we become alert to the ways in which that reality can change. Reality is a trickster. Look at it head on and it vanishes, your sight wiped out as surely as if you stared at the sun. You have to look a little askew, to squint or peer out of the corners of your eyes. You have to be still, so as not to spook it. Very often it is fiction that shows us reality most clearly, by shifting our perspective out of the ordinary, by being just a little bit strange. So I can read in Always Coming Home about the bringing-in ceremonies of the Kesh people, in which a sick person is welcomed into a sacred place, sung to, given a comfortable spot to sleep, guided in taking various medicinal therapies, and accompanied in ritual performances that exercise both body and spirit. And in those descriptions and stories I can see how our own medical system splits the body and mind apart; how we try to heal people independent of the political, economic, and environmental systems in which they live; how that healing, however partial, persists those systems even as they make us ever sicker. I can see, also, how it could be otherwise. “[R]eality underlies imagination, and attention to reality trues and tunes imagination,” 2 Bringhurst writes, and the reverse is also true: without that attention to reality, our imagination wobbles and veers off course, flops down on the ground like a child overwhelmed in the heat. Without reading, we cannot grasp what is real and what is not, what is possible and what is changeable. Rather, we accept whatever is given, as if it were all that ever was and all that ever could be. As if we were merely recipients of the world and not creators of it. Which is why reading has so often been proscribed. “Every literate society began with literacy as a constitutive prerogative of the (male) ruling class,” 3 writes Le Guin. It didn’t stay that way, of course, but not for lack of trying. In his history of Black reconstruction, Du Bois describes a one-two punch: The fact of the matter was that in the pre-war South, there were two insuperable obstacles to a free public school system. The first was the attitude of the owners of property. They did not propose under any circumstances to be taxed for the public education of the laboring class. They believed that laborers did not need education; that it made their exploitation more difficult; and that if any of them were really worth educating, they would somehow escape their condition by their own efforts. The second obstacle was that the white laborers did not demand education, and saw no need of it, save in exceptional cases. They accepted without murmur their subordination to the slaveholders, and looked for escape from their condition only in the possibility of becoming slaveholders themselves. Education they regarded as a luxury connected with wealth. Du Bois, Black Reconstruction in America , page 641 Witness this sequence of attacks: first, prohibit reading by all but a few. Exclude Black people, women, and servants from schools and libraries. When that prohibition fails, make poverty the soldier who sends the readers back. Do not grant money for schools or teachers or books. If the people manage to pool their resources and build their own schools—as newly freed Black Americans did in the years just after the end of the Civil War—make threats against those schools until they close down. Burn them if you must. Later, fund the schools for your own children lavishly but deploy every instrument you have to make sure the schools for working people’s children are short of both good teachers and good books. Ban the books those children might use to see themselves in the world, for good measure. When some people still manage to learn to read, come at it from the other side: make the work required to scrape together a meager living so great there is no energy left at the end of the day for anything other than a dead and dreamless sleep. Cast reading and higher education as elitist, out of touch with the “real” world, childish and feminized. Make it seem a threat to the bare existence that they have, against all odds, just managed to eke out. The “real” world positioned opposite reading is a false one, a counterfeit world that is too simple and plain to be read, too hardened and heavy to be moved. It’s a facade that purports to be immutable and constant, comfortingly predictable even as it eliminates all comforts. True reality is neither so steady nor so readily perceived; it requires reading—an attention to text and subtext, to connections between texts, the keen sight of the cat as it watches the sparrow, holding its breath. The ruling class gets to wring their hands in disapproval at how few people read, as if that wasn’t the intent all along. Then, being in a position of authority, they can propose various solutions to this problem of their own making: mechanisms like pinning teacher wages to test results, or draining school funding into voucher programs, which seem to align the right incentives but do nothing to evoke the attention required for reading to take place. And rarely do these proposals suspend the other hostilities, such that schools and teachers stay poor and work remains too much, both ever-present and ever-precarious. Meanwhile, reading is framed up not as a practice for attending the world—for unmaking and remaking it anew—but as a virtuous leisure activity, good for the spirit, like taking your vitamins. It’s not as productive as, say, inserting onerous new paperwork blockades between people and their doctors; it doesn’t raise the stock price quite like laying off ten percent of your workforce. But it’s good to have read, once, and to be plausibly prepared to do so again. It’s a wonder anyone reads at all. Yet people do. And so each generation sees new, creative applications of the same old tricks to get them to stop: accelerated work cultures privilege neat summaries and charts over reading and writing; automated transcription replaces thoughtful note-taking with surveillance and the hyperaccumulation of information; vapid entertainment proliferates that requires no thought or attention at all, billions of hours of television, movies, short video that is little more than anesthetizing spectacle, a denial-of-service attack against our own minds. [W]e don’t come by stupidity naturally. On the contrary, we come into the world as intelligent creatures, curious and avid for instruction. It takes immense time and effort, individually and collectively, to dull and eventually stifle our intellectual and aesthetic capabilities, our creative perception, and our use of language. Manguel, The City of Words , page 130 This will be framed as post-literacy, as an inevitable evolution or progression. But such a framing exculpates the executors of a centuries long program to maintain an illiterate, subservient class. When we talk about an absence of literacy, about how few people seem able to read thoughtfully or deeply, we are not talking about something that merely happens , an occurrence without actor or reason, like an asteroid slicing through the atmosphere. We are witness to a strategic all-out attack and the ruins it leaves behind. We are not post-literate but dis -literate, subject to a concerted and well-funded effort to separate us from literacy, an effort proliferated across schools, workplaces, and, perhaps most perniciously, our homes and pockets. From channel surfing to doomscrolling, we have long been inundated with technology designed to stupefy and placate. The latest assault tries to transform reading from relation into information. Rather than a collaboration between reader and writer, we get knowledge stripped of its context and color, reduced to data points presented in such a way as to brook no dissent. Let the machines read for us while we lay about, listening to neat summaries of books and papers, smug in our time-saving abilities—though what, precisely, we have saved that time for remains to be seen. Let the machines write for us too, displacing thinking and making with recording, every answer to every possible question available at the barest command. No curiosity, no desire that cannot be immediately sated and therefore squashed before it comes to life. Disliteracy posits that words are simple, basic things, that questions can be answered neatly and briefly, that meaning-making is transactional rather than contested. It produces oracles and supplicants, bosses and bootlickers, tyrants and cowering subjects. But always there are those few who distract the guards and slip away and gather to plan a counter-attack. We have been fighting disliteracy for generations now, from building those first public schools to refusing orders to pull books from our library shelves, from turning off the TV to turning off our phones, to gathering for reading groups and book swaps, to writing and reading and publishing books and poems and zines and blogs, writing and reading with full hearts and minds yet alive to the world. Why would we ever stop now? On June 23rd , in a Texas federal court room, eight people were sentenced to effective life sentences for acts including printing and distributing leftist zines and running an anarchist book club. The judge in the case openly admitted that the long sentences were intended to deter people who profess similar ideologies. The move from prohibition to austerity to distraction and dismissal comes back around again, to where every effort of disliteracy ultimately aims: to forbid thinking that imagines futures where the wealthy, ruling class no longer rules. In her 1989 Massey Lectures , Ursula Franklin talks of the dangers of prescriptive technologies. As she defines them, prescriptive technologies are those in which every step along a process is preordained, designed to be followed just so. In a prescriptive process, an individual cannot exercise their own judgment, lacking both the visibility and the agency to do so. Franklin writes that the proliferation of prescriptive technologies has “created a culture of compliance” which has, in turn, “diminished resistance to the programming of people.” 4 Nearly the whole arc of our technological development in the decades since has been to ratchet up that programming, to make avoidance of it near impossible. What is so-called artificial intelligence if not a large scale effort to program people to move in accord with capital? What is the intense specialization that every industry drives toward, if not an effort to design people who can deliver only what they’ve been programmed to deliver, and nothing else? Disliteracy is the frontline of that assault, as it disarms us against that programming, makes us vulnerable to it, unable to see it clearly and so ill-equipped to interrupt it. By contrast, literacy—the skill to read deeply, to pay attention to both the explicit and implicit, to inquire and make connections—is both armor and weapon, a shield against the infantilizing counterfeit realities tossed at us day and night and a sharp knife for cutting through to the real and ever changeable world, hidden just out of sight. We live in what Adam Greenfield terms the Long Emergency : a five-alarm fire playing out over generations, in which a warming planet, neoliberal precarity, rising fascism, and a psychopathic billionaire class threaten our very survival. Nothing is more critical than arresting and mitigating this suite of threats. We must urgently and patiently build towards socialism, towards the radical redistribution of wealth, the redesign of our technologies, economies, and social structures that can live in accord with the natural world, of which we are not apart but a critical part. There is no version of that effort that does not include reading. We must understand how the billionaire-fueled technodisaster works so that we can see where to interrupt it and displace it, how to design counter-assaults and subversive movements. We must be able to see reality before us so that we can true our imagination towards different realities. Such vision requires reading in all its many forms, both the reading of words and the reading of the world. We must be able to read ourselves into the world, to write new worlds in which we can live and thrive. Reading precedes writing, but writing follows, necessarily and inevitably. This, too, is why reading is such a danger to the autocrat and the billionaire. To read is to seed your own writing, to bring forth the writing that is already in you but needs the fire of reading to set down roots. When we read, we learn not only to narrate our own lives but to reject the conformist roles that have been narrated for us; we learn that no story is ever the last. Not even the story of reading’s end. Clucking about the end of reading, pitying the child or adult who does not read—these acts not only waste time, they acquiesce. To bemoan the end of reading is to forfeit the fight before you even enter the ring. What is reading for? Reading is for liberty. And the question we must ask ourselves isn’t, is reading ending, but how are we taking up the fight? Because the fight isn’t over, not yet. Reading has been left for dead many times before, by many a wannabe despot and narcissistic technocrat. But always she gets up. Somewhere a kid picks up a book, and she straightens her back. A library opens their doors, and she spits out a tooth. A banned book is passed between friends and she rises, taking a small but steady step. Soon, she is walking along again, a little cat stepping lithely beside her. We waste our time worrying about her when we should be running to catch up. Bringhurst, What Is Reading For? , page 17.  ↩︎ Ibid. , page 7.  ↩︎ Le Guin, Words Are My Matter , page 67.  ↩︎ Franklin, The Real World of Technology , page 19.  ↩︎ View this post on the web , reply via email , or become a supporter . Bringhurst, What Is Reading For? , page 17.  ↩︎ Ibid. , page 7.  ↩︎ Le Guin, Words Are My Matter , page 67.  ↩︎ Franklin, The Real World of Technology , page 19.  ↩︎

0 views

The City of Words

Alberto Manguel approaches the question of, “Why are we together?” To which one answer is, what’s the alternative? But this is not an answer that quite satisfies. Indeed, Manguel doesn’t look for answers so much as ways of staying with the question, of spending time with stories that show how we are together, what that togetherness looks like, and what it requires of us, how it changes us. And, critically, how we are pulled apart, by whom, and to what ends. From the Epic of Gilgamesh to Don Quixote, the myth of Cassandra, and 2001: A Space Odyssey , he finds that stories are where we understand our reality, where it exists today, and where it might change tomorrow. View this post on the web , reply via email , or become a supporter .

0 views

Black Reconstruction in America

Countering contemporary stories of Reconstruction as a failure, Du Bois’s very thorough history demonstrates not only the immense strides made in the years immediately following the end of the Civil War, but also that the architects of that change were the newly freed slaves themselves. Beginning with a general strike, when enslaved people quit their work and joined the advancing Union armies, through to the establishment of hundreds of public schools, Black Americans pursued a worker-led democracy with public services open to all. That vision was felled by white Americans in both the North and South, who could not bring themselves either to acknowledge Black Americans’ contributions nor to share the economic fruits of their labor. The final chapter of the book reflects on the propaganda, a mere fifty years after the end of the war, that had already displaced a story of Black Americans’ miraculous efforts with one that reinforced both racist beliefs and the preexisting economic hierarchy. A century after the book’s publication, and we could argue that Reconstruction never ended, and many of the same challenges remain. But we have something those first Reconstructionists did not: their history to guide us. View this post on the web , reply via email , or become a supporter .

0 views
Stratechery Yesterday

An Interview With Roblox CEO David Baszucki About Aggregating Play

Listen to this post: Good morning, This week’s Stratechery Interview is with Roblox CEO David Baszucki . I’ve interviewed Baszucki twice, in February 2022 , and November 2023 . What struck me about this interview is just how much AI has changed the landscape for Roblox. This was a company predicated on the concept that anyone can make a game, but now, for the first time, literally anyone can make a game. That means a world of abundance, and in that world, there is an opportunity to be an Aggregator, and Roblox is aggressively pursuing that opportunity. To that end, we discuss how AI has changed Baszucki’s view of what is possible, what goes into a game creation harness, making games on your phone, and the power of recommendation. Then we talk about Roblox’s vision of a universal player, where a Roblox game works everywhere, and Roblox Everywhere, where Roblox developers can use the platform beyond the Roblox app. We also touch on advertising — the natural Aggregator business model — and whether Baszucki still thinks he is building the metaverse. As a reminder, all Stratechery content, including interviews, is available as a podcast; click the link at the top of this email to add Stratechery to your podcast player. On to the Interview: This interview is lightly edited for clarity. Topics: The AI Impact | A Game Creation Harness | Roblox Build | Roblox Discovery | Universal Player | Roblox Everywhere | Advertising | Metaverses David Baszucki, welcome back to Stratechery. DB: Thank you, Ben, for having me back. It’s great to be here. So this is the third time I’ve interviewed you, and I want to sort of put that in an interesting context. First, you started Roblox in 2004, you went public in 2021, you first talked to me in 2022 and again in 2023 , that’s like a nearly 20-year stretch. Now it’s 2026, and here’s my question: Is the world more different for you now, compared to three years before, than it was for the entire first two decades from starting the company to the last time we talked? DB: The changes in the world we all feel are sure happening a lot more rapidly. When we first published Roblox — I don’t know if people on this podcast remember — software used to be distributed on floppy disks and CDs. You know, the funny thing is, you’re the second person I’ve interviewed in the last two or three weeks where we’ve referenced back to fact that the reason we say packaged software is it used to actually be packaged! DB: It’s been crazy, we had the Internet, when we started the company, we had the vision of a category called immersive co-experience, sci-fi writers have been writing about the holodeck forever, and we went along our way. I’m still pro-metaverse, we can use the word metaverse, it’s okay. DB: Okay, good, we use them all. It’s Snow Crash — metaverse, holodeck, they’re all good. We started on this vision of building human co-experience, we saw the mobile age come across us, we saw the crypto age. The AI acceleration wave we’re in is faster and bigger and crazier than anything I’ve ever seen, it’s changing how we think about the product, it’s changing how people are going to create games. What’s really exciting is, when we started the company, we had this slogan called “You Make the Game”. DB: We started with that slogan, we learned along the way that the ratio of people who might want to play games to make games has drifted — more people want to just play games than make games, because historically making games has been Roblox Studio and 3D editing and writing script. We could be approaching the time where “You Make the Game” really comes true, and where making a game is accessible to everyone. It’s really fun, I’ll tell you a bit about some of the experiments we’ve been having with Roblox Build . But we’re entering an era where making a game could be as big as playing a game. I’m right there with you. We’re obviously going to touch on all those points, I think it’s probably predictable what we want to talk about. But to go back to 2023, you called AI then, “a super paintbrush and a super 3D modeler, rather than a full replacement” — Is that still how you’re thinking about AI? DB: It’s what the data is proving out. We just had our earnings call a few weeks ago , we highlighted a lot of acceleration. One, there’s various ways humans can augment with AI on Roblox, they can use MCP , which is like plugging in a model, they can use the Roblox AI assistant to help build. And what do you mean with that MCP server? You mentioned you had 5x growth quarter-over-quarter. That’s where you’re actually using Claude Code or Codex or whatever to work with Roblox? DB: People are plugging in, we can see all of them — Claude Code, Codex, other models — all being plugged into Roblox Studio to help build things. We’ve seen two games hit the top 20 made by AI, we have other metrics like the number of assets. What do you mean by “made by AI”? Because you also said 80% of games in the top 100 have AI-contributed content. DB: Touched by AI, vibe-coded directly with AI, and we can see the count of assets accelerating. DB: It’s turned out to be, I believe, somewhat faithful to what I said. This is a human paintbrush accelerator, good ideas are still very important, novel types of gameplay are very important. But people are able to flex their creativity much more quickly. We have members of the Roblox board of directors carrying a mobile phone around, building games like 15 times a day. We have people who are not necessarily engineers or product managers now building within the company, so we’re really at the dawn of a new era. You mentioned the super paintbrush, super 3D modeler, is there a super gameplay developer? Because there’s a large step between, “I have an idea for a game”, versus the actual mechanics of the game. How much can the AI do to help you as far as that goes? DB: You’re touching on the dream of what is a game creation harness versus a coding harness . Dive into it, this is super interesting. Lay out the difference and the way you’re thinking about that. DB: So everyone’s getting familiar with coding harnesses — Claude Code, Cursor, Replit, Lovable, Codex, you name it. A game is arguably much more complicated than code. As you mentioned, there’s art, there’s 3D objects, there’s scenes, there’s avatars, there can be gameplay code, there can be missions, and there can be code underneath it. So a harness that is being created to create games really has to run in multiple modalities, needs to listen to you, and if you said, “I would like a multiplayer tortoise-and-the-hare game that 100 people can play, and we’d like to do it on Venus, and I’d like it to run on all devices” — there’s a lot of different things that need to be generated there. The avatars, the assets, all of that, as well as the gameplay, which I think is a very human thing — your idea of what type of a game it is is actually very unique. So one of our board members is building a hybrid kind of Wordle-crossword game with his own vision of how this crossword game should work, and that’s very unique to him. I’m optimistic we’re still seeing that notion of a human coupled with an accelerating paintbrush in essentially a very complex harness for building games. There’s so many pieces you talked about. The asset creation piece, compared to 2023, much further along, arguably there. You could have even the video component, or the moving worlds, but then you almost have these different pieces. Do you have to build — is there going to be one harness, and one sort of — we’re going to get to your Build app in a little bit — that handles all of that? Or are you still thinking we need to do this piece-by-piece as the model gets good enough for, or we need different models maybe for the different parts of this? DB: I think just as we see with harnesses that are routing different models, even for coding now, a lot of companies have multiple models running side-by-side and their harness is optimizing. Our harness inside Build and inside Studio Build is running not just multiple models for certain things, but then there’s a second dimension of, “Are we building a scene?”, “Are we building a 3D object?”, “Are we building code?”, “Are we building an NPC?”. So yes, we are routing both by kind of specific asset that’s being created, as well as multiple models within each of those, and we’re combining some areas where we have incredible data on Roblox — for example, data that can be used to help create non-player characters, characters that act normally, side-by-side with you. But there’s also really good coding models out there, both open source and frontier, and so we see a harness being able to put all these things together. What’s the mix of those models? Say we have three categories — frontier, off-the-shelf open-source models, and models that you’ve trained specifically. And I guess even there there’s two categories, are you doing foundational models on your own, or just doing some post-training? DB: We literally have all three of those running in our Build harness. And we’re, in certain cases, optimizing the cost of frontier with the capabilities of open source. We have a Cube model — we’ve announced it — which is trained on 3D assets. Yeah, super interesting. Tell me about the Cube model. DB: The Cube model is our own 3D asset creation model trained on all of the 3D objects inside Roblox, where the developer has opted in to the training. It’s very fast, it’s very efficient, and it runs on our own hardware. When you go into Build or I go into Build and I say, “Hey, make that tortoise-and-a-hare game”, and if you describe that tortoise as somewhat unique and different, “I want the tortoise to look like this, and have a fur that looks like this, and maybe have this”, that Cube model will and may come into play and generate that tortoise for you. How does your cost structure work for this? Is it a usage thing from a developer perspective? You have the MCP server — that’s where they can bring their own, what’s the mix? DB: You sound like a product manager, because these are exactly the same discussions I had about an hour ago. The ultimate vision is something like Roblox Build is just like the creation of short-form video. Short-form video 10 years ago — all of a sudden we all figured out we can make video and edit it on our phones, amongst multiple products that was like a huge revelation. We are so on the same page, I have a whole section on short-form video later in the interview. That’s good foreshadowing. DB: Yeah. And so along comes short-form video, and we have phones, and all of a sudden we’re making and sharing video. Arguably games are a lot more complicated, they can be immersive 3D environments, multiple people can come there. They have, as I was saying, code and geometry and avatars, but that’s where Build is going — that same notion of, “I’m going to pull out my phone and create something”, some of those models are still expensive. But the dream is, we’re already testing — I think Canada went live today. We’re testing in, I think, Serbia and New Zealand, we want it available for everyone and so it creates a wonderful opportunity for us to be super efficient with our models while super powerful. It creates the opportunity for those users who want to just do hundreds of iterations to have them buy tokens as well, if they really want to dig into it, so we’re optimistic this will be free for everyone. You keep mentioning Build, I’m on your website , and this is how you describe Build: “Build is a new way to make your own Roblox game right from your phone. Just describe the game you want in your own words, and Build’s AI creates a playable game for you in real time. You don’t need any coding or game-design experience – if you can describe it, you can build it. Want to change something? Just tell Build what to adjust, and keep going until it feels right”. Is this what you always wanted? Are we going to look back and say Roblox Studio, your pride and joy, was just a stepping stone to this? DB: This was a sci-fi fantasy when we started the company, and arguably a fantasy we never thought would come true. I would say when we started the company, we couldn’t have imagined it, and for many years, I think many people in the industry were always trying to figure out ways to make editing 3D easier, “Oh, that’s a really easy consumer 3D modeler” — even the best consumer 3D modeler is still pretty complicated. It’s unbelievable, my current 3D experience right now is, I’ve gotten very into 3D printing and I’ve never opened the associated app for it at all. It’s all done in the AI and just goes straight to the printer, it’s unbelievable. I appreciate all those people who did all the actual modeling and stuff for the last few years — I’ve skipped over all of it, but it’s the same thing in digital space. DB: I would say in the last five years we started to see that maybe AI can do this and I would say it’s been in the last two to three years where the rate of acceleration has started to surprise people and as that rate of acceleration has started to surprise people, this dream becomes much more possible. There are games on Roblox right now that are earning money that have been made with Roblox Build. We have not tens or hundreds, but thousands of games that have been published in Roblox Build. It’s not live in the U.S., we’re testing, and it will be soon, so the data is already out there. What’s so interesting is you saying, “We couldn’t have imagined it”, because one of the things in our previous interviews that came across again and again was the continuity of your vision and like, “Yeah, we saw this back then, and now we’re getting there, and we’ve had this vision all the way” — and that sort of goes back to my first question. Is there almost been a break in the last few years where even you are like, “Holy cow, I didn’t know this is where we were going”? DB: I feel like all of us in the technology industry are feeling that — everyone, CEOs, programmers, people who use these products, consumers. We’re all in the middle of it, I would say, over the last several years. Do you think this makes Roblox more or less valuable? If anyone can make a game, is Roblox Studio, your jewel, not that big of a deal anymore? DB: I think what really ends up being valuable is the combination of a few things. We’ve shared the notion of Universal Player, that I’ll dive into, the notion of Roblox Everywhere , the notion of the power of distribution platforms becoming more and more powerful when a game is created, “Where do I find it?”, “Where does it run?”, “How do we keep it safe?”, “How do I play it with my friends?”, “Is there an economy?”. So in a way, distribution platforms become more powerful. It’s worth thinking about it like — pick a distribution platform, whether it’s TikTok or YouTube, in a way, AI can accelerate those platforms, but in a way, those platforms have enormous strength with or without AI and even though someone could reproduce the whole YouTube platform with AI — the cloud, the client, all of those things — people are still going to go to YouTube to watch video. Yeah, this is the connection I was drawing — going to the short-form video platform idea. I’ve always drawn a distinction between distribution and discovery , distribution is free — anyone can post a website, at least generally speaking, they could host a game on their website, they could host a game on Vercel or wherever it might be. But then discovery is, if there’s a gazillion games, how do you find what you’re looking for? Of those two, what do you think is more important for Roblox’s future? DB: They’re both enormously important. The Roblox platform itself has well over 100 million people coming every day. On the discovery side of our platform there’s two angles to it, the first is, what happens when everyone’s building a game? All of a sudden, in the old days, there’s an abundance of new games and experiences. How do we connect the right person with the right game with their friends? Even in what might be called AI slop, there can be amazing games embedded in that AI slop, even if it’s 1 in 100 and even when games are crafted by hand, there can be some of those games that just aren’t interesting to people, so discovery becomes enormously important. What we have going on — and with the opportunity going on at Roblox — is that in addition to traditional discovery, which is optimizing every user-game pair and predicting long-term retention from that connection, with more and more games, content understanding becomes incredibly important and because Roblox is a platform where all of the games are running in the cloud, we can examine the content, learn from what we’ve learned, and maybe say, “This game has an interesting, new, diverse way it’s been constructed, this game looks a lot different than other games”, and that can help surface great content to new users. The other thing, in addition to on-platform discovery, is this notion of Roblox Everywhere that we’ve shared. Let’s get to that, I promise we’ll get to it, because I think it’s super interesting in this context. But you’ve gotten much more into — you mentioned matching players to the right game, what have you learned from getting into recommendation algorithms? The path — I keep referring to it — but this is the social-networkization— DB: Yeah, it’s very different than video, because a game is something a user can play multiple times, a game is an environment where friends can have fun. Some good games last for years and years. You know, Adopt Me has been on the platform forever, so finding an Adopt Me that creates joy for a long time is very, very important, rather than a one-shot video. I think what we have learned is to optimize for longer-term retention rather than short-term retention. Well, that really hit your earnings when you made that shift a couple quarters ago. What was your thinking? Is that what you expected? DB: I don’t want to comment on hitting the earnings, but I want to comment that mathematically, if we can raise long-term retention — which means more people stay on the platform, more people have a good time, and, like I mentioned with Adopt Me, find games they might play for 10 years — that pencils out. And retention is critically important in growing users and growing word of mouth and growing all of those things, so we’ve gotten better and better at optimizing long-term retention. We measure it directly, we measure the contribution to long-term retention from every user-game pair. We see interesting things — different types of groups of people like different types of games and I think if we go to the Roblox home page, for example, and I play, or someone else plays, I think people are universally saying, “Oh my gosh, those are more and more looking like games that I’d like to play for a long time”. You told me in 2022 that Roblox’s initial product failed because it wasn’t multiplayer and social and that was one of the foundational lessons of the company. Now you’re enabling offline single-player games. Have you moved? Is this what has changed? What’s shifted, where — yes, of course you’ve mentioned the social aspect multiple times — but also there are games people just want to play, a great game, on their own? DB: I feel long-term the foundation of Roblox will continue to be multiplayer, friends coming together, that may be in real time, that may be asynchronous, that may be “I take a turn, you take a turn”, that may be I play a match-three puzzle at some point and compare it. What the move to single-player, the move to puzzle, is really saying with our aspiration for Universal Player and Roblox Everywhere, we have enough bandwidth now to cover the whole spectrum. When we talk about the notion of Universal Player, the notion is going all the way from a traditional 2D offline puzzle game, all the way to that which is yet to be invented — which is super high-scale multiplayer, photorealistic reality — and everything in between. So the vision with the puzzle game, as well as Roblox Reality, is going back to the video analogy. In a way, with video, the camera and the player have been somewhat invented, we have cameras all over, we have 4K, 60-hertz playback, we have playback mobile, we have playback in our living room, and so all of the video out there generally will play back on my living room 4K, 60-hertz TV. That’s not true in gaming. There’s not a universal rail, where every game as of yet invented, as well as to be invented, you could imagine it playing there, so that’s the notion of 2D puzzle and Universal Player. Presented by Agentic commerce purchases with Link, Stripe’s digital wallet that works surprisingly well for agents, grew 38x in September. The catalyst was consumer agents like Muse and Instinct. Filling out a web form is not a value-add activity for anyone. No one chooses to fill out web forms in their spare time. That’s why these agents have been particularly useful. I’ve written about how these platforms are giving ordinary people an AI agent with a computer, enabling agents to do genuinely useful things on our behalf.  When one of those things is spending money, it needs a wallet that knows what it is, and isn’t, allowed to do. Stripe has learned that’s really about deciding how much freedom to give it. You might approve one purchase, or give it $500 for flights this week, and let it figure out the rest. The wallet’s job is to keep it within those lines while handling everything between “go buy this” and the purchase actually happening. That’s what Stripe is building with Link: You approve what it spends, it can come back to you if the final price changes, and eligible purchases can even come with protection if the agent makes a mistake. You can use Link on Muse, Instinct, as well as many other of the agents you might use already. So step back and explain Universal Player, broadly speaking — both in terms of the different surfaces, and also bringing in games from other platforms into the Roblox experience. DB: Part of this comes — I’ll come at it first from an AI angle, and then a puzzle game angle. From the AI angle when we hook either our Studio assistant or an MCP model up to Roblox Studio, and you or I say, “I’d like to build this”, there’s still technical constraints, if I hooked up MCP and said, “Build a game that happens in the state of California, make it a 3D multiplayer environment, I’d like it to be photorealistic, and I’d like it to be able to have up to 100,000 people all walking around and driving cars” — not technically possible. But we do want to push towards that — once again, multiplayer high-scale photorealism — as quickly as possible, and make a place for anyone who’s either imagining a game or building it with MCP server, or, as you mentioned, ultimately bringing in a game they maybe have already made and converting it to that type of environment. So if we have a Universal Player, that’s a superset of all games that can run multiplayer. You could imagine that if you had a puzzle game that’s offline, connect it up, bring some of the source code in if you want to, and we’ll convert it to Roblox. Or you had a single-player high-res game, we’ll convert it to Roblox and in that conversion process, a couple other cool things will happen. We coined the term “Robloxification” — it’s really what’s different about the Roblox architecture. Your single-player game from a PC can now be multiplayer by default, because we’re running against a cloud. Because we’re doing 3D streaming, your single-player game will also run on a phone — oh, it’s being Robloxified. Your single-player game, rather than being a 500-gigabyte download, you can just join it immediately, that’s very interesting. Your single-player game has access to economy and other things so the notion with Universal Player is really both convert, as well as Robloxify, existing games as well as new games. Is this leveraging — to go back to the discovery versus distribution — is this leveraging the fact that you want to get into Roblox’s discovery engine? There’s people on Roblox, they’re not going to go download your game individually, they’re not going to go to another website. DB: That’s exactly right, in that a game brought into Roblox Everywhere in our Universal Player will then be available in the Roblox app. And as we thought about it, what a great way to discover more content than to have great games out there that are also discoverable in the app. This is the analogy — to go back to the short-form video — where you had this story with Meta versus TikTok. TikTok realized that it’s called a social network but it’s not really a social network, it’s just really giving you the videos that it thinks you are going to like, and who you follow doesn’t have anything to do with it. Meta is stuck in their social network, “That’s what makes us powerful”, and to compete with TikTok, to make Reels into a thing , they had to let that go, “We’re just going to give you what you want”. Is there an analogy there to your embracing single-player games, to you having recommendation algorithms? And sure, Meta will tell you the social network part is important, will always be important. Is that analogous to you saying, yes, the social aspect of Roblox is important, will be important, but actually to truly grow, to reach your full potential, you have to actually atomize a bit more and meet the player with exactly what they want? DB: Yeah, I think if anything it’s even bigger than that, I’ll go through three realizations. The first realization that we’ve come to, looking at the physical world, when people play — whether they’re playing sports or a board game or any form of play, jostling around with friends — it’s typically not just play, it’s playing, it’s connecting, it’s community, it’s creating the play, “What are we going to do?”, it’s sometimes watching other people’s play, it’s dressing up to play. And so we started thinking about the market, not as the game market, but the play market, and how all of those pieces really work together so that’s been a bit of a stretching, rethinking things for us. The second is, when we say the play market, we can no longer just say, “Well, Roblox is a 3D multiplayer game engine”. You were constraining yourself. DB: That’s right. All of the constraints, I think, in the past that helped us focus and grow at a certain scale have to flip from focusing constraints to constraints we give up on. What was more difficult — convincing the company we have to let those constraints go, or did you have to convince yourself? Because again, two things that really stood out. Number one, you had this long-term vision, and it’s actually been continuous, and now you’re saying, “Wow, this has been a big shift”. But then number two, this being focused, “This is what we do”, and now you’re like, “Well, actually, no, we need to let that go and do everything”. DB: We’ve gone through several of these. The early version of Roblox was PC and Macintosh. We, for a while — if you can believe it — there was no mobile phone version of Roblox and when we looked at the iOS App Store top 100, there was no 3D game in the top 100. China was a little bit ahead, they were starting to poke at it, the U.S. was not. Giant company debate, “How could Roblox ever work on a phone? The phone is 2D. It’s not going to work”. Luckily, mea culpa, we went for it and now we’ve gone through that transition. There’s also a time on Roblox, very early on, we thought the blocky look was so simple and easy to build with, we wouldn’t allow the importation of 3D mesh objects, we mea culpa’d it, because ultimately we want all styles of game. And so I think 2D and offline is kind of one of the last holdouts for that, in saying it’s really the play market, and we can’t constrain that anymore. Are you pushed into this market, or are you pulled — just the market opportunity is so large? DB: I think it’s so much more fun and simple to just say, “We’re going after the play market”. (laughing) That’s right, let’s do it all. DB: We need integrated and safe ways for community, we need integrated and safe ways to find great games to play with, we need all of that just in a simple — it’s actually a simpler product spec and a more fun product spec. Does that mean, you as a company, you’re more defined by — maybe you’re like supply-defined, where, “What can we do, and this is what we’re going to deliver”, and now that’s sort of flipped to, “What’s the market and how can we fill that market?”. DB: Yeah, I think it leads to all kinds of interesting features of the product. For example, short-form video is traditionally used for watching by yourself. Imagine something that feels like short-form video, where you’re seeing the 3D game where your friend is already playing, and it’s a way to find a friend and jump into a game. Right. We made the short-form video comparison, but you’re literally doing short-form video. DB: Finding 3D ways to discover is super interesting, finding ways to connect with your friends is super interesting. I feel this singular vision on play is a category that’s got legs and I think the thing that is yet to be figured out is how big is creation versus playing with friends. What I have seen with the early players on Build is, there’s a lot of joy in making a short-form video on one of these platforms and having your friends see it. That happens in spikes and I’ve seen people do that. The joy I’ve seen of people creating games on Roblox and literally sitting there with their phone and saying, “Oh my gosh, I have four people in my game, and those four people are playing my game, giving me feedback” — I’ve seen that be really powerful. That’s interesting, because the feedback mechanism — you can act on it. If someone gives feedback on a video, it’s just a comment on a video. DB: And like I highlighted, board members doing 15 modifications a day to their game so that four people turns into six people. That’s really interesting. It’s like there’s a 3D aspect to gaming, as opposed to the 2D aspect of a video. This is almost like a 4D aspect, where the interaction — it’s a social network in a very different sort of way , it’s around this object that could evolve and move with the interaction over time, I think you do have a 4D product. DB: That’s right. Well, we use the term 4D lovingly in our physics engine, because 4D objects are objects that have behavior and code and do things, rather than static objects. The other topic you’ve brought up continuously is Roblox Everywhere. First, explain what it was — I have some questions about this that are connected to what we’ve been talking about. What is Roblox Everywhere, from the top? DB: We shared earlier, our jump from PC, Mac, “Oh my gosh, we’re doing mobile, could it work?” — and then we shared some of the other changes we’ve made along the way. One of the things, for quite a while, we’ve held on is: 100% everything is in the Roblox app. DB: But as we’ve seen our vision of the Universal Player — the vision that, whether you build on Roblox or you convert or you use AI, below the rails, Universal Player is the place a game can be constructed and run at scale — as we thought more and more, all of a sudden the power of what is the Universal Player becomes appealing, not just in the Roblox app, but possibly for a creator who wants to ship a standalone game in the iOS App Store, the Google Play Store, on their PC, on a console. And as we thought through it, the benefits of giving creators access to the Universal Player, even when they’re not in the app, brings an enormous advantage to us, which is that their content can then be available for discovery in the app. That gets to my question. Okay, I’m on board with the releasing, let’s be on all devices, let’s not just have blocky characters, let’s have 3D characters, all the things we’re talking about. But I’ve been framing this whole discussion — we’ve been comparing to short-form video, which is an Aggregator play. You own the end users, you own the consumers, you have Universal Player, people can bring their games in to reach the customers, you have an advertising business that we talked a lot about last time, I have some questions about. Roblox Everywhere seems to be like the whole company is now flowing in one direction, you have the Roblox place — if you want to make a game, go there, there’s customers there, there’s monetization there, it’s all there. And now you’re like, actually, let’s open up a trap door and let everyone go out the side, am I the one that’s now being the wimp and saying, “Can you be a little bit more focused”? DB: I appreciate your insight there, but what’s really exciting to us is the potential to get such a large percent of the gaming market running on Roblox Everywhere, and the potential content explosion that happens within our app. The way we thought about Roblox Everywhere is, if you’re a creator — you might be an indie creator just pushing a small app, you might be a large studio — the more we can have both the most amazing technology platform, really Universal Player, and the more it makes absolute sense for you to run on that technology platform, whether you’re in the Roblox app or standalone, we get the benefit of that content in our app which is social, which can be launched instantly, which shares a common social structure, which carries a common safety structure, a common economic structure, all running together. So our calculus — and as you said, maybe it looks risky or whatever — but our calculus is actually, this is the best way to grow users in the Roblox app itself. Yeah. Well, it’s interesting because I think this gets on the — I’ve been drawing the analogy, we’ve been drawing the analogy jointly, between short-form video and gaming. But to your point, gaming is still a lot more difficult and if you go through the history of gaming over the last 40, 50 years, this has been a trend is over time, just the cost of developing gets so large, you need to be multi-platform. The PS3, one of the all-time examples, builds this super complicated, powerful architecture that no game ever leverages, because the cost of creating HD assets is so much higher . They need to be on Xbox also, they need to be on PC, and so everything goes multi-platform, Sony responds by doing the exclusive strategy, etc. Is this a similar articulation, that making games is hard, and so if we don’t make it so developers can run their games everywhere, they’re not going to be on Roblox either? DB: It’s really hard and right now there’s a bifurcation, a lot of times, between that super cool high-end PC game I see and what I can run on my two-gigabyte Android phone overseas. Those typically are different products. And so you’re trying to make the whole world the market for a developer — if you build on this, the whole world will be your market? DB: Imagine if it was technically feasible to build for super high-end AAA multiplayer on a PC, and connect to the same game on a two-gigabyte Android phone overseas. That’s a technical opportunity, we think, for creators. How is that different from streaming? Like, you stream a console game to your phone, what is different about what you’re proposing? DB: There’s a very creative history of what is called game streaming, where the game is run far away, I send my keyboard and mouse to the game, and then video comes back. (laughing) Right. And it sucks. DB: And this was even 20 years ago — Gaikai, OnLive, OTOY — we’ve seen a long history of this. You said it sucks, the way I would say it is, some of the things we’re doing in our video — you and I are on a Zoom call right now, when I look at my character, my character’s reacting instantly, I feel like I’m looking in a mirror, in a pure video streaming architecture, I might move 50 or 100 milliseconds later than when I do that, and people are very sensitive to that. If you’re close to the video server, maybe it’s pretty fast but I do believe having local 3D instantaneous feedback is super, super critical. So that could be one reason why video streaming just hasn’t kind of exploded as much as we thought. Is there an issue where streaming — they’re trying to retrofit what existed, and you’re natively building for this experience, and that makes a difference? DB: We want native 3D, you know, we want multi-device native 3D, very low latency happening on those. There’s some other dimensions where gaming is getting more difficult as well. The regulatory environment — it’s not like the old days if you or I make a game. There are different laws in every state and in every country, cultural laws, all of those. One of the opportunities is to have a platform that can automatically adjust to that — what are all of the rules around age, around ratings, around all of those things? That’s another thing that can help a creator reach the world without having to think about all those things. How do you think about monetization for the Everywhere games? Is there going to be like a platform fee, like a Unity sort of aspect? Or is the payoff, “If they’re building using our technology, they will also be in Roblox, and that’s where we’ll make the money”? DB: We shared at RDC the notion that monetization may be somewhat similar for games Roblox would publish. And so if you went to an app store, there may be some games published by Roblox that are the exact same games that are inside Roblox. We would only do that with the developer’s permission, but it could be really cool — you could go to your app store and search for “Grow a Garden” and say, “Oh my gosh, there’s the game”. For games where the developer is pushing directly to the app store, we haven’t shared the economics but in the thesis of what I said — which is eliminating any reason for the creator not to think about it — that leads to the economics needing to be pretty provocative and so stay tuned on that. Where is advertising fitting in this and your vision overall? Give me the advertising update. We spent a lot of time on that three years ago. DB: We shared on the earnings call that we’re more and more excited, and we’re all in, not just on Roblox platform advertising, which is growing, I think we shared that’s growing very quickly as well. As creators come into Roblox and use Roblox Studio Assistant or Build or MCP, “Okay, I need to get some initial traction, I need a thousand users”, those ads are available on the Roblox platform. And isn’t that the great thing if it’s abundance, there’s too many games, you have to discover it — user acquisition ads are very profitable. DB: We have seen an acceleration of that type of advertising and to take that all the way back to the prior analogy, we have board members on their phone buying advertising. (laughing) Conflict of interest, they’re bumping up their own stock price. DB: There’s a second type of advertising that, more and more, is becoming available, which is very short, five-plus-second skippable pre-roll video. There was a time, way back in the history of Roblox, we tried pre-roll video, it was not a good experiment. The quality of the video was not super exciting, pre-roll video at that time was 30 or 45 seconds. Technically it was a pain in the butt, and we yanked it out because we didn’t like the user experience. That kind of left us with, for a while, “Uh-oh, no pre-roll”. But today, the fun and the quality — if we’re very selective of the brands, and we could imagine the brands that are interesting to a 21-year-old Roblox player — clothing brands, electronics brands, movie brands — where they might actually say, “It’s pretty cool to see this”. We also, because typical games on Roblox launch not quite instantaneously — they launch maybe in five or six or seven seconds. Right, you have time. DB: There’s actually a beautiful technical overlay there, if we do it right and do it natively, to put this all together so we’re very excited about this potential combination. Is there an aspect where companies, especially when they’re first doing advertising, they overthink it? Like, “We have to have the world’s most inventive ads, there’s going to be billboards in the game, and these experiences” — and actually, no, just show a pre-roll video, it’s fine. DB: I think that’s right. I think we have a history of thinking big, and I do feel ultimately there’s going to be a wide range of types of branding that people do. There’s a lot of immersive 3D potential for literally shopping in 3D and doing all of that but there’s also an enormous quantity of pre-roll video. Right, you can get to that eventually, there’s actually a lot of low-hanging fruit, it feels like a lot of first-time advertiser platforms — they’re reluctant to pick, and then they’re like, “Actually, let’s just pick the low-hanging fruit and go from there”. DB: I think that’s right and I think in a COPPA -compliant, privacy-compliant, Roblox-values-compliant way, we can still imagine amazing user experience for advertising. Does this tie into the potentially provocative pricing for Everywhere? Where you make a game, it’s everywhere, congratulations — but if you want to actually make money, you’re going to need to be on Roblox and that’s the best place to spend money to acquire users. It’s better than spending on Meta, better than spending on wherever else it might be. DB: You could imagine, in under 18 on Roblox, we’ve shared we may have literally 20% of gaming revenue in the U.S. flowing through the platform and so that’s huge penetration in that age group. As we move towards that same penetration over 18, all of a sudden the value of advertising on Roblox for my new game becomes more and more valuable, because those users are already there. Are older players like your great white whale? I think every time that we’ve talked over the years, it’s always been, “We’re going to expand into older players”. When is that the reality, as opposed to the opportunity? DB: Reality is right now, the fastest-growing thing on our platform is 18 and up, it’s growing very fast. Are you getting new users, or is it people aging into and sticking with Roblox? DB: Absolutely, both. It’s a smaller cohort than the under-18 thing. But as it becomes an increasingly larger percentage of our revenue, it will more drive the growth rate of the top end as well. And how does that relate to the single-player offline, new types of gaming, puzzles, and all the things you’re talking about? DB: I think there are some of those segments that are very much 3D multiplayer, some of those segments are puzzle. There’s an overlap in that, as we think about the whole play market and we don’t restrict any types of games going forward, we have more opportunity to really create a good chunk of that market and once those users are on our platform, they’re very valuable, because other games can be attractive to them as well. In our first interview you talked about how you deliberately avoided paid acquisition, because organic virality was so essential to Roblox, in part because of the social aspect of the games. DB: I think we were careful with it. It’s a much bigger thing now, right? DB: For under 18, even in our early days, we experimented with paid acquisition, but we are very careful with always getting a return on the spend, and always knowing that organic viral had to be the biggest, but there still is a logical amount to spend. And we’re doing the same on over 18 right now, we are mixing organic with paid, there’s an optimal mix of them. We always want whatever we spend on acquisition to make incremental revenue more than what we spend and we are sticking to that hygiene. So it does make sense for us to do the paid acquisition. Is Roblox a metaverse? Is that still the dream? I like the word, no one else does. DB: I feel it’s weird how that word kind of came and went a bit but I think over time, maybe that word will come back, right? Because in the ’80s, ’90s, and 2000s, that was a very popular way of describing not just a gaming platform, but a communication platform — a place where people came together to play or to work or to do a bunch of things. I do feel ultimately, beyond gaming, that still makes sense. This Zoom call, at some point, will be a 3D simulated metaverse call, and we’ll be able to run in traditional 2D mode, and we’ll be photorealistic but if I wanted to go and look at that globe behind you, and I asked your permission, I said, “Ben, can I come and see the globe?” — you’d say fine, hopefully, and I’d come and look at it. And that’s something we can’t do on Zoom that will be unique to, ultimately, a metaverse call. It is a very cool globe. I got it at an antique shop. It has, like, a barometer in it, a thermometer, and it actually lights up — it is a lamp, also so it’s my background. DB: I love globes, I love telescopes too. Well, there you go. With the metaverse, with this 3D world, you just talked about a real-world thing, you could come into my room. But to go back to the example, you mentioned the developer that wants to build the state of California and driving cars around and 100,000 people, is this ultimately going to be realized, not through polygon drawing, but it’s all just going to be AI-generated ? DB: I don’t think it’s going to do that, and the reason we’re building this Roblox Reality architecture — and I’ll share a bit about it — is we do want, “What’s the quickest way to get to multiplayer, photorealistic, immersive gaming?”. Multiplayer is where the fun part comes in, and it’s why we talk hybrid. So in the movie business, there’s several famous directors right now who are going hybrid and what they’re doing is, they’re either shooting live actors, or they’re building a very rough scene for their movie in a 3D system, then they’re taking the 3D information and they’re upsampling it with an AI model to 4K photorealism and so they’re putting together the best of traditional — and in the case of live actors, there’s much more accurate capture of the face, of the emotion, when shooting real film for the actor, but then you can decorate the set however you want. In gaming, synchronizing 10,000 players needs to be done in the most efficient way possible and doing that in a video latent space is not the most efficient way, doing that in a rough 3D representation is the most efficient way. But for every one of those 10,000 players, it’s getting a pretty efficient 3D representation, you can imagine each one of them uniquely getting an AI video model upsampled for them specifically that looks like 4K, photorealistic 60 hertz, and I think that’s where it’s going to come out. Are you going to win on doing this because you have a technical advantage, you pull it off, or because you already have the audience? Lots of people could build this out. DB: I would say yes and yes, hopefully. This is a vertical integration play, the vertical integration. Right, which has always been a core part of Roblox’s theory. DB: I’ve played with, for example, Grow a Garden, or classic games on Roblox, with early versions of photorealistic upsampling, and it works out of the box. There is a notion that existing games can run for all players, same gameplay, but for some, photorealistically upsampled. But I also feel it’s a technology play, because most of the video models that are being built today are either single-player world models, or video generation models — like you or I want to use one of these models to make a cool 15-second video. This technology is different, this is real-time, low-latency video being generated from the 3D video and the 3D depth map and a bunch of other things, so it’s a very specific type of video model that has some overlap, I think there’s opportunity both for technology as well as vertical integration. The thing that I’m taking away is — and this has always been the case talking to you — the scale of the ambition, but it does feel like the big shift is actually, “Let’s literally do everything, let’s do the supply side, we own the demand side, let’s do all kinds of games”, is that what Roblox is today — we’re all gaming, period? DB: I would say, do everything within the carefully thought-out boundaries of the future of play. And so within play, yes, let’s be open to 2D puzzle, let’s go all the way from two-gig Android to photorealistic Roblox Reality and in between, let’s make things available in the Roblox app as well as in Roblox Everywhere. So I would say, within those hopefully thoughtfully constructed guardrails, then yes — in a way, it’s do everything. Do you feel okay without the focus? Without knowing, “This is what we do”, is, “We do everything” — is that focus in its own right? DB: It is focused, because there’s still some pretty tight guardrails. And so I think, given the size of the company and the ability to use AI to accelerate engineering, I think it’s the right current product spec — just like when we started, it was PC-only, blocky, and that was good enough. Last question, you mentioned the AI component. This “do everything” — is that downstream of, “Now we can use AI to program”? Or did the AI programming come on just in time to make this vision possible? DB: For many companies, I think like ours, back and forth, iterate, iterate — AI engineering acceleration, expanding maybe the definition of the product spec, AI engineering, expanding the definition of the product spec. But I do think companies around the world are now starting to take things that they thought would be a nine-month project, and thinking of it as a two-month project. How do we rethink how we architect, to make these nine-month projects two-month instead? Very good. David Baszucki, very interesting, very cool to see what you’re doing. DB: Great talking with you. Thank you again, Ben. This Daily Update Interview is also available as a podcast. To receive it in your podcast player, visit Stratechery . The Daily Update is intended for a single recipient, but occasional forwarding is totally fine! If you would like to order multiple subscriptions for your team with a group discount (minimum 5), please contact me directly. Thanks for being a supporter, and have a great day!

0 views
Brain Baking Yesterday

Creating Your Own Gaming Backlog Yields Behavioural Insights

At the end of 2024, I made my own video game Top 100 page , resulting in a cool grid-based list available at https://jefklakscodex.com/top100/ . While writing A Huge Pile Called The Ongoing Backlog , I discovered even more websites dedicated to categorising and indexing your backlog: Giant Bomb’s Video Game Tracker, Backloggery, Backloggd, MyVideoGameList, Completionator, Darkadia, Searchtoplay, … Every few months a new system seems to pop up—and go permanently down, taking your data with it. You know where I’m going with this… So yes, I created my own backlog based on the Top 100 grid system, now deployed at https://jefklakscodex.com/backlog/ . I already had all the data living in separate Markdown so all I had to do is add some more entries and add a few backlog-specific bits and pieces. The result doesn’t look too shabby: Jefklak's Codex Backlog, split between currently playing and the rest of the backlog. The technical design is fairly simple: it’s just a Hugo with some filters, fetching data from Markdown frontmatter. An example of a file looks like this: Where the How Long To Beat (HLTB) data and the cover image is automatically fetched through an external script. The key is relevant here, as is to keep it from popping up on the main site including the RSS feed before finishing it and writing down my thoughts. See my blog workflow post for more technical details. A few of the features were ported back to the Top 100 page, such as: The idea for using average game length buckets was to mimic the Nintendo Switch’s way of recording playtime. That way, when I’m in the mood for a shorter game, I can quickly glance over the backlog and filter out the ones that’ll take me too long to finish. As part of the Backlog Statistics , a new graph called “Average Game Length” was added to visualise the game length distribution in the backlog. Both the Top 100 and the Backlog pages showcase the same pattern: most of the games take beetween 5 and 10 hours; then between 10 and 20; then between 0 and 5 and between 20 and 30; with the fewest between 30 and 40 and still too many games breaking through the 40+ hour mark. Unsurprisingly, the three Dragon Quest games lying on the shelf collecting dust are responsible for that. You can also click on one of the bars in the graph which will automatically filter on that game length. A part of the backlog stats: games by release year and platform. Fifty-eight of the games on the backlog are physical versions , with the remaining twenty-two being digital releases. I tried being honest by including every possible game I have yet to play, including the Switch eShop, Steam, and GOG.com library. I stopped there: the SNES Mini and PSX Classic also house twenty-something titles that I have yet to properly discover 1 . All games are legally-owned. I have zero intentions of downloading yet another ROM library that would completely flood the backlog. At this moment, I am playing 10 games, and have 70 more waiting for me. In other words, I’m drowning in games. I’ve said it before and will say it again: Too Many Games, Too Little Time . The amount of hours required to beat the entire backlog is hours which would require almost two full years of playing two hours a day every single day. Given other obligations, this is already a very optimistic calculation. My gaming habits yearnotes tell me I finished 27 games in 2025 and 2024: that means it’ll take three instead of two years to finish all 80 currently on the backlog. Also, a large backlog brings up another problem: is there any time left to replay the classics? Another interesting statistic: when looking at the games by release year, you can see that most games are relatively recent compared to the same stats from the Top 100. This is not a big surprise: the last few years, I’ve been buying mostly (physical) Switch games—hence the dominating group of 28 games from that platform, with the PC following suit with 22 games. It’s been awfully quiet when it comes to scoring good deals at GB(C) games on flea markets. The ridiculous prices demanded by the second hand cartridge market for once works in my favour. I went to great lengths to try and add correct purchase dates —the default sort property. This means I can now see how many games I bought this year, last year, and the year before. Going further back, things became increasingly difficult to pinpoint. Let’s examine 2025 and 2026 a bit more closely. This lays bare a painful truth about my video game consumerism: I buy a lot of physical games to place them on the shelf. Especially this year, exactly zero of those purchased within the same year were finished. And yet every single digital game I bought was played & reviewed on The Codex. Why? Here are couple of possible explanations. First, I am suffering from a well-known condition called Fear Of Missing Out when it comes to physical (and very limited) Switch releases. So whenever I see one that’s been on my radar of a while or is priced somewhat right, I can’t resist. Also, Joel puts me up to it. Second, the digital games I buy are sometimes influenced by others I follow or recent releases I want to play now . Third, many of these are indie games that will never get a physical release. Fourth, when I order a physical game, it takes a while to get here. By the time they’re here, another game has been queued up and it has to wait. I was wrong about collecting physical games . It looks like I’ve become a hoarder and not a player. The harsh truth here is that I could be happier by going fully digital and only buying when I feel like playing a particular game which greatly increases the chances of said game being played and finished. Another observation: I am immune to “deals” and price fluctuations for digital games. I ignore Steam sales, Humble Bundle et al., and I buy a game (usually through or ) regardless of discount. I buy because I want to play, yet I am worrying about prices and ordering too late when it comes to physical releases. Who’s being stupid now? So what now? Good question. This exercise hasn’t exactly left me roaring to go and discover even more hidden gems. The more things being piled up on the backlog, the more depressed I become, yet I keep wanting to buy these limited runs because “I have to, this is my only shot”. I know that compared to others, my backlog is relatively small. My definition of “backlog” is anything I purchased, including the dreading Steam library that in my case is pretty manageable. Yet something’s gotta give. Here’s a promise to myself for 2027: I will not buy a single new video game . Not one. Zip. Nada. I will instead try to reduce the backlog and will be extremely happy when at the end of next year there are 50 games on there instead of 80. The ones I want to buy will firmly stay on the wishlist. Perhaps I should also be very selective when it comes to adding them there, otherwise for 2028 the wishlist will explode and the buying spree will simply come back. If I just focus on the games in HLTB bucket 0-5 and 5-10, that’ll be 37 ones scrapped off. I could force myself to power through a few longer games, but I know I’ll just be dropping it halfway through. The longest games I managed to tackle the last two years were about 30 hours. I will also permit myself to trim the backlog by selling games if I have to (which is of course only possible with physical releases). My biggest concern with this challenge is, again, the Limited Run Games et al. releases. I will never completely miss out on these games: there’s almost always the option to buy them digitally. Perhaps by the end of 2027, I’ll become a digital convert, who knows! Wish me luck! I’ll be needing it… For compilations such as the Turok Trilogy or the Final Fantasy Pixel Remasters , I just added one entry and will add another one once I finish the first. Luckily, the amount of these compilations yet to play in my collection is minimal. I also tend to review the compilation itself while exploring the games but never fully finishing them all (for example the Turtles Cowabunga Collection ).  ↩︎ Related topics: / lists / games / By Wouter Groeneveld on 12 November 2026.  Reply via email . Filtering by physical games; Filtering on average game length (in buckets: 0-5 hours, 5-10 hours, …); Activating multiple filters at once; The enhanced sort combobox. Bought in 2026: 20 in total (8 physical, 12 digital). Played: 12. Backlog: 8. Physical & played: 0. Digital & played: 12. Bought in 2025: 19 in total (12 physical, 7 digital). Played: 9. Backlog: 10. Physical & played: 5. Digital & played: 4. For compilations such as the Turok Trilogy or the Final Fantasy Pixel Remasters , I just added one entry and will add another one once I finish the first. Luckily, the amount of these compilations yet to play in my collection is minimal. I also tend to review the compilation itself while exploring the games but never fully finishing them all (for example the Turtles Cowabunga Collection ).  ↩︎

0 views
sunshowers 2 days ago

Contra "Glue work considered harmful"

Sean Goedecke, Glue work considered harmful (emphasis here, and in the rest of the quotes, in original): So why doesn’t glue work get you promoted, if it’s so crucial to shipping projects? Are companies stupid? Are they deliberately leaving value on the table? No, I don’t think so. Companies don’t reward glue work because they don’t want you prioritizing it. And they don’t want you prioritizing it because they want you shipping features. Glue work is hard. If you’re capable of doing glue work well, they want you to use that ability to deliver projects instead of improving general efficiency. This is an argument to settle for mediocrity. If you’re like most people who have worked in big tech, it is plainly obvious to you that they are leaving value on the table. (Whether it is deliberate or not is a matter of what’s in people’s hearts.) What big tech employers want is largely incoherent. They want you delivering features. They also know that somebody’s got to do the glue work to keep the company running, and they have trouble describing or capturing its value. Here, and throughout his post, Goedecke is quite accurately describing some of the incentives presented to employees at big tech. My problem with the post is that he tells you to internalize them instead of keeping in mind that a better world is possible. The core problem is that you’re deciding for yourself what the company needs instead of doing your job. Isn’t it your job to make your team run smoother? No! Your job is to execute the mission of your company’s leadership. If glue work is critical to the mission of a company’s leadership, how does neglecting it serve the mission? It is better to execute that mission at 60% efficiency than to spend all your time increasing efficiency in general (or even worse, to execute some other mission at 100% efficiency). Why? For two main reasons: first, you’re inevitably going to burn out, which will be bad for everyone; second, it’s better to let your team get used to operating at the base efficiency level of the company instead of artificially removing friction for a brief period. There are two very different things being conflated here: saving some gas in the tank for when there are real deadlines, which is great advice, versus not trying to make your coworkers’ lives better, which is a real case of misaligned incentives. Besides, the premise is fundamentally wrong: there is a lot of glue work that, if you give it the respect it deserves, removes friction permanently . I’m obviously biased here, but I think the cargo-nextest project is a great example of glue work (running tests!) done so well that the problem mostly vanishes. More recently, at Oxide I wrote an agent skill called flake-review , backed by a catalog I wrote 1 over a few hours. I’ve since used the skill to fix almost a dozen test flakes, making the entire team’s lives better. Should you never do glue work? No, you should do glue work tactically . That is, you should do this kind of extra work for the projects you lead — the projects whose success you’re accountable for — in order to make sure they succeed. You won’t be rewarded for the glue work specifically, but you will be rewarded for the success of the project. For other projects, you should just do your regular job. With the most emphatic of feelings, fuck that . I do glue work whenever I’m the best situated person to do the glue work. The idea that you shouldn’t help your peers, simply because someone in middle management has trouble articulating the value of helping your peers, should be deeply offensive to any serious professional. Is this a deeply cynical take about how to succeed in office politics? I don’t actually think so. Large tech companies operate at something like 20-60% efficiency at any given time (as they get larger, they get less efficient). A large chunk of people’s working lives is wasted on solvable problems whose value organizations don’t recognize. How can one not be cynical about this kind of unnecessary waste and suffering? It baffles me. So, what is going on here? Any organization beyond a certain size requires legibility to function. The requirement for legibility pulls in all the things many people recoil at: performance reviews, OKRs, KPIs and whatnot 2 . Some big tech firms have figured out ways of making some of that glue work more legible. For example, Meta has fairly large internal tools and developer infrastructure teams, where goals are set around measurable indicators like performance numbers. But there will always be some glue work that will resist all attempts to measure it, and to the extent that firms don’t care about it, they will suffer. What does one do instead? Well, getting rid of performance reviews certainly helps! For the last few years of my work life at Oxide, the distinction between glue work and feature work has largely vanished; the question I’ve repeatedly asked my coworkers and manager is “how can I be helpful?”, not “what would look good on my performance review?” But I accept that larger organizations will need a greater degree of legibility. I think all the usual answers apply: don’t overhire (and certainly don’t incentivize managers to hire as many people as possible), don’t require all work to be legible, and trust your employees with the rest. I wrote the catalog in my own words, for two reasons: to gain a deeper understanding of the kinds of test flake patterns we’ve seen in our codebase, and to not subject my peers to AI slop prose.  ↩︎ Did you know that OKR and KPI mean slightly different things ? Before writing this post, I did not!  ↩︎ I wrote the catalog in my own words, for two reasons: to gain a deeper understanding of the kinds of test flake patterns we’ve seen in our codebase, and to not subject my peers to AI slop prose.  ↩︎ Did you know that OKR and KPI mean slightly different things ? Before writing this post, I did not!  ↩︎

0 views
Unsung 2 days ago

System Settings and its last mile problem

macOS’s System Settings app might be a contender for the worst piece of software Apple released this century. Its 2022 redesign was based on wrong assumptions, the execution of that already bad redesign idea has also been subpar, and the situation not only hasn’t gotten any better in recent memory – I can point you to years-old bugs – but now it is spreading like gangrene to other apps . Among System Settings’ numerous UI crimes stands a simple, but incredibly important one: the app does a bad job at conveying to the users where they are, in a place orientation feels very important. A lot of this is self-inflicted, with bad search and confusing pop-ups partying with truly embarrassing bugs… Actually, one literally just happened to me. The only thing I did was opening System Settings: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/1.1600w.avif" type="image/avif"> Which section am I in? General, right? That’s the one highlighted? No, turns out that “Software Update Available” added itself post launch and stole the content pane, but didn’t update the nav on the left: This is embarrassing because it highlights that Settings are built in a shoddy way that allows the content and the left nav to get disconnected. The end result is yet another design problem that makes it hard for me to build in my mind the accurate map of all the settings, and to understand where each one goes and how they all connect. And I have a feeling I’m not the only one. But this is not actually what I wanted to show you. (I just got distracted by a bug on the way to where I was going.) The problem I wanted to share is more universal and helpful to know about. Let’s say I search for “hide dock”: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/4.1600w.avif" type="image/avif"> The first result is what I wanted, and clicking on it gets me there: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/5.1600w.avif" type="image/avif"> Type and click! It all seems great on the surface. The topmost option on the right is what I want; I can toggle it and move on with my life. But I might not realize that the right pane has been scrolled down to that option, and there’s a bunch of stuff above it, too. This is tricky, because sometimes it’s useful to know what the whole section’s name is. Or, maybe, the option I wanted is influenced by the option just above it, which I might now not even realize exists. Mostly, auto scroll is disorienting. The shy scrollbars are on by default, so they won’t lend a helping thumb. The light separator line that appears below the header is hard to notice. So is the blurred appearance of the closest scrolled-off thing underneath it. I am certain most people arriving at any scrolling container already pre-scrolled will assume the container is just… shorter. This is a problem you see on the web, too. There are solutions out there: you can animate-scroll to the right place on entry, or you can leave some space above (a clever trick is to calculate the distance so that one of the options left above is cut in half, conveying more stuff in that direction) – although both of these work better for section headers rather than specific elements like here. What would probably be best for setting would be to… point to the found thing. And what’s interesting is that Apple already built a fun mechanism for it: It’s a little goofy, seemingly inspired by those tabs for signing documents… = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/9.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/9.1600w.avif" type="image/avif"> …but most of its complexity has more to do with two menus next to each other. The pointing does its job well. And, even if it could use a refresh or some improvements, in a perfectly functioning ecosystem the System Settings team would grab that interface, reuse it, polish it, and give the newer revision back to the Help menu as well. In the process, the user would benefit thrice: first by seeing help improve, second by getting a better orientation mechanism for the settings, and third by experiencing and learning a consistent pattern across many surfaces. (Lastly, many among you might have already realized this: scrolling as a method was doomed from the beginning. If the found item is closer to the bottom of the container, like below, there is just no way to pull it all the way to the top anyway.) = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/10.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/system-settings-and-its-last-mile-problem/10.1600w.avif" type="image/avif"> (I added a new tag, navigation , to collect posts like these. The title of the post is a reference to a logistics term .)

0 views
Unsung 2 days ago

“From digital mischief to outright destruction”

The 1980s and 1990s PC viruses were a special breed. The MS-DOS operating system wasn’t particularly secure – few home computer operating systems were back then – so viruses could spread quickly, and many did. Some of the viruses focused more on actually wreaking havoc and destroying things, and some primarily on effective propagation that served no additional purpose. The last group was viruses that were maybe… a little bit exhibitionist, announcing themselves with various audio-visual effects of the kind of quality you might expect from vintage computers in the hands of bored programmers. Various antivirus programs were as much a necessity back then as ad blockers feel today. In Poland, the most popular one was called MkS_Vir – named after its creator, Marek Sell. I believe MkS_Vir had a reputation for being great at detecting the viruses and disinfecting machines, but part of its appeal was that it also hosted something that you could call a virus zoo – a few actual viruses, completely defanged but still presenting their audio-visual effects, so you could experience them without any fear. I emulated MkS_Vir just to show you. Here’s a virus that once in a while would make all your letters uppercase: Here’s one that would rotate your screen on Fridays: Here’s one that a month after the infection would show flames – and render your computer unbootable: Here’s one that laughed at you: Here’s one that waited three months and then ate your letters: This one was a true classic, making your letters fall: And this one flushed your screen like a toilet: These all seem retro and cute today. I don’t want to trivialize them, though, even those that “only” messed up your screen. Imagine being new to home computers – already a petrifying proposition – and then seeing something like that, not knowing whether computers were even meant to do this . Turns out, there were a lot more “virus zoo” efforts. A Czech antivirus program called AVG also had a built-in one; YouTube has a video walking your through a lot of them in sequence . The Internet Archive has a malware museum , created by Mikko Hypponen in 2016. What’s particularly interesting about this effort is that these 87 entries are not screenshots or videos – they are actually emulated malware, rendered inert in part by emulation’s inherent sandboxing, and in part by some careful preparation, likely similar to the ones above. Lastly, danooct1 has been collecting and showcasing viruses, trojans , and worms on his YouTube channel . These are not the most gripping narratively, but at 672 videos (sic!), one has to admire the sheer effort. They extend the timeframe from the DOS era to early Windows, and occasionally even more platforms. This makes it possible to see more modern takes on the viruses above, like a melting screen worm , now in true graphics mode… …or the legendary (in the derogatory sense) YouAreAnIdiot trojan : Just visit the channel , click on Popular, and enjoy from the comfort of your timeshifted and airgapped chair. (The title of the post comes from the description of danooct1’s channel.)

0 views