The Trie Is Not the Blockchain
You're holding a block header. Thirty-two bytes of state root, one peer willing to talk, and a question: does this address hold a nonzero balance? Your light client doesn't have the full Ethereum state. What it has is a traversal problem, and the depth of that traversal is what determines how expensive the answer is going to be.
That depth is not fixed. It grows logarithmically as Ethereum accumulates accounts. Understanding this is the difference between knowing that light clients are "efficient" and knowing why they're efficient on a good day, and where exactly they start to strain.
A Merkle Patricia Trie Is a Tamper-Evident Filing Cabinet
Ethereum's global state, every account balance, every contract's storage, every nonce, lives in a data structure called a Merkle Patricia Trie. Patricia is the compression part: it collapses long chains of single-child nodes into one step. Merkle is the integrity part: every parent node contains a Keccak-256 hash of its children, so the root hash commits to everything below it.
Keccak-256 specifically matters here. It produces a 32-byte output, and each node in the trie contains one or more of those outputs as pointers to its children. The state root in an Ethereum block header is the Keccak-256 hash sitting at the very top of this structure. Change a single leaf value anywhere in the trie and every ancestor hash changes too, propagating upward to the root like pressure through a pipe.
This is what makes a Merkle proof work. To prove that account 0x4a3b... holds a particular balance, a prover hands you the leaf node plus every sibling node along the path from that leaf to the root. You hash your way up, step by step, and check that the final hash matches the state root you already trust. Match means valid.
Depth Is the Multiplier
In a hexadecimal Patricia trie (branching factor of 16, as Ethereum uses), a trie holding n leaves has a maximum depth of roughly log₁₆(n). With Ethereum's state approaching 200 million accounts, log₁₆(200,000,000) is about 6.5, meaning the trie runs 8 to 10 nodes deep in practice once you account for extension nodes and partial-key encoding.
Every node on the path from leaf to root must be included in the proof. Each node is a Keccak-256 hash (32 bytes) plus surrounding data. A single proof scales linearly with depth: at depth 8, you transmit and verify roughly 8 nodes; at depth 12, it's 12. Bandwidth and CPU cost per proof are O(depth), and depth is O(log n), so the whole thing is O(log n). That logarithmic scaling is the genuinely good news.
The less-discussed part: each verification step requires one Keccak-256 computation. Keccak-256 is not free on constrained hardware. A low-power IoT device from a few generations back can perform roughly 5,000 to 15,000 Keccak-256 operations per second. A proof with 10 nodes means 10 hashes. Run 50 proofs in quick succession and you're at 500 hash operations. That starts to matter for battery-powered clients.
A Worked Scenario: Two Wallets, One Verification, Different Bills
Consider two users. Priya runs a full Ethereum node on a desktop and exposes a light-client endpoint for her phone. Marcus runs only the light client on that phone, connecting to Priya's node.
Marcus wants to verify that a payment landed in his account. His light client requests a state proof. Priya's node traverses the trie from root to Marcus's account leaf, collecting sibling hashes at every branch. The path is 9 nodes deep. The proof she sends is about 9 × 532 bytes (a branch node in Ethereum's encoding is typically 532 bytes fully expanded), so roughly 4.8 KB over the wire.
Marcus's client receives those 9 nodes, recomputes 9 Keccak-256 hashes in sequence, checks the final hash against the trusted state root. Total CPU time: under a millisecond on any modern phone. Total bandwidth: under 5 KB.
Now the state grows by a factor of 16, a full additional trie depth level. Depth increases by 1. The proof grows to 10 nodes, roughly 5.3 KB. Cost increase: about 10%. Logarithmic scaling really does protect you.
What actually stresses light clients in practice is not a single proof. It's proof batching during sync. If Marcus's client needs to verify 200 state entries after being offline for a week, it's requesting 200 proofs. Shared nodes can be cached and reused, but in the worst case (random account addresses, uniformly distributed across the keyspace), nearly every proof traverses a distinct path. That's 200 × 9 hashes, 1,800 Keccak-256 operations, and up to 960 KB of proof data. Still manageable. But you can see the slope.
Why Address Hashing Locks In This Cost
Ethereum doesn't index the state trie by raw address. It indexes by keccak256(address). This is, in my view, one of the most consequential and underappreciated structural decisions in the protocol. Uniform key distribution prevents adversarial trie manipulation, where an attacker creates many accounts sharing long key prefixes to force deep paths for specific targets. The tradeoff is real and the Ethereum designers made the right call.
The cost: you cannot predict where in the trie any given account lives. Two accounts owned by the same person might sit in completely different branches, sharing no path nodes at all. This kills a natural optimization that a raw-address trie would allow, nearby addresses sharing proof prefixes, in exchange for guaranteed worst-case path length and resistance to depth-inflation attacks.
For light clients, proof caching is therefore less effective than it sounds. A mobile wallet verifying its own recent transactions touches accounts whose hashed keys are scattered across the trie. You can cache the top few levels (shared by many paths), but below depth 3 or 4 the paths diverge and caching stops helping.
Ask yourself: if the same property that makes the trie tamper-resistant is the property that makes proof compression harder, which one do you give up? The answer should be obvious, and it is.
What Verkle Tries Change (and What They Don't)
The Ethereum research community has been working on replacing the Keccak-256 Merkle Patricia Trie with a Verkle Trie, which uses polynomial commitments rather than hash-based Merkle proofs. The practical effect: a Verkle proof for multiple leaves in the same proof can be aggregated into a structure that grows sublinearly with the number of leaves queried.
For a light client verifying 200 accounts in one request, a Verkle proof could be dramatically smaller than 200 individual Merkle proofs. The depth problem doesn't vanish, but multi-leaf aggregation changes the bandwidth equation fundamentally.
Keccak-256 itself would still appear in the block hash and other contexts. As the trie's commitment scheme, though, it would be replaced. The per-proof cost would shift from "O(depth) hashes" to a single elliptic curve pairing check, which is heavier per operation but doesn't scale with depth or leaf count. Whether that's a net win depends on the hardware. A pairing check is expensive on constrained devices, potentially more so than 10 Keccak hashes. This is not a settled question, and anyone telling you Verkle is a clean upgrade for IoT light clients is getting ahead of the benchmarks.
The core principle survives the upgrade. Proof cost is still set by the commitment scheme's verification complexity and the structure of the trie. Verkle tries change the specific numbers. They don't change the fact that trie architecture is where light client economics are decided.
What You Should Actually Track
If you're building anything that touches Ethereum light clients, the number worth watching is not gas prices or block times. It's trie depth. As state size grows, depth creeps upward, and proof size grows with it. The logarithmic damping is real and reassuring. It is not infinite.
If you're seeing consistent depths under 10 with caching hit rates above 60% on the top trie levels, your proof costs are in a comfortable band. Push past depth 12 with no caching and high proof volumes, and you'll feel it in bandwidth budgets before you feel it in CPU.
The trie is the cost model. Everything else is downstream of it.