Tokens Get Cheaper, Diffs Get Longer · Morning Gist
Tuesday, October 135 stories · 16 min
Tokens Get Cheaper, Diffs Get Longer
OpenAI and Anthropic cut model prices, and engineers at Netflix, GitHub and PlanetScale explain how they solved identity, scrolling and CPU-choice problems.
Picked from 120 new articles across 23 sources · arrow keys for other days
Today in 30 seconds
30s left
OpenAI's GPT-6 Luna halves mid-tier prices to $0.10 per million input tokens. Anthropic cut Claude Opus 5.5 prices by 20%. story 1 ↓
Netflix issues Spark certificates only when two claims agree: one from AWS, and one signed by its own job launcher. story 2 ↓
GitHub got million-line PRs to scroll smoothly. The hard part was 400+ comments whose heights aren't known until they're drawn. story 3 ↓
A position paper finds that plain coding agents on newer models beat purpose-built text-to-SQL systems. Most remaining errors came from not knowing the business's data. story 4 ↓
PlanetScale warns that '4 vCPUs' can mean whole cores or shared threads, and a compiler default keeps Postgres replicas from crossing CPU architectures. story 5 ↓
OpenAI also launched GPT-6.1 Sol and says it nearly matches Astra at coding and computer use for one-fifth of Astra's token prices.
1/5Simon Willison· Sep 22
OpenAI halves prices with GPT-6 as Anthropic cuts Claude Opus prices
On 22 September 2026, OpenAI launched GPT-6 Sol and Luna at half the price of the models they replace, and Anthropic launched Claude Opus 5.5 20% cheaper. Simon Willison found Opus 5.5's "max" thinking setting unusable.
Why it matters · If you build on these models, a strong mid-tier model now costs half what it did yesterday, so cost estimates and default-model choices need redoing.
Know this first
Context from the editor, not the article · 39 sec
1 · How model pricing works
AI companies charge for API use by the token. A token is a chunk of text, roughly three-quarters of a word. Prices are quoted per million tokens ("$2/M"). Input (what you send) and output (what the model writes) are billed separately, and output usually costs four to six times more.
2 · Cached input
When a request starts with the same text as an earlier one, the provider can reuse work it already did on that prefix and charge a much lower "cached input" rate. Long agent sessions resend the whole conversation on every turn, so most of their input tokens get billed at this cheaper rate.
3 · Thinking effort levels
Reasoning models can write hidden working-out before they answer. Users choose how much with an effort setting, from low up to "max". That working-out counts as output tokens, so higher effort costs more, takes longer, and uses up the cap on how many tokens one response can contain.
How Netflix turns an AWS role into a trusted internal identity for Spark
Netflix's Spark jobs on Amazon's managed compute start with only an AWS identity. Netflix swaps it for an internal certificate, but only when AWS and Netflix's own job launcher independently agree on who the job is.
Why it matters · Any company with its own service identity system will hit this gap on managed cloud compute, and Netflix's design is a reusable template for closing it.
Know this first
Context from the editor, not the article · 35 sec
1 · Cloud identity versus your own
AWS gives each running process an IAM role, a set of permissions plus temporary credentials. Many companies also run their own identity system that their internal services check before answering a request. The two are separate, so a process holding only an AWS role can't reach internal services.
2 · Certificates and mutual TLS
An X.509 certificate is a signed document that binds a name to a cryptographic key. With mutual TLS, both sides of a connection show certificates, so each one knows who the other is. A private PKI is a company's own system for issuing these certificates.
3 · Managed compute limits control
3/5GitHub Engineering· Alberto Gimeno· Sep 23
How GitHub made million-line pull requests scroll smoothly in its Copilot app
GitHub rebuilt the pull request view in its Copilot app by tracking code lines and comments as two separate height systems. A 2,200-file, million-line change with 400+ comments now scrolls like a small one.
Why it matters · It's a concrete pattern for any interface that mixes fixed-size and variable-size content, plus a reusable way to find intermittent UI bugs with automated measurement loops instead of human eyeballs.
Know this first
Context from the editor, not the article · 35 sec
1 · Pull requests and diffs
A pull request proposes a code change for review. Its diff shows every added or removed line, file by file. Reviewers attach inline comment threads to specific lines. Big refactors or migrations sometimes can't be split, so one pull request can grow to thousands of files.
2 · The DOM and its cost
Browsers and web-based desktop apps draw pages from the DOM, a tree of element objects. Each element costs memory and layout work. A page with a million elements becomes slow to load and scroll, so large lists need tricks to avoid creating them all.
3 · Virtualized lists
4/5Murat Demirbas (Metadata)· Murat· Sep 23
Plain coding agents now beat specialized data agents, a new position paper finds
A new position paper ran a plain coding agent against purpose-built data agents on the same models. With the newest model, the plain agent won. The authors say research should move to storing knowledge about a company's data. Murat Demirbas reviews it.
Why it matters · If newer models absorb custom agent scaffolding, engineering effort is better spent on durable knowledge about your data and code than on clever orchestration.
Know this first
Context from the editor, not the article · 34 sec
1 · The Bitter Lesson
A 2019 essay by AI researcher Rich Sutton. It argues that general methods which improve with more computation, like learning and search, eventually beat systems built on hand-coded human expertise. Researchers find this 'bitter' because years of careful engineering keep getting overtaken.
2 · What a data agent is
A data agent is a large language model (LLM) that answers questions about a company's databases. It inspects tables, writes SQL or code, runs it, reads the results and tries again. Researchers wrap the model in 'scaffolding': prompts, tools and multi-step pipelines that guide this loop.
3 · Why schemas confuse agents
5/5PlanetScale· Ahmed Darwich· Sep 25
PlanetScale's guide to choosing ARM or x86 CPUs for Postgres
PlanetScale recommends ARM by default for Postgres. ARM's whole cores suit many small concurrent queries. x86's faster cores and wider vector instructions suit a few heavy queries. Switching later requires a full migration.
Why it matters · "4 vCPUs" can mean very different hardware, and the cloud database architecture you pick at creation is effectively permanent.
Know this first
Context from the editor, not the article · 38 sec
1 · Two CPU families
x86-64 is the instruction set from Intel and AMD that runs most PCs and traditional servers. aarch64, also called ARM64, is the 64-bit ARM instruction set. It started in low-power phones and now appears in cloud servers. Software must be compiled separately for each, and the two can behave differently in subtle ways.
2 · What a vCPU is
Cloud providers sell compute in virtual CPUs, or vCPUs. A vCPU is not a fixed unit. Depending on the chip, it may be a full physical core or one of two hardware threads that share a core. So two instances with the same vCPU count can have quite different real capacity.
3 · How Postgres replicas work
Postgres usually creates a replica by copying the primary's on-disk data files byte for byte. It then keeps the copy current by replaying the write-ahead log, which records every change. This only works if both machines interpret those bytes the same way.
Pelican drawings by six GPT models at different thinking levels. GPT-6 uses more muted colours than GPT-5.6.1 / 2
On 22 September 2026, Anthropic released Claude Opus 5.5. About an hour later, OpenAI released GPT-6 Sol and GPT-6 Luna. Developer Simon Willison tests new models as soon as they appear, and his first impressions show a price war.
OpenAI halves its prices
AI model APIs charge per million 1. A token is a piece of text about three-quarters of a word long. Input and output have separate prices, and there's a cheaper "2" rate for text the provider has already processed.
GPT-6 Luna: $0.10 input / $0.50 output, down from $0.20 / $1.20 for GPT-5.6 Luna. Willison already used the older Luna as his go-to cheap model for building apps.
GPT-6 Sol: $2 / $10, exactly half the price of GPT-5.6 Sol ($4 / $20).
GPT-5.6 also has a 25% price rise scheduled for November, so the gap will grow. Luna is now one of the cheapest models OpenAI has ever released. Only the much weaker GPT-4.1 Nano and GPT-5 Nano cost less. Sol now matches xAI's Grok 4.7 ($2 / $6) on input.
Anthropic cuts too, but less
Opus 4.5 through Opus 5 all cost $5 / $25. Opus 5.5 costs $4 / $20, a 20% cut. The cached-input price fell 60%. Willison says the cache cut matters most for 3 work, where a model runs multi-step tasks and resends the whole conversation on every turn. In those sessions, more than 90% of input tokens are usually billed at the cached rate. Anthropic says Opus 5.5 communicates more clearly and matches Fable 5.1, its top model, in intelligence.
Even after the cut, Opus costs twice as much as GPT-6 Sol. The top tier hasn't moved: GPT-6 Astra and Claude Fable 5.1 still cost $10 / $50. Anthropic says Sonnet 5.5 and Haiku 5.5 are coming soon. Haiku 4.5 costs $1 / $5, ten times GPT-6 Luna.
"Max" thinking that never finishes
Willison's informal benchmark asks each model to draw a pelican riding a bicycle as an 4, a text-based vector image format. He runs it at each "5" level, which sets how much hidden reasoning the model writes before answering. On "max", Opus 5.5 planned the drawing in great detail, down to shin lengths and chainring teeth. Then it hit Claude's 128,000-token 6 before writing any SVG. It failed the same way twice. Each attempt cost $2.56 and took nearly 20 minutes.
Willison calls "max" "effectively useless". He reasons that if it overthinks a toy prompt, he can't trust it on real work. Fable 5.1 on max had no such problem.
Where he's landed
Willison now uses GPT-6 Sol by default in 7 and Opus 5.5 by default in 8, the two companies' coding agents. These are day-one impressions, and there are no benchmarks beyond the pelicans.
On 22 September 2026, Anthropic released Claude Opus 5.5. About an hour later, OpenAI released GPT-6 Sol and GPT-6 Luna. The day before, xAI had shipped Grok 4.7 and Xiaomi had shipped MiMo v2.6. Simon Willison is a developer who tests new models as soon as they come out. He calls his write-up early impressions, and the clearest thing in it is a price war. OpenAI halved the prices of its mid and low tiers. Anthropic cut its flagship's price for the first time in five releases.
The new price table
Model APIs are billed per million 1. A token is a piece of text about three-quarters of a word long. Input, 2 and output each have their own price. Cached input is the cheaper rate charged when the start of a request repeats text the provider has already processed. Here are the main prices from Willison's table (input / cached input / output, per million tokens):
Model
Input
Cached
Output
GPT-6 Luna
$0.10
$0.01
$0.50
GPT-5.6 Luna
$0.20
$0.02
$1.20
Grok 4.7
$2
$0.50
$6
GPT-6 Sol
$2
$0.20
$10
GPT-5.6 Terra
$2
$0.20
$12
Claude Opus 5.5
$4
$0.20
$20
GPT-5.6 Sol
$4
$0.40
$20
Claude Fable 5.1
$10
$0.25
$50
GPT-6 Astra
$10
$1
$50
Willison already used GPT-5.6 Luna as his favourite model to build applications on, because it performed well and cost little. GPT-6 Luna halves its input and cached prices and cuts output by about 58%. GPT-6 Sol is exactly half the price of GPT-5.6 Sol on all three rates. The gap will soon be wider. GPT-5.6 has a 25% price rise scheduled for November, so the current GPT-5.6 prices are effectively promotional.
The cuts hit competitors and OpenAI's own older models alike. Grok 4.7 launched at $2/$6, less than half the price of GPT-5.6 Sol. GPT-6 Sol now matches it on input. GPT-5.6 Terra costs the same as GPT-6 Sol, and Willison says that leaves no reason to use it. At the bottom of the range, the only cheaper OpenAI models have been the much weaker GPT-4.1 Nano ($0.10/$0.40, April 2025) and GPT-5 Nano ($0.05/$0.40, August 2025).
Anthropic's response: Opus 5.5
Opus 4.5 through Opus 5 all kept the same price: $5 per million input tokens and $25 per million output. Opus 5.5 costs $4 and $20, a 20% cut. The cached-input price fell 60%, to $0.20.
Willison thinks the cache price matters more than the headline rate. In 3 work, where a model runs multi-step tasks, calls tools and resends the whole conversation each turn, more than 90% of input tokens are often billed at the cached rate. To illustrate (this is not a figure from the article): an agent session that sends 10 million input tokens, 9 million of them cached, used to cost about $4.50 in cached reads plus $5 in fresh input. At the new prices it costs $1.80 plus $4.
Anthropic's Thariq Shihipar describes Opus 5.5 as a response to user feedback. In his words, it communicates more clearly, it is cheaper per token than Opus 5.0, it matches the intelligence of Fable 5.1 (Anthropic's top-tier model), it uses tokens efficiently, and it works at every effort level. Anthropic also says it is better at Blender, the 3D modelling tool. Willison hasn't tested that yet.
Opus 5.5's $4/$20 equals GPT-5.6 Sol's old price, which OpenAI has just halved. The price war has so far reached only the tier just below the top. GPT-6 Astra and Claude Fable 5.1 both still cost $10/$50. Anthropic says Sonnet 5.5 and Haiku 5.5 are "coming soon". Willison wonders whether Haiku can compete on price again: Haiku 4.5 costs $1/$5, ten times GPT-6 Luna.
When "max" thinking breaks
Willison's informal benchmark asks each model to "Generate an 4 of a pelican riding a bicycle". SVG is a text-based format for drawing vector images. Willison runs the prompt at each thinking-effort level. That setting controls how much hidden reasoning a model writes before it answers.
For the first time, a model returned nothing. Opus 5.5 on "max" called the prompt "a classic test request" and then planned in great detail. It checked that a shin length "checks out at roughly 95.2", worked out the leg path from hip to knee to ankle, confirmed the far crank arm would be hidden behind the seat tube, and noted that no font-family was needed because the image had no text. Then it stopped. Claude models cap a single response at 128,000 output tokens, and the reasoning counts toward that cap. Opus 5.5 used all of it before writing any SVG.
A second attempt failed the same way. The cost adds up: 128,000 output tokens at $20 per million is $2.56, which is what each attempt cost. Each also took nearly 20 minutes. Willison's conclusion: if "max" thinks itself to death on a toy prompt, he doesn't trust it on real work, and he calls the setting "effectively useless". Fable 5.1 on max did not overthink, and it drew the best pelican he has had from any Anthropic model.
Willison admits that comparing companies by pelican drawings may not make much sense. He still finds the test useful for comparing one model family across reasoning levels. One example: the GPT-5.6 models chose bold, bright colours and the GPT-6 models chose muted ones.
What he's using now
Willison has made GPT-6 Sol his default in 5, OpenAI's coding agent, and Opus 5.5 his default in 6, Anthropic's coding agent. His 7 Agent demo now runs on GPT-6 Luna. Datasette is his tool for exploring and publishing data, and in the demo Luna seems fast and competent at writing SQL queries and building HTML and JavaScript apps.
What's still open
These are first-day impressions. Apart from the pelicans, there are no benchmarks and no head-to-head quality numbers. Two questions remain. Is GPT-6 Sol at half price actually as capable as Opus 5.5 at twice its price? And is the max-effort failure a tuning bug Anthropic will fix, or a real limit of letting a model decide for itself how long to think?
Remember
Cached-input prices matter most for agents: Opus 5.5's cached rate fell 60%, compared with 20% for its headline price.
Hidden reasoning counts toward the output cap, so maximum effort can use up the whole response before any answer appears.
The price cuts have hit the tier below the top; the top models still cost $10/$50 per million tokens.
On managed services like Amazon EMR, AWS runs the machines. You can't install boot-time agents or hand out identity at startup the way you can on servers you run yourself. You still control your code and its runtime, for example through plugins.
Image: Netflix Tech Blog
Netflix has described how its 1 jobs, which run on 2 (AWS's managed service for the Spark data-processing engine), get a trusted Netflix identity even though AWS hands them only an AWS one.
The problem
Internal Netflix services authenticate each other through 3, a private 4 (a company-run system for issuing certificates). Every workload carries a short-lived 5 certificate and proves who it is over 6. Before issuing a certificate, the identity service must confirm the requester really is the workload it claims to be. That check is called 7.
Spark jobs run as a 8, Netflix's unit of data ownership, which has its own tables, users and identity. But on EMR a job starts with only an AWS 9 execution role, the cloud permission set AWS attaches to the job. It can't decrypt protected columns or pass table access checks until it holds a Netflix certificate.
The foundation: a one-to-one mapping
Each Data Project gets its own dedicated IAM role, and a Data Project service records the pairing. That mapping is what lets "running as role R" be translated into "this is workload W." Because one AWS account can't hold tens of thousands of roles, the roles are spread deterministically across a small pool of accounts.
Three steps
Signed claim. The control plane, the only service allowed to launch Spark jobs, signs a small payload naming the identity, its role and its scope, and passes it along in the job's configuration. On its own this proves little, because anyone who reads the configuration could replay it.
Cloud proof. A Spark plugin in the driver (the job's coordinating process) uses the role's credentials to pre-sign a call to 10 (Security Token Service), but doesn't send it. Anyone can fetch the resulting URL, but only the role's holder could have made it, and the answer comes from AWS rather than from the workload.
Corroboration. The identity service fetches the URL, checks the control plane's signature, and issues a certificate only if the role AWS reports matches the role the control plane said it launched.
AWS's answer can't be forged but names only a role. The control plane's claim is specific but replayable. Trusting only where they agree means the workload never vouches for itself.
Scale and renewal
A job can have thousands of executors, the worker processes. Having each one attest would send bursts of AWS calls that look like an attack. So the driver attests once and passes credentials to executors over Spark's encrypted internal channel. That adds a second trust boundary. Certificates are short-lived, so the driver re-attests on a timer, and executors simply exit when their credentials expire.
The post gives no performance numbers, and it doesn't say how the signing key is protected.
Netflix has published how it gives 1 jobs a trusted internal identity when they run on 2. Spark is a distributed data-processing engine. EMR (Elastic MapReduce) is AWS's managed service for running it. The author, Dhruv Pratap, notes that very little of the design depends on Spark or EMR.
The gap
Netflix services authenticate each other through 3, a private 4 (public key infrastructure, a system for issuing and checking certificates). Each workload holds a short-lived 5 certificate, and services check each other's certificates using 6. A workload can't simply ask for a certificate. The identity service first has to confirm the requester really is the workload it claims to be. That check is called 7. On VMs, containers and serverless functions, Netflix can lean on some environment-specific proof that the platform can verify independently.
The second concept is the 8, Netflix's unit of data ownership. A Data Project owns tables, has a list of authorized users and has its own identity. Jobs run as the Data Project, not as the person who launched them, so table access control and audit logs work the same way whether a job is scheduled or interactive.
On EMR, a Spark job starts with only an AWS execution role, the 9 role AWS attaches to the job. It has no Netflix identity. Yet it needs one for nearly everything internal: decrypting an encrypted column, checking table ACLs (access control lists), or keeping an interactive session open longer than a short-lived token lasts.
The mapping comes first
The design depends on a decision made outside Spark entirely. Each Data Project identity maps one-to-one to its own IAM role, and the Data Project service records that mapping. With the mapping, "this process runs as role R" can be translated into "this process is workload W." Pratap argues this is the hard part of bridging two identity systems: committing to a mapping and keeping it authoritative. The cryptographic protocol is the easier part.
One AWS account can't hold tens of thousands of IAM roles, and Netflix expects Data Projects in the tens of thousands. So the roles are sharded deterministically across a small pool of dedicated accounts. A side benefit is that workload roles sit across an account boundary from the control planes that launch them.
Five participants
Control plane: the only service allowed to launch Spark jobs. It holds a signing key issued for this purpose alone.
Data Project service: the authority on which role belongs to which identity.
Identity service: checks attestation requests and issues certificates.
Spark plugin: Spark 3.0+ lets plugins run code while driver and executor processes start up.
10 (Security Token Service): here it plays notary, which isn't its usual job.
Three steps
1. A signed claim. When a job is submitted, the control plane checks the caller, looks up the role, and builds a small payload. The payload names the application identity, the role, and the environment and stack the credentials should be scoped to. The control plane signs it and passes it along as ordinary job configuration. Because only one service can sign, the set of things that can vouch for a job is small and auditable. But the payload is only a claim. Job configuration passes through infrastructure Netflix doesn't fully control, so anyone who can read it can replay it.
2. Proof of the cloud identity. The driver (Spark's coordinating process) starts with the role's credentials available. The plugin uses them to sign a call to sts:GetCallerIdentity but doesn't send it. The result is a short-lived 11. Anyone can fetch it, only the role's holder could have made it, and the answer comes from AWS, not from the workload. To use an analogy, it works like a sealed envelope that only AWS can open and read aloud. HashiCorp Vault's AWS login and AWS's own function attestation use the same trick. The plugin sends the URL and the signed metadata together in one request.
3. Corroboration. The identity service fetches the URL from STS and learns which role signed it. It checks the metadata signature against the control plane's key. It confirms that the role AWS reported matches the role the control plane said it launched for that identity. Then it issues certificates scoped to the signed metadata.
Here is a worked example (the names are illustrative). The control plane signs "identity recs-features, role dp-4812, env prod." STS reports that the URL was signed by dp-4812. The two agree, so a certificate is issued for recs-features in prod. Now suppose an attacker replays that metadata from a process running as some other role. STS reports the other role, the match fails, and no certificate is issued.
The two statements fail in opposite ways. AWS's statement can't be forged but says too little, because a role isn't a workload. The control plane's statement is specific but can be replayed. Netflix takes the application name from the signed metadata and uses AWS's answer only to corroborate it, rather than parsing app names out of role names, which is fragile string matching. That choice costs a network round trip and a stricter signing requirement.
Fan-out and renewal
A Spark job has one driver and up to thousands of executors (worker processes) that come and go. If every executor attested on its own, one job could fire thousands of STS calls in a burst. That looks like an attack and runs into AWS rate limits. Netflix instead has the driver attest once and hand credentials to executors over Spark's internal RPC (remote procedure call), set up with authentication and 12 encryption. Load on the identity service stays flat. The price is a second trust boundary, with the driver now acting as a credential distributor.
Certificates are short-lived, so the driver JVM runs a timer that re-attests well before expiry. Credentials go in a temp directory only the process owner can read, and they're deleted on exit. Executors don't renew. One that outlives its credentials just exits and gets replaced. Pratap's rule is that attestation must be repeatable, not a one-time step at startup, or "a long-running job dies nine hours in."
What's left open
The post gives no numbers on latency, attestation volume or failure rates. It also doesn't say how the control plane's signing key is protected or rotated, or how fast a compromised driver could be contained. The general recipe is still clear: one authoritative mapping, two independent claims checked against each other, a single scarce signer, a hook in the runtime you still control, a deliberate policy on fan-out, and renewal built in from the start.
Remember
Bridging identity systems depends on an authoritative one-to-one mapping more than on clever cryptography.
Pair an unforgeable but vague cloud proof with a specific but replayable signed claim; trust only their agreement.
Distributed engines multiply every per-process call, so decide deliberately where attestation happens and how often it renews.
Virtualization creates elements only for rows near the visible area and reuses them as you scroll. To fake the full list, the app keeps a table of every row's height. Running sums of that table give the scrollbar size and each row's position.
Image: GitHub Engineering
GitHub rebuilt the pull request view in its GitHub Copilot app, a desktop app for working on code, so that huge reviews stay fast. The test case was an open-source pull request with 2,200 files, over a million changed lines and 400+ inline comments. Alberto Gimeno explains how.
Code is easy
You can't create a million 1 elements (the browser's tree of on-screen objects), so long lists use 2: only the roughly 100 rows near the screen exist, and they're recycled as you scroll. A table of row heights fakes the rest. The scrollbar length is the sum of the heights, and each row's position is the total of the heights above it. Every code line has the same known height, so GitHub computes that table once, up front, and it never changes.
Comments are hard
A comment thread's height depends on how its text wraps, whether collapsible <details> sections are open, whether a reply box is growing, and whether images have loaded. You only find out after rendering. A fixed estimate leaves gaps or clips content. Fixing heights after the fact makes the page jump while you scroll.
GitHub's answer is two separate height systems. Code heights stay exact. Comment blocks have their own index: each is tied to a file and line, starts with an estimate, and gets replaced by a measurement. A fingerprint of its content and state, plus the width it was measured at, decides when a cached height is still valid.
Measuring carefully
An early design gave each block a 3, a browser API that reports size changes, and wrote heights straight back into the layout. That can retrigger itself in a loop, so GitHub dropped it. Instead, one batched measuring pass runs when scrolling stops. It only looks at blocks within about 2,400px of the screen, and it always trusts on-screen measurements. Observers now just flag blocks for that pass. The exception is a resize you cause yourself, like opening a reply, which is applied within the same frame. When heights do change, the app keeps whatever you're reading pinned in place.
One bug: the app skipped corrections while the user was scrolling, but its own automatic scrolls fooled that check, so content drifted off screen.
Finding bugs without a human
The view continuously checks its own rules, such as how many elements are mounted and how big scroll corrections are. Automated tests enforce these as limits. An autopilot drove the real app through scrolling, resizing and toggling in a loop, logging health signals that an AI agent could read.
The post reports no timing numbers. It only says the extreme pull request now behaves like a normal one.
GitHub has rebuilt the pull request view in its GitHub Copilot app, a desktop app for working on code, so that very large reviews stay responsive. To stress-test it, the team opened the biggest open-source pull request they could find: 2,200 files, over a million changed lines, and more than 400 inline review comments. Alberto Gimeno's write-up covers three things: the rendering design, the data pipeline that feeds it, and the automated loop the team used to find bugs.
Why code is easy and comments are hard
You can't put a million 1 elements (the browser's tree of on-screen objects) on a page. The standard fix is 2: mount only the roughly 100 rows near the viewport and recycle them as the user scrolls. The illusion depends on a table of row heights. The scrollbar's length is the sum of all heights. Row N's position is the 3, the running total of the heights above it. Scrolling to a row is plain arithmetic.
General-purpose virtualizers fill this table with estimates and correct them as rows are measured. A diff of pure code doesn't need to: every row is one line at a known font size, so the whole table can be computed up front and never changes. GitHub calls this the "all heights known before paint" contract. Its diff surface is built on it. It uses an imperative row renderer that recycles elements instead of creating a React component per row. Offsets are stored in typed arrays, the server streams diff documents structure-first, and there's an exact "scroll to row N" API. No per-frame work grows with the total number of rows.
Comments break the contract. A thread's height depends on how its Markdown wraps at the current width, whether <details> (collapsible) sections are open, whether a reply box is open and growing, plus suggested-change diffs, reactions, and images that change size when they finish loading. You can't know any of this until the thread is rendered. A fixed-size slot from an estimator is right on average but wrong at the extremes. Most comments get blank gaps, and the big ones get clipped or sprout an inner scrollbar. Measuring after paint and writing the result into the shared table moves everything below it while the user is scrolling, so the view visibly jumps.
Two geometries
The fix was to split total height into two independent parts:
total height = exact code height + sum of comment-block heights (estimated, then measured) + scroll padding
The code geometry stays exact and is never rebuilt. Each dynamic block (thread, draft, reply composer) gets a stable key and is anchored to a file, line and side, not to a pixel position. Each block also keeps a fingerprint of everything that could change its height (content, open <details>, active composer) and the width it was last measured at. That width is rounded into buckets so a small window resize doesn't throw away every measurement. A block's effective height is its valid measurement if there is one, otherwise a cached height if the fingerprint and width still match, otherwise the estimate. Blocks scale with the number of comments, not lines, so a few thousand are manageable.
Measuring without a feedback loop
The first design used one 4 per block. ResizeObserver is a browser API that reports when an element changes size. Each observer wrote its block's height back into the layout. GitHub rejected this design: an observer that changes the layout of the element it watches can trigger itself again, and the cost grows with every mounted block.
What shipped is a single measurement pass:
It runs only when scrolling settles, never during a scroll.
It considers only blocks within about 2,400px of the viewport, so the work scales with the screen, not the document.
It reads every mounted block in one batch, causing one 5 (the browser recomputing layout) with no writes in between. Mounted blocks are always measured. One bad bug, blank strips under comments, came from a mounted block being skipped and left on a too-tall estimate.
It renders at most one nearby unmounted block off screen to correct its estimate. Blocks taller than the viewport skip this, because any extra space sits below the fold.
Per-block observers still exist, but by default they only flag a block for the next pass. There is one exception. When you cause a resize yourself, by expanding a section or opening a reply, waiting showed a one-frame mismatch between the comment and the code below it. Now a visible block is measured and corrected in the same frame, before paint. Two limits prevent a loop: at most one synchronous commit per frame, and never during an active scroll.
Keeping your place
When heights change, corrections are applied by identity, not by pixel. The app records which row or block you're looking at and your offset within it. It then applies the height changes, finds that anchor's new position, and scrolls so the anchor stays put. Changes above the viewport are compensated. Content filling in below the viewport is ignored. A section you toggle yourself pushes content down naturally.
One bug shows how subtle this is. Corrections were skipped if the user had "just scrolled," but scrolls the app made itself also counted. Toggling the file-tree sidebar changed the diff pane's width, wrapped lines reflowed, and the app issued its own small scroll. The guard read that as user input, skipped the correction, and the file drifted off screen. Gimeno's lesson: any "is the user interacting?" check must be one your own side effects can't satisfy.
The pipeline
Three habits on the data side mattered. The file tree and metadata stream first and paint while the diff loads, and all review threads are fetched up front. Syntax highlighting runs off the 6 (the thread that also handles input and drawing), so rows appear as plain text and get coloured later. Big Markdown bodies are built only as they approach the viewport. Diffs are released when you navigate away to save memory. But a header that repainted instantly around an empty diff looked broken, so the last few diffs are now cached.
Finding bugs mechanically
Bugs like "whitespace under some comments, only sometimes, on big pull requests" can't be debugged by eye. The surface carries permanent probes that check its own rules: how many rows and blocks are mounted, whether measurement makes one commit per frame and how long that frame takes, how big scroll corrections are, whether any block was inserted after scrolling began (must be zero), and whether observers are cleaned up. An end-to-end test asserts these as budgets against a synthetic huge pull request, so 7 (continuous integration, the automated test run on every change) can tell whether the surface is healthy.
Two automated lanes ran on top. A headless probe ran JSON-described flows against a mock server and ranked bottlenecks, so an AI agent could profile a flow described in plain English. An autopilot drove the real desktop app through cold and warm passes: toggling sections, opening replies, resizing, sweeping deep into the file list. It logged a health signal (no gaps, no blank blocks, real content mounted) to disk for an agent to read.
The post gives no frame-time or load-time numbers, only the claim that the extreme pull request now behaves like a normal one. It also doesn't say how the design performs on lower-end machines.
Remember
Splitting fixed-height content from variable-height content into separate geometry indexes keeps the cheap, exact path intact.
Observers that write sizes back into the layout they watch can loop; flag changes and measure in one batch instead.
Checks like "is the user scrolling?" must ignore scrolls your own code triggers, or corrections silently get skipped.
Real databases have thousands of tables, columns with cryptic names, and business rules nobody wrote down, like which column defines an 'active customer'. A model that is excellent at SQL still has to discover these local conventions, and that discovery costs time and tokens.
Image: Murat Demirbas (Metadata)
A new position paper argues that much data-agent research is about to be made obsolete by better models. A data agent is an AI system that answers questions by querying a company's databases. Distributed-systems researcher Murat Demirbas reviewed the paper. Its frame is Rich Sutton's "1": general methods that scale with computation eventually beat hand-built expertise.
The test
The authors compared two kinds of agent:
A plain coding agent: OpenAI's 2 harness, with no task-specific tuning.
The best purpose-built data agents, designed by humans.
They ran on two benchmarks of database questions, 3 and DAB. Both sides used the same model, so only the 4 changed. Scaffolding means the prompts, tools and pipelines wrapped around a large language model (LLM).
With OpenAI's older o3 model, the specialized text-to-SQL system 5 won on both accuracy and token efficiency. Text-to-SQL means turning English questions into database queries. With GPT-5.6 Sol the result reversed and the plain coding agent won on both. Turns per query fell from 23.2 to 6.0.
What's left
The new bottleneck is knowing the data, not reasoning about it:
Schema exploration grew from 16% to 25% of the turns. This is the agent looking around the tables to learn what exists.
Semantic errors caused over 60% of the newer model's remaining failures. The model didn't know the company's business definitions, the correct 6 (the columns that link tables), or tables nobody had documented.
The authors had the agent explore 12 datasets and 12 sample queries, then write a context document that was fed into later prompts. Accuracy rose by up to 19 percentage points. Even at this small scale, building it cost real time and money: one context took nearly an hour and $9.60, another $12.16. Demirbas expects enterprise-scale costs to be far higher.
The proposal and the critique
The paper calls for a persistent semantic context layer: knowledge about the data, built offline, stored in the database and served to agents. It sketches two forms. One is a dependency graph of business rules. The other is a continuously updated "7" that AI rewrites when the data changes.
Demirbas calls the agenda superficial: it lists topics like "consistency models" without solutions. He also asks why databases should build this layer at all, since the paper shows agents can write their own context.
He also rejects the authors' reversal of their own earlier claim that agents would flood databases with queries. His argument is 8: when queries get cheaper, people run many more of them.
His own suggestion is 9, a formal specification language. Business rules would become checkable invariants, rules that must always hold. That would let an agent catch an impossible filter, such as a delivery date before an order date, before running the query.
A new position paper on data agents argues that research has been aimed at the wrong target. A data agent is an AI system that answers questions by querying a company's databases. Distributed-systems researcher Murat Demirbas reviewed the paper on his blog. Its authors include Ion Stoica and Matei Zaharia, and its frame is Rich Sutton's "1": general methods that scale with computation end up beating hand-engineered expertise. The paper's claim is that as large language models (LLMs) improve, they will absorb the agent 2 researchers have spent years building. Its proposed replacement is a stored, curated description of the data environment, which the authors call persistent semantic context.
The experiment
The authors set two kinds of agent against each other.
A general coding agent: the 3 harness, OpenAI's software-engineering agent, used with no task-specific engineering.
State-of-the-art data agents designed by humans for these tasks.
The tests were two benchmarks of natural-language questions over databases, 4 and DAB. Both sides ran on the same underlying models, so the scaffolding was the only thing that changed.
5 is a purpose-built text-to-SQL system, meaning it turns English questions into database queries. With OpenAI's older o3 model it won on both accuracy and token efficiency. Tokens are the units of text a model reads and writes, and they drive cost. With GPT-5.6 Sol that result reversed: the plain coding agent beat it on both measures.
The number of back-and-forth turns needed to answer a query fell from 23.2 with o3 to 6.0 with GPT-5.6 Sol. The newer model got the analysis right quickly and skipped most of the trial and error.
A reversal of the authors' own earlier claim
Demirbas points out that the authors use these efficiency numbers against their own paper from a year earlier, "Supporting Our AI Overlords." That paper warned that databases would be swamped by "agentic speculation": bursts of exploratory queries from confused models. The new paper says efficient agents "directly challenge the premise" of that work.
Demirbas disagrees and thinks the earlier direction still holds, for two reasons:
6. When something gets cheaper, people tend to use more of it. Cheaper queries mean more agents running longer tasks, in parallel and in the background, so the database does more total work.
Varied workloads. The Overlords paper's main point was that agent queries vary a lot, while databases are tuned for repetitive workloads. Fewer turns per query doesn't make queries more alike, so load still arrives in bursts.
What still goes wrong
The efficiency gains reveal a new bottleneck. Schema exploration means looking around the tables to learn what exists and how it connects. It shrank in absolute terms, but its share of turns rose from 16% with o3 to 25% with GPT-5.6 Sol, making it the largest remaining slice.
The failure analysis points the same way. Once coding and execution errors were mostly gone, over 60% of GPT-5.6 Sol's remaining failures were semantic. The model didn't know the organization's own business definitions, the right 7 (the columns that link one table to another), or schemas nobody had documented. The model is smarter but still doesn't know your data.
A small test of the fix
The authors let the agent "self-curate" a context document. It explored the databases and 12 sample queries, and the resulting text was placed in the agent's initial prompt. Accuracy rose by up to 19 percentage points.
Building that context was expensive, though, even at this tiny scale of 12 queries and 12 datasets:
The schema-focused context took about 3,400 seconds (nearly an hour) and cost $9.60.
A version built with 8 cost $12.16. GEPA is an automated prompt-optimization method; the article doesn't describe it.
Demirbas notes that scaling this up to an enterprise with terabytes of data and thousands of tables would push the overhead much higher.
The proposed agenda, and its weak spot
The authors propose a persistent semantic context layer. It would be built offline, stored by the database system, and served to agents so they stop rediscovering the same facts. The paper splits the work into two parts: keeping that context semantically consistent as data changes, and designing efficient physical data structures to hold it.
Demirbas calls this section the paper's weakest. Even allowing for a position paper, he says, it lists categories like "consistency scope" and "consistency models" without offering technical solutions or analysis. He also raises a deeper objection. The paper's own experiment shows agents can write their own context. If the Bitter Lesson holds, better models may also work out their own memory formats, consistency rules and on-disk layouts, which is everything Section 3 assigns to the database community.
The paper does sketch two concrete designs:
A dependency graph, with business definitions and schema rules stored as linked, traceable nodes.
A live 9. A materialized view is a stored query result that the database keeps up to date. Here, database change events would trigger targeted AI rewrites of the context whenever the underlying data shifts.
Either way, AI memory would stop being a static text file and become metadata the database manages.
Demirbas's proposal: 10
Demirbas thinks the problem is real, and that it gets worse with organization size. He sees the same pattern in software engineering: hundreds of engineers point models at a large codebase, and every session pays again to rediscover conventions and ownership boundaries the organization already knows.
His suggestion is TLA+, Leslie Lamport's formal specification language. It is best known for checking event orderings in distributed systems, but at its core it is set theory plus temporal logic. Temporal logic is a way of stating what must hold over time, not just at one moment. That lets TLA+ express schema properties, relations between data facts, and dependencies.
He cites Boris Cherny using Anthropic's Opus 5.5 to find race conditions with TLA+ in a few prompts, as evidence that models no longer need an expert operator to use the language.
In his design, an agent would translate natural-language business rules into TLA+ relations. If a metric is redefined, the model shows which downstream definitions break. Agents could also check a planned query against the invariants before running it. An invariant is a rule that must always hold. For example, a query that looks for records where the delivery timestamp comes before the order timestamp violates a temporal invariant, and the agent could fix its filter before ever touching the database. This is Demirbas's idea, not the paper's.
Open questions
The paper leaves the hard parts open: how to keep context consistent, how to make building it cheap at enterprise scale, and whether the database community needs to build it at all. Demirbas ends with a caveat on the Bitter Lesson itself. He argues it applies best where statistical approximation is acceptable. Where you need absolute correctness and performance, he thinks human-engineered algorithms and abstractions can still hold.
Remember
With the same newer model, a plain coding agent beat a specialized text-to-SQL system on accuracy and cost.
Over 60% of the remaining failures came from not knowing company-specific data meanings, not from coding mistakes.
A self-written context document raised accuracy up to 19 points, but building it took close to an hour, even for 12 datasets.
PlanetScale, a company that hosts managed databases, now asks customers creating a Postgres or 1 cluster (Neki is its sharded database product) to pick a processor architecture: ARM (aarch64) or x86-64. A guide by Ahmed Darwich explains why this choice matters and why it's hard to reverse.
A 2 isn't a fixed unit
Clouds sell compute in vCPUs, or virtual CPUs. On x86 instances, a vCPU is usually one 3. Hyperthreading lets one physical core run two instruction streams, switching to the other when one stalls waiting on memory. Darwich's analogy is two cooks sharing one kitchen: more food comes out, but they share the oven and sink. ARM server chips like AWS 4 and Google Axion don't hyperthread, so each vCPU is a whole core.
Which workloads favor which
Whole cores help when many small queries arrive at once, as in an online store handling hundreds of carts and stock checks. They also leave room for background work like 5, Postgres's cleanup process. For one long, CPU-bound query that runs on a single core, such as a dashboard totaling millions of rows, x86's higher clock speed usually wins.
Vector width also matters. 6 instructions process several values per step. x86's 7 works on 256 bits at a time, and AVX-512 on 512. Graviton4 and Graviton5 use 128-bit vectors. 8, PlanetScale's full-text search index, intersects 256-bit page bitmaps, which takes a single AVX2 instruction on x86. 9, a vector-similarity extension, has AVX-512 code for some distance calculations and falls back to slower generic code on ARM.
Why you can't switch later
Postgres replicas start as a byte-for-byte copy of the primary's files and then replay the 10, the record of every change. That only works if both machines read the bytes identically, and across architectures they may not. In C, the language Postgres is written in, a plain char is signed on x86-64 Linux and unsigned on ARM64 Linux. So byte 0xFF reads as −1 on one and 255 on the other. 11, a text-matching extension, sorted its index entries using such comparisons, so a copied index could appear misordered on the other architecture. Postgres 18 fixed that case, but the general risk remains. Switching architectures therefore means migrating to a new cluster with , which copies rows rather than files, so the new machine builds its own indexes.
The advice
Darwich recommends ARM as the default for ordinary workloads, citing price-performance, and says it is usually slightly cheaper on PlanetScale. Consider x86 when a few heavy queries dominate. The article gives no benchmark numbers. Instead, it advises teams to test both architectures with the same data and settings at peak concurrency before committing.
PlanetScale, a company that hosts managed databases, has published a guide for customers creating a Postgres or 1 cluster. Neki is PlanetScale's sharded database product, which splits data across many servers. At creation time, customers must choose one of two processor architectures: aarch64 (ARM) or x86-64. The guide, by Ahmed Darwich, makes two points. Two clusters with identical 2 and memory figures can perform quite differently. And the choice is hard to undo later.
Two lineages
x86 started at Intel in 1978. It became the standard for personal computers after IBM used it in the original PC, and its design has always favored backward compatibility and raw speed. ARM came from Acorn, a British computer company. Acorn wanted to put its chip in a cheap plastic package, so it set a power budget of one watt to keep the chip from overheating. When the first chip was powered up in April 1985, the power meter read zero. A fault on the test board meant the chip was running on current leaking in from nearby circuits. Properly connected, it drew about a tenth of a watt. Designer Sophie Wilson later called that efficiency an accident. The efficiency made ARM the standard chip for phones. More recently, datacenters chasing lower power and cooling bills adopted it too. AWS now designs its own ARM server chip, 3, and Google designs Axion.
What a vCPU actually is
The first difference is what the cloud provider counts as a vCPU. A CPU core has several execution units, but a single thread of instructions rarely keeps them all busy. It often stalls while waiting for data from memory. Hyperthreading, also called simultaneous multithreading, keeps two threads loaded on one core. When one stalls, the core runs instructions from the other. Darwich's analogy is two cooks sharing one kitchen: together they produce more food, but they share the oven and the sink. On x86 instances, each of those threads is sold as a vCPU. Graviton and Axion don't use hyperthreading, so on ARM each vCPU is a whole core with its own oven and sink.
Concurrency versus one heavy query
This matters most for concurrent work. Picture an online store with hundreds of customers at once: product lookups, stock checks, cart updates. Each query is small, and Postgres can spread them across cores. Whole cores also leave room for background work alongside application queries, such as parallel query workers and 4, Postgres's process that cleans up dead row versions.
A reporting dashboard is different. Suppose one query spends several seconds totaling millions of sales rows. If that query is CPU-bound and doesn't use parallel workers, it runs on a single core, and extra cores don't help. Single-core speed matters here, and x86 server chips usually run at higher clock speeds.
Vector width
Some instructions process several values at once. These are 5 instructions (single instruction, multiple data), and they work on wide "vector" registers. When comparing 32-bit numbers, one instruction can handle 4 pairs with a 128-bit register, 8 with a 256-bit register, or 16 with a 512-bit register. On x86, 6 provides 256-bit vectors, and some chips also support AVX-512. AWS's Graviton4 and Graviton5 use 128-bit vectors.
This affects real Postgres features. 7, PlanetScale's full-text search index for Postgres, keeps a 256-bit bitmap for each search term. Each bit records whether a given database page contains that term. Take this query:
CREATE INDEX articles_body_tin ON articles USING tin (body);
SELECT * FROM articles WHERE body ==> 'postgres AND replication';
TIN finds candidate pages by ANDing the bitmaps for "postgres" and "replication." On x86, one AVX2 instruction covers all 256 bits. With 128-bit registers, that takes at least two operations. (The article states only the x86 case. The ARM count follows from the widths.) 8, the popular Postgres extension for vector similarity search, has AVX-512 code paths for Hamming and Jaccard distances. These measure how two bit vectors differ or overlap. On ARM, pgvector falls back to general-purpose code, so some index types run better on x86.
Why you can't switch later
The usual way to move Postgres to new hardware is to build a replica there and promote it to primary. A replica starts as a byte-for-byte copy of the primary's files, including tables and indexes. It then replays the 9 (WAL), the running record of every change. The flaw is that those files are only meaningful if both machines read the bytes the same way.
The article's example is 10, an extension that speeds up fuzzy text matching by indexing trigrams, which are three-character chunks of text. Postgres is written in C, where the compiler decides whether a plain char is signed or unsigned. GCC and Clang, the two common C compilers, make char signed on x86-64 Linux and unsigned on ARM64 Linux. So the byte 0xFF means −1 on one and 255 on the other. pg_trgm sorts trigrams using char comparisons. If you copy its index to the other architecture, the new machine may disagree with the stored ordering, and lookups can return wrong results. Postgres 18 fixed this case. Darwich uses it to show the general risk: copying bytes doesn't guarantee both machines agree on what they mean.
For that reason, PlanetScale keeps a primary and its replicas on the same architecture. In Neki, the architecture is fixed in the configuration profile the shards use. Resizing and adding replicas work as normal. Changing architecture requires a new cluster. You create the schema there, then use 11, which streams row-level changes instead of raw file bytes, to copy the data and keep up with new writes. The destination builds its own indexes, so their ordering follows its own comparison rules.
The recommendation
For new applications doing ordinary reads and writes, Darwich recommends ARM by default. He cites good price-performance and parallelism. ARM sizes on PlanetScale usually cost a bit less than x86 sizes with the same vCPUs and memory, though this varies by size and region. x86 deserves a look when a few CPU-heavy queries dominate the workload, or when you rely on SIMD-optimized paths like TIN or pgvector's bit distances.
The article publishes no benchmarks. It gives no throughput or latency figures and no price gaps. Instead, it tells performance-sensitive teams to run their own comparison. Load the same data and settings onto an ARM cluster and an x86 cluster, test at expected peak concurrency, and compare throughput, slow-query latency and cost. Given what a migration costs, that test is worth running before you commit.
Remember
On x86 clouds a vCPU is usually half a core. On Graviton and Axion it is a whole core.
The signedness of a plain C char differs between x86-64 and ARM64, so on-disk index bytes can mean different things on each.
The article includes no benchmarks. Test both architectures at peak concurrency yourself before committing.