Skip to main content

Solana switched consensus protocols at 13:54 UTC on Wednesday 21 October 2026. The coverage has the shape of the story right: Alpenglow replaces Proof-of-History and TowerBFT with a protocol whose votes travel validator-to-validator instead of being written into blocks, and the network now targets finality in roughly 150 milliseconds instead of several seconds. CoinDesk even flagged the accounting consequence, which is more than most upgrade coverage manages: dashboards will show transaction totals falling off a cliff, and anyone comparing this week to last week has to count user transactions separately from the votes that used to fill the blocks.

That warning is correct and it is also where everyone stopped. The press told you the count would fall. Nobody asked the next question, which is the only one that matters to anybody trying to get a transaction into a block: if validator votes were most of the transactions in every Solana block, how much of the block were they actually using?

I measured it. Across 36,447 vote transactions on both sides of the switch, the answer is 2,100 compute units each, every single time, which works out at 2.34% of the block’s compute budget. Votes were 59% of the transactions and a rounding error of the work. The number that collapsed on Wednesday was never the number that decides whether your transaction lands.

TL;DR

  • Alpenglow’s handoff is visible on-chain as a gap: the last TowerBFT block was slot 459652999, the first Alpenglow block was slot 459653008, and the eight slots between them produced no blocks at all.
  • The headline claim checks out. In 12 of 12 batched probes the confirmed and finalized commitments returned the identical slot, with finalized trailing the chain tip by exactly one slot (about 212ms), against the 12.8 seconds Solana’s own proposal document attributes to TowerBFT.
  • Validator votes were 59.1% of transactions in a 40-block sample taken 24 hours before the switch, and 64.4% in the 15 blocks immediately preceding it. Both samples are now zero.
  • Every one of the 36,447 votes I measured consumed exactly 2,100 compute units. That made votes 6.13% of the compute actually used and 2.34% of the 60,000,000-unit block limit, which I verified on-chain from the feature account that activated it.
  • Those blocks were running at 38.2% of the limit. Removing the votes freed 2.34% of a budget that was already 62% idle, so the capacity story is arithmetically empty. Inclusion is decided by write-lock contention and the priority fee market, and the measured fee per block did not fall.

The switch, as the chain recorded it

Start with the thing that is not in any of the coverage, because it takes one free RPC call. Ask a Solana node which slots in the neighbourhood of the handoff actually produced blocks:

getBlocks(459652990, 459653020) returns 459652990 through 459652999, and then jumps straight to 459653008. Slots 459653000 to 459653007 are absent, and asking for any of them individually returns error -32009, “slot was skipped, or missing in long-term storage”. Eight consecutive slots produced nothing.

That gap is the handoff. Block 459652999 carries 649 vote transactions, which is what a TowerBFT block looks like. Block 459653008 carries 1,701 transactions and not one vote, which is what every Solana block looks like now. The chain’s own timestamps put the former at 13:54:00 UTC and the latter at 13:54:03 UTC.

The Solana Foundation told CoinDesk the handover took about 900 milliseconds, with 446 of 654 participating validators certifying the block used as the starting point. Both things can be true: a certificate exchange completing in 900ms is not the same measurement as a leader schedule producing no blocks for eight slots. The honest version is that the certificate round was fast and the block production gap was longer, and the latter is the part you can check yourself for free.

One probe that failed is worth reporting, because the failure is informative. The Alpenglow migration proposal publishes a feature key, a1penGLz8Vm2QHYB3JPefBiU4BY3Z6JkW2k3Scw5GWP, and Solana’s feature accounts normally record their own activation slot. That account does not exist on mainnet. Before concluding anything from an absence, I ran a control: the feature accounts for the 50M and 60M block-limit changes are both present, both owned by Feature111111111111111111111111111111111111, both flagged activated, at slots 332640000 and 355104000 respectively. So the method works and the account genuinely is not there under that key. You cannot date Alpenglow from the feature registry the way you can date the block limits. The eight missing slots are the on-chain evidence.

The headline is true. I checked it.

It would be cheap to write a contrarian post without first confirming the claim it is contrarian about, so here is the confirmation.

Solana’s RPC exposes three commitment levels, and the gap between them is the whole of what “finality” means operationally. Asking for them in three separate calls is a trap, because the chain advances between calls and you measure your own latency. Batched into a single JSON-RPC request and repeated twelve times:

Commitment Result
processed minus confirmed +1 slot in 11 of 12 samples, 0 in the twelfth
confirmed versus finalized identical slot in 12 of 12 samples
finalized minus processed -1 slot, median across 12 samples

Confirmed and finalized are now the same number. Finalized sits one slot behind the tip of the chain, and at the slot rate I measured over the same period, 107,127 slots in 22,740 seconds or 212.3ms per slot, one slot of lag is about 212 milliseconds. Alpenglow’s own proposal document says TowerBFT “has a consensus finality time of 12.8 seconds”. A second, independent view agrees: of 668 current validators, 529 report a root slot identical to their last voted slot, which under TowerBFT’s lockout rules essentially never happened.

So the 150ms figure is real, with the caveat Anza itself gave: it is a target under normal conditions, and a machine that is not one of the validators voting directly will learn about finality later than the validators do. Fine. The claim survives contact with the data, which is rarer than it should be.

The number that collapsed

Now the part that got reported as a dashboard inconvenience.

I sampled 40 consecutive blocks from 08:28 UTC on 21 October, before the switch, and 40 from 08:39 UTC on 22 October, after it, deliberately matched for time of day. I also took the 15 blocks immediately before the boundary and the 15 immediately after, to catch the switch itself.

Before (40 blocks, 21 Oct) After (40 blocks, 22 Oct)
Transactions 45,210 14,536
Vote transactions 26,733 (59.1%) 0
Non-vote transactions 18,477 14,536
Mean transactions per block 1,130 363

The mean block went from 1,130 transactions to 363, a fall of 68%, and nothing a user does changed. In the 15 blocks immediately before the boundary the vote share was higher still, 64.4%, which is the kind of variance you get from a four-second window.

The vote count has a satisfying property: in the pre-switch sample it averages 668 votes per block, and getVoteAccounts currently returns exactly 668 current validators. One vote per validator per slot, which at the measured slot rate of 407,026 slots per day is roughly 272 million vote transactions a day that no longer exist.

They were not free. Each vote paid about 5,040 lamports, so the pre-switch sample runs at 0.003367 SOL per block in vote fees, or about 1,370 SOL a day across the network. That flow is gone, replaced by a validator admission ticket of 1.6 SOL per epoch charged to every eligible validator and burned outright, which at 668 validators is roughly 1,069 SOL an epoch. Whether the swap is a rise or a cut depends on how long an epoch now lasts, and 432,000 slots at 212.3ms is 25.5 hours rather than the 48 the ticket was sized against. An earlier post here covered that drift; the point is only that the ticket inherited its number from a world with a slower slot.

The capacity nobody freed

Here is the measurement the upgrade coverage needed and did not take.

A Solana block is not limited by how many transactions it contains. It is limited by compute units, and the limit is 60,000,000, which is not a figure I am taking on trust: the proposal that raised it to 60M is still marked “Review” in the public proposal repository, while its feature account on mainnet says activated at slot 355104000. The chain is ahead of its own paperwork, which is worth knowing on its own.

So: how many compute units did a vote consume? Across 26,733 votes in the pre-switch sample and 9,714 in the pre-boundary sample, the histogram of compute units consumed has exactly one entry.

Measurement Value
Vote transactions measured 36,447
Distinct compute-unit values observed 1
Compute units per vote 2,100, without exception
Vote compute per block 1,403,482
Vote share of compute actually used 6.13%
Vote share of the 60,000,000 limit 2.34%

Votes were 59.1% of the transactions in a block and 2.34% of the block’s compute budget. Those two sentences describe the same objects and they are the reason the capacity story does not survive.

And it gets worse for the capacity reading, because the limit was not close to binding. The same 40 pre-switch blocks averaged 22,899,717 compute units, which is 38.2% of the limit, with the single busiest block in the sample reaching 45,699,320, or 76%. Mean idle headroom was therefore around 37,000,000 compute units per block, roughly twenty-six times the entire vote load. Deleting the votes handed back 2.34% of a budget that was already 62% unused. You cannot free capacity that nobody was competing for.

The post-switch sample makes the same point from the other direction. It averages 14,406,392 compute units per block, 24.0% of the limit, and 363 non-vote transactions against 462 the day before. Non-vote activity is down about 21% day over day. That is ordinary variance in what users were doing on a Thursday morning, and I am reporting it precisely because it is the opposite of what a freed-capacity story would predict. Nothing rushed in to fill the space, because the space was always there.

What actually decides whether your transaction lands

If the block’s compute budget was two-thirds idle, why does anyone ever fail to get included?

Because the binding constraint on Solana was never the block total. It is contention for write access to specific accounts, and the priority fee auction that resolves it. A block with 37 million spare compute units will still refuse your transaction if the one account you need to write to is being fought over by everyone else in the same slot, and the way you win that fight is by paying.

That market did not relax. Non-vote fees in the pre-switch sample averaged 0.010474 SOL per block. In the post-switch sample they averaged 0.012919 SOL per block, slightly higher, on 21% fewer user transactions. Removing 272 million daily transactions from the ledger moved the price of inclusion in the wrong direction for anyone hoping for relief, which is exactly what you would expect once you know the votes were never bidding in that auction in the first place. They were a fixed 2,100-unit tax paid by validators, not a competitor for your slot in the block.

This is the shape of the error, and it is not specific to Solana. A count was published, the count was large, the count fell, and everyone reasoned about capacity from the count. The unit of capacity was a different unit the whole time.

Four posts this is not

This blog has written about adjacent things and the distinctions are load-bearing, so let me draw them rather than let a reader assume.

It is not Solana’s Epoch Just Lost Six Hours, which argued that a shorter slot is not a capacity upgrade because each slot’s allowance shrinks in rough proportion to the window. That is a claim about the budget scaling with the clock. This is a claim about a transaction count never having been the budget at all, and about a limit that was 62% idle.

It is not 2 Seconds to Confirmed, 19 Minutes to Final, which measured the distance between Base’s three block heads and argued that a draw has three different answers to “when is this irreversible”. Here that distance has collapsed to zero on one chain, and the post is about a different quantity entirely: not when the block is safe, but how full it was.

It is not Solana’s First Vote Was Verifiable. That Is Not the Same as Representative, which was about a governance ballot. The votes in this post are consensus votes, cast every slot by machines, and the fact that both are called votes is an accident of vocabulary.

And it is the mirror image of the Ethereum exit-queue measurement from earlier this month, where the per-epoch limit was pinned at 100% of capacity for 768 consecutive epochs. There the limit was the whole story because it genuinely bound. Here the limit is the whole story because it did not.

What this does to a draw

Translate all of that into the only question a player actually has, which is whether the game was fair.

A draw has exactly two timing requirements and a throughput headline answers neither of them. The first is inclusion: was my entry recorded before the raffle closed? That is decided by whether a block accepted my transaction in a particular window, which as measured above is a question about write-lock contention and fee priority, not about how many transactions the chain can report per second. A chain advertising a large number has told you nothing about whether your specific entry made the cut, and a chain whose advertised number just fell by 68% has not become worse at including you.

The second is irreversibility: once the winner is picked, can the result be unwound? That is a finality question, and on this one Alpenglow is a genuine and measurable improvement. A chain where confirmed and finalized are the same slot is a better place to settle a prize than a chain where they are 19 minutes apart, because the window in which “you won” can become “actually you didn’t” has closed.

So the fair summary of Wednesday is: the thing that got better for gaming is the thing the coverage buried in paragraph four, and the thing that got dramatically smaller was never load-bearing. If you were choosing a chain for a prize draw on the strength of transaction counts, you were choosing on a number that could fall by two-thirds overnight without any underlying change in what the chain does for you.

Which is the general lesson, and it is the reason this blog keeps measuring things instead of reading announcements. “Provably fair” is a claim about a specific chain of custody between your entry and your payout. Every number that is not part of that chain is marketing, including the flattering ones.

Where Satoshie stands

Satoshie runs provably fair raffles and coinflips on Base, with winners drawn by Chainlink VRF, and we publish the numbers that bind a draw rather than the numbers that make a chain look fast.

Concretely, that means the entry deadline for a raffle is a block number and not a wall-clock time, because a block number is what a chain can actually honour. It means the randomness that picks the winner is requested on-chain and delivered on-chain with a verifiable proof, so the draw does not depend on anyone’s throughput claim. And it means the figures we quote about our own games are measurements of our own contracts, not of the chain underneath them. A chain’s transaction count is not a guarantee of anything we owe you.

We have published our own unflattering measurements for the same reason: draws delivered and charged but refused, callbacks that cleared their gas limit by 115 units, subscriptions that cannot be closed. A number you can only read in the upward direction is not a number.

Honest limits

Six things could be wrong with the above, and you should know them before you quote any of it.

The samples are small. Forty blocks on each side is about nine seconds of chain each, plus two 15-block windows at the boundary. The vote share figures are robust because they are structural, one vote per validator per slot, but the compute and fee averages carry real sampling error and I would not defend a second decimal place.

The before and after are 24 hours apart. I matched time of day deliberately, but user activity on a Wednesday morning is not user activity on a Thursday morning. Every day-over-day difference in non-vote transactions, compute used and fees paid is confounded with ordinary demand variation, which is why I have leaned on the within-sample ratios instead.

Block timestamps are estimates. Solana’s blockTime has one-second granularity and is not a measurement of wall clock. The 13:54:00 and 13:54:03 figures are good enough to date the handoff and not good enough to time it, which is precisely why I did not try to adjudicate the 900 millisecond claim with them.

The 60,000,000 limit is inferred, not read. I verified that the feature raising the limit to 60M is activated on mainnet, and I verified the method with a control on the 50M feature. I did not read a live cost-tracker value, and account-level compute limits exist alongside the block limit, so “2.34% of the budget” is 2.34% of the block-wide budget specifically.

The missing feature account is unexplained. The key I probed is the one published in the migration proposal, the controls prove the probe works, and the account is not there. I am not going to guess whether the final activation used a different key or whether the account was reclaimed. I am reporting what returned null.

None of this says Alpenglow is bad. It is plainly a large improvement on the axis that matters for settlement, and I confirmed that myself above. The argument is narrower and duller: the most dramatic-looking consequence of it, a two-thirds fall in transactions, means almost nothing, and treating it as a capacity event is a category error.

Three questions worth asking

Of any chain quoting a transaction count: what fraction of it is the chain talking to itself? Before Wednesday, Solana’s honest answer was about 59%. Other chains have their own internal traffic and most of them do not separate it in the headline figure.

Of any upgrade described as freeing capacity: what percentage of the actual limit was in use beforehand? If the answer is under half, the capacity argument is over before it starts, and whoever is making it either has not checked or is hoping you will not.

Of any game you are about to play: which published number, if it changed by two-thirds tomorrow, would change what you are owed? If the answer is none of them, the numbers are decoration. If the answer is one of them, make sure it is written into the contract and not into the marketing.

The closer

Solana did something genuinely hard on Wednesday afternoon and it worked. Eight slots went by without a block, the protocol underneath changed, and the chain came back with finality an order of magnitude tighter than it had at lunchtime. That deserves the credit it is getting.

What it does not deserve is the capacity narrative that is going to grow around the falling transaction counts over the next fortnight, because those 272 million daily transactions were 2,100 compute units each in a block that was running at 38% of its limit. They were never in your way. The chain has been quietly carrying a very large number that nobody needed, and the interesting thing about Wednesday is not that the number went away. It is how many people were using it to reason about something it never measured.

Measure the thing that binds. Everything else is a chart.

All on-chain figures in this post were measured on 21 and 22 October 2026 against the public Solana mainnet RPC endpoint, and can be reproduced with getBlocks, getBlock, getVoteAccounts, getMultipleAccounts and getSlot. Protocol details are quoted from the Solana improvement proposals for Alpenglow, the Alpenglow migration and the validator admission ticket.

📷 Photo by Claudio Schwarz on Unsplash

Valentina Ní Críonna

Author Valentina Ní Críonna

More posts by Valentina Ní Críonna