This Code Is CRAP — Alberto Savoia

In 2007, Alberto Savoia and Bob Evans launched CRAP — Change Risk Anti-Patterns. The starting observation is linguistic: engineers inheriting bad code don’t say “the median cyclomatic complexity is unacceptable.” They say the code is crap. So they coined an acronym that matches the vocabulary of the people who need it, deliberately mildly offensive so it sticks. The formula, CRAP1: CRAP1(m) = comp(m)^2 × (1 - cov(m)/100)^3 + comp(m) comp(m) is cyclomatic complexity; cov(m) is basis-path coverage from automated tests Above 30, the method is considered CRAPpy The point is that it sorts methods by change risk — sort the list, talk about the top of it The provenance is the interesting part. It wasn’t derived from theory. Savoia had source and JUnit tests for a large set of open-source and commercial Java projects, ranked code with a candidate formula, asked colleagues whether they agreed, and iterated until diminishing returns. The curve is a fit to human judgement — he says so plainly instead of dressing it up as a result. ...

September 16, 2026 · 2 min

A Software Thing I Built: GPS on a 25MHz 486-SX — spd

A forum post from an embedded contractor looking back at a 1993 job: a “real-time GPS-driven moving map display” running on a 25MHz 486-SX with 32MB of RAM, a 1024x768 display, software in ROM, and no math co-processor. This was about five years before anyone had seen a consumer GPS from Garmin or Magellan. The constraint was the whole design problem: The 486-SX shipped without an FPU Every GIS library he could find leaned on floating-point trig The target was a moving map redrawn every two seconds The unlock came from a Dr. Dobb’s Journal article about a library called Hipparchus, from a company named Geodesy. It used Voronoi cells and reduced almost all of the computation to 8- and 16-bit integer arithmetic, with one or two single-precision operations left over. According to the author it actually had higher resolution than extended-precision floating point. He prototyped from the article’s code, the client bought a license, and the result reportedly ran about twice as fast as the first consumer units while driving a colour 1024x768 display every two seconds. ...

September 16, 2026 · 2 min

On Learning Programming in an Age of LLMs — Mark Seemann

A reader wrote Mark Seemann a long letter: no formal CS background, a year of LLM-assisted work, a fairly large TypeScript and PostgreSQL system with APIs and multi-model workflows. Then the uncomfortable part — trying to turn the prototype into a product, he suspects he built something above his own level of understanding. Seemann answers in public, and says up front that his answers are not rigorous. The reader’s diagnosis is familiar to anyone who has done AI-assisted work at speed: ...

September 16, 2026 · 2 min

I've factored the RSA keys of a Certificate Authority from the 90s — Matthew McPherrin

In March 1999, Netscape 4.51 shipped with two 512-bit RSA root certificates from E-Certify, a defunct Canadian certificate authority — one trusted for SSL, one for S/MIME. RSA-155, the 512-bit factoring challenge number, was factored later that same year. The keys were already too weak on the day the browser started trusting them. Matthew McPherrin factored both of them on a desktop. The archaeology is the fun part: Root certificates were bundled inside browser installers, so both the Netscape and Internet Explorer archives on archive.org contain decades of trust decisions Extracting every bundled root and filtering by key size turned up the pair of E-Certify 512-bit roots, removed by Netscape in 2002 CADO-NFS on a Ryzen 9 5950X took 32 hours for the Gold Server key and 29 hours for the Gold Client key The two primes give you back the private key, so he could issue certificates from a CA that stopped existing a quarter century ago Verifying that took a custom TLS server written in Go, because Netscape 4.51 has essentially zero TLS overlap with anything modern; the result is live at e-certify.fly.dev and rates an F from SSL Labs The transferable lesson is that key strength is not a property of an algorithm, it is a property of an era and an attacker budget: ...

September 15, 2026 · 2 min

Performance Improvements in .NET 11 — Stephen Toub

Stephen Toub writes the longest performance post of the year, every year, and the framing has not changed: nothing in it is a breakthrough. A bounds check removed, an allocation that stops happening, a lock that is not taken, a loop that runs in fewer cycles. Each one is nearly invisible on its own, and the point is that they are not invisible together. What is in the .NET 11 edition: ...

September 15, 2026 · 3 min

When Code Is a Maze, Smart Developers Make Maps — Simon Smart

Simon Smart argues that modern code is harder to understand than code from any previous era. Not because it is badly written — because decoupling replaced “spaghetti code” with “ravioli code”: components that are individually tidy and act autonomously, with no visible thread connecting them. The cost lands on anyone who has to navigate it: With spaghetti there were at least strands to follow. With pub/sub, it can be extremely difficult to say what a piece of code does or what caused it to execute. The default behaviour is to charge into the maze, run around until you hit the right place, then leave — and do it all again next time. “In most cases, we spend much more time trying to understand the code than we ever do making changes to it.” He is careful not to turn this into an architecture argument — choosing how code is shaped is “very much a luxury” for most developers. Everyone else just has to find their way through what they inherited. So the leverage is in leaving navigation aids. ...

September 15, 2026 · 3 min

High-performance garbage collection for C++ — Anton Bikineev, Omer Katz & Michael Lippautz

Blink is C++, and the DOM object graph it builds is tangled with JavaScript objects, so Chromium manages that memory with a real garbage collector: Oilpan, connected to V8 through cross-component tracing that treats the C++/JS object graph as one heap. This V8 blog post explains the core principles, then digs into the part that shows up as page jank — reclaiming dead objects concurrently. Marking is ordinary graph traversal: objects are nodes, pointers are edges, roots are registers, stack, and globals. C++ objects cannot change representation at runtime, so Oilpan asks them to declare their outgoing edges precisely: ...

September 14, 2026 · 3 min

From Git to Fossil — Lucio F. Albenga

Lucio F. Albenga had already used RCS, CVS, SVN, Mercurial, Bazaar and Git when he went looking for a replacement for his personal projects. He landed on Fossil — the version control system from the SQLite author, shipped as a single C binary. His argument is not that Git fails at scale. It is that most projects never needed Git’s scale and pay for it in ceremony. What he was actually after: ...

September 14, 2026 · 2 min

How to Write an Effective Software Design Document — Michael Lynch

Michael Lynch has written design docs at Google, Microsoft and his own companies. This excerpt from his book Refactoring English is the most concrete treatment of the form I’ve read, mostly because every recommendation ships with actual example prose — a fictional caching layer called RecencyBank — instead of a heading checklist. The organising idea is that a design doc is not a specification. It forces you through the decisions before you write the wrong implementation, and it’s the cheapest way to get teammates aligned. ...

September 14, 2026 · 3 min

Bad Code Is Kudzu — Vicki Boykis

Vicki Boykis takes one metaphor and follows it all the way. Kudzu was imported to the American South deliberately, as erosion control, and grew until it was taking sidewalks, foundations and trees. The only thing that kills it is aggressive pruning, done by everyone who lives near it at once. Features are the same. Once a feature is merged, removing it stops being a matter of deleting code: Other people start writing code on top of it You end up two years deep into an implemented feature no one wants “Deleting code is hard, particularly because it’s a thankless task that usually doesn’t go on promo packets” But deleting code is silent — nobody notices it happening The incentive problem is why it doesn’t happen: shipping is visible and honest cleanup is not, which is how codebases accumulate features nobody asked for. Her claim about this moment is that the tradeoff has inverted. Adding code is nearly free now, so the plan to remove it should be written at the same time as the code — and removal has gotten cheaper too. ...

September 14, 2026 · 2 min

Pandas Should Go Extinct — Eddie Atkinson

Eddie Atkinson’s argument is not that Pandas is unpopular — it’s that Pandas’ performance cliff chooses your architecture for you. Teams hit memory pressure in the tens of gigabytes and reach for Spark, Databricks, Snowflake or Dask: distributed systems they will probably never need. He gave the talk at Latency Conference and published the benchmarks with it. How much “Big Data” is actually out there: Amazon’s own analysis of its Redshift fleet puts 94.68% of tables under 100GB 86.9% of queries operate on 80GB or less, and finish in under a second Even assuming 10KB rows, the ceiling is 1TB — “You have Medium Data problems, and need Medium Data solutions” On the 1 Billion Row Challenge, 32 cores and 128GB: ...

September 14, 2026 · 2 min

Why Is Google Still Serving Dodgy Ads? — Chris Greening

Chris Greening (who writes and makes videos as atomic14) noticed an ad in the YouTube app on his iPhone because he accidentally tapped it — the kind of lapse in concentration these things are engineered to catch. The creative was a fake iOS alert reading “iPhone Storage is Full,” complete with system-style typography and Yes/No buttons, sitting inside the ad slot. He did the civic thing and reported it. Google’s response was that the ad does not violate policy. He reported it again, and got the same answer. Others reported the same ad and received the same boilerplate: “We found that the ad doesn’t go against Google’s policies, which prohibit certain content and practices that we believe to be harmful to users and the overall online ecosystem.” ...

September 14, 2026 · 6 min

Lotus Notes and the Dangers of Starting from Scratch — Matthew Guay

Lotus Notes shipped in 1989 with encryption two years before PGP brought it to ordinary email, attachments before MIME, read receipts, a replicated shared database, and a custom interface that worked the same on every platform. It was not an email app — email was roughly 5% of how people used it. Matthew Guay traces it back to PLATO Notes in 1973 and follows what it cost to build the future alone. ...

September 13, 2026 · 3 min

Understanding the Recent DDoS Attack Against Read the Docs — David Fischer

In mid-to-late June 2026, Read the Docs absorbed the largest attack in its history: 5.5 million requests per minute at peak against a normal daily peak under 100,000, sustained for nearly ten days, against a small ops team running on Cloudflare. This is the write-up of what failed and what actually held. The attack was deliberately built around the defenses it expected: Millions of unique IPs across hundreds of ASNs, mixing residential blocks with hosting providers — breaking per-colo rate limiting Systematically randomised HTTP headers and TLS parameters, which made JA3/JA4 fingerprinting useless Cache evasion by design: random 404 paths and uncached 302 redirects served by the Python backend instead of the edge Adaptive rotation of target paths and IP pools whenever a rule landed A “yo-yo” pattern — ramp until the rate-limit threshold shows, then back off — designed to maximise autoscaling spend What worked, roughly in order of impact: ...

September 13, 2026 · 2 min

Reverse engineering my e-scooter and rewriting the firmware in Rust — Ben

Ben bought an e-scooter, found a button combination that skipped the PIN entry, and spent the next six months reverse engineering it down to the firmware — then replaced the display unit’s firmware with his own in Rust. Getting in was easier than it should have been: The phone app’s Bluetooth handlers exposed over-the-air update capability, plus telemetry the app never shows (motor current, battery charge history) that is also reported to the manufacturer The display’s “charge only” USB-C port turned out to be carrying a CAN bus on two of its pins The controller MCU (an APM32E103, an STM32F103 clone) still had its markings and an SWD header: OpenOCD dumped flash and RAM, and Ghidra found three images — bootloader, updater and application The firmware used the chip vendor’s peripheral library with no LTO, so decompiled HAL functions matched the published source closely enough to recover pin assignments and peripheral configuration The update path is the part that should worry anyone buying one of these: ...

September 13, 2026 · 3 min

I made a build visualizer to understand Bun's compile times — Lalit Maganti

Tracing every process a build launches turns “the build is slow” into a diagram. Lalit Maganti built buildprof to settle one question: why Bun’s Linux CI build ran ~30 minutes in the Zig era and ~5m40s in the Rust era, and how much of the celebrated >5× speedup was actually the language. He reproduced the numbers on a 6-core VM (24m24s versus 5m40s), then let the trace answer it: In the Zig build a single ld.lld invocation ran alone at the end for 16m35s — two-thirds of the build — and LLD’s own OptModule phase accounted for more than ten minutes of that The Zig build used Full LTO; the Rust build used ThinLTO, a detail mentioned only in passing in the original claim Switching just Bun’s own Zig code to ThinLTO: 20m20s. Still slow, because WebKit and ICU arrive as prebuilt static libraries compiled with Full LTO — rebuilding those too brought the build to 15m11s The gap that remained was structural, not linguistic: Rust compiles more than 90 crates in parallel, while the Zig build funnelled everything through one module, and dependency arrows showed the linker waiting on a single bun-zig.o while the C++ side had long finished The tool design is worth copying. Builds are process trees, so recording fork/exec with ptrace — plus a seccomp filter for file events — covers Cargo, Ninja, Make, Zig and the arbitrary scripts wrapped around them, with no per-build-system integration. Overhead is small (ripgrep 12.27s → 12.43s, Redis 26.78s → 31.89s), and --no-file-events trades file detail for speed. ...

September 13, 2026 · 2 min

Stabilizing Rust's Never Type — Daroc Alden

Rust’s never type — the ! used for functions that never return — is now stable, and Infallible becomes an alias for it. The change is tiny and the type has existed internally for years. The interesting part is what it took to ship it, which LWN’s write-up documents in detail. What the never type is for: Generics get cheaper. A FromStr impl whose conversion cannot fail can set type Err = !, keeping the same generic interface while the compiler strips the error branch as unreachable. Type inference stays uniform. Rust treats if and loops as expressions, so the compiler needs some type for the result of an infinite loop rather than a special rule. ! coerces to any other type, which is sound precisely because the value can never exist — dead-code elimination driven by the type system. The hard part was never fallback: ...

September 13, 2026 · 2 min

How We Rebuilt Complex Permissions Without Migrating to Zanzibar — Adilson

Infisical added folder-level access control to a permissions system that already had too many ways to grant access. The write-up is framed around a claim that generalizes well past authorization: RBAC belongs to the same class of work as billing, schema migrations, and audit logs — nobody praises a correct one, and everyone notices when it is wrong. Why roles alone could not express the requirement: An engineer who is the only one with Netsuite experience needs their engineer role plus specific credentials. A contractor refactoring Lambda functions needs that role minus billing data. The role does not change; the access requirement does. Both conventional fixes are bad — editing the shared role grants or removes too much, and cloning a custom role creates parallel configuration for a one-off case that will drift. The legacy workaround, per-person Additional Privileges, could not subtract privileges and stored paths as strings, so renaming a folder silently broke a grant. Folder grants key off folder IDs instead. They deliberately skipped Zanzibar-style authorization (SpiceDB, OpenFGA): ...

September 13, 2026 · 3 min

Don't call yourself an artisanal programmer — purplesyringa

purplesyringa writes code by hand and refuses LLMs, and recently noticed the industry has a word for that: artisanal. The split being sold — serious engineers who care about the end result versus hobbyists who enjoy the act of coding — does not describe the job. Accepting the label, the essay argues, quietly accepted the question of whether AI-free work is engineering at all. Her own position is about correctness, not nostalgia: ...

September 13, 2026 · 3 min

When Anyone Can Build Software, Who Decides What Not to Build? — Younss

An enterprise architect with twenty years across several institutions argues that cheap generation removed the wrong part of the job. Software was never expensive because code was hard to write — it is expensive because you operate it, secure it, staff it, integrate it, govern its data, and live with its decisions for a decade. He concedes the other side first: much of what architecture groups produced was commodity artifact, and a function staffed to produce artifacts should get smaller. ...

September 13, 2026 · 4 min