How Anthropic Made claude.ai 3x Faster With Claude
- YT :: https://www.youtube.com/watch?v=FsDUOUV9Vs8
- Original title :: How Anthropic made Claude 3x faster
Theo reads Anthropic's blog post on a two-week August sprint that made claude.ai and the Claude Desktop app ~3x faster, done almost entirely by Claude running in a shared Slack channel (Claude Tag). The core lesson he endorses: once Claude can measure something deterministically, it can hill-climb it - so the highest-leverage work is finding new things to measure and ratcheting wins in CI. He mixes praise with live demos of regressions (stale sidebar cache) and argues some of the chosen metrics likely encouraged them.
Results
Four journeys covering 95% of activity (launch, start conversation, load conversation, send message) were broken into 13 measurements. At p75: web fresh load 3.1s → 0.55s, desktop launch 6s+ → ~3s, starting a Claude Code session 0.8s → 0.3s, loading Cowork sessions ~3s → <1s, Cowork send 1s → 48ms. 12 of 13 targets were hit by day three; over 3,000 changes merged, reportedly with no customer-facing incident or rollback.
Theo's live testing
The app does feel faster, but he reproduces data-layer bugs: a new thread vanishes from the sidebar if you refresh before it persists, and threads deleted in another browser stay in the IndexedDB-cached sidebar without invalidation. His verdict: part of the speed came from caching too aggressively and revalidating too rarely. In T3 Chat he shows cached data in a faded state until the server confirms it.
Setup
A Slack channel with standing instructions: monitor deploys for regressions, audit telemetry, maintain dashboards, fix low-hanging fruit, propose projects, communicate with humans, and become as autonomous as possible. Claude used the Datadog MCP to pick the journeys. Instrumentation was made comparable: each metric starts at a user interaction, ends at render, and separates client from server time. Theo stresses that bad measurement (timing from component mount rather than page load) is the most common reason performance arguments go wrong.
Claude estimated each of ~20 projects in milliseconds; it badly overestimated durations, as models still do (Theo shows Opus quoting 25 working days for something doable in hours).
Notable optimizations
- Static composer baked into HTML so users can type before React initializes; precompiled V8 code cache for the desktop shell.
- Composer kept mounted across conversations, sessions prefetched on hover, sidebar re-renders cut 90%.
- A React hook census found ~6,900 hooks and 900 store subscriptions re-rendering on every keystroke in the composer.
- A single
:root:has()selector added 24ms to every DOM change. - A leftover
location.reloadpath caused ~500k hidden reloads a day; idle tabs cloned identical cache snapshots into IndexedDB twice a minute on the main thread. - Em dashes or curly quotes made V8 store the whole reply as UTF-16, pushing syntax-highlighting regexes onto a slow two-byte path (~1s freezes); a 20-line fix copies code blocks into one-byte strings. Theo's take: highlighting belongs in a worker/WASM, never on the main thread.
- Chrome's speculative prerender rendered the page at the previous tab's height (the managed new-tab page has a 56px footer), causing a layout shift after first paint.
Deterministic lab measurement
Wall-clock time is too noisy for CI gates, so they used deterministic proxies: JS instruction counts under Valgrind with node --predictable, V8 precise-coverage call counts, React commits per interaction, style recalcs and DOM mutations. Each benchmark had to prove it tracked wall-clock time or be dropped. On the message-tree assembly path, a quarter of instructions were megamorphic lookups resolving the same message ID three times; fixes cut instructions 48% and wall clock 78%. Benchmarks became ratchets: a PR raising the count fails CI, and a daily job lowers the ceiling.
Theo's caution: counting requests or commits pushes agents to remove work that isn't blocking (e.g. sidebar refetches), which is exactly how the stale-sidebar regression could arise. A layout-shift test that fails on any shift may also forbid correct cache revalidation.
The loop and scaling out
Someone opens a thread with a recording of a slow spot; Claude traces it, builds a benchmark, ships risk-sized PRs behind flags, watches field data after deploy, ratchets the win or turns the flag off. Threads ran in parallel, some producing 50-100 PRs, and Claude opened new threads itself. Up to 200 changes landed per day; about a third of PRs added telemetry or guardrails. Nearly 200 feature flags were introduced, over half cleaned up by sprint end. The static composer got dozens of guardrails: JSDOM-rendered markup, pixel alignment across 14 viewports, keystroke-handoff tests, and field monitoring. Rollout went employees → 1% → everyone.
Theo's parallel: once a verification harness exists, fanning out agents is cheap; his own perf harness let an agent auto-merge ~40 T3 Code PRs with two minor regressions. He argues engineers must still test builds by hand, because users won't report subtle regressions; make that cheap (e.g. a PR label that builds a downloadable DMG).
Steering: ambition, taste, direction
- Ambition :: Claude defaults to cautious scope and pessimistic timelines; engineers repeatedly pushed it ("please be braver", "the targets are not the stopping point"). Theo agrees words like "ambitious" or "boil the ocean" move models off the safe path; his "wacky ideas" prompt produced a custom Rusty V8 runtime for his Lakebed project.
- Taste :: Claude posted before/after recordings for user-visible trade-offs (cell-by-cell tables, skeleton delays, word fades). Theo would wait for whole tables and paragraphs and never stream token-by-token.
- Direction :: threads were kept narrow; humans sequenced work and killed over-engineering, e.g. a 900-line build plugin to save 2ms per send.
120 Hz frame budget
Claude built a deterministic 120 Hz headless Chromium rig (DevTools BeginFrame control) and stepped through streaming replies frame by frame against an 8.3ms budget: memoized finished blocks, moved code-fence tokenization to a worker. One thread landed ~60 PRs; long replies now block the main thread 200ms instead of 750ms, use a third of the CPU, and hold 120 fps. The rig runs nightly.
Theo's broader take
Anthropic pioneered letting AI write too much of its own code and is now using better models to clean up that slop. He attributes weak engineering to a research-first culture that didn't value engineers. Takeaway: don't ask the model to "improve performance"; have it build and validate measurements first, then climb them. Working around slop with harnesses, not reading every line, is the new meta.