Why
Reading the chain directly does not scale past one widget — real screens need joins, history and aggregates, so they read a projection built by an indexer. That is CQRS by necessity, and it imports CQRS's one cost: the read model lags the write model. The user who just paid sees an old balance; the list is missing the newest row.
The failure mode is not the lag — it is hiding it. A screen that says balance as of block 19,342,001, with your payment pending on top, is telling the truth and feels fine. A screen that silently shows stale data feels broken exactly when the user cares most, seconds after they acted. The staleness is unavoidable; the dishonesty is a choice.
How it works
Two data paths for one screen, lag you control, and the two UI elements that repair trust.
PoC
An anvil chain with a token, a tiny indexer (Ponder or a hand-rolled event loop) writing balances to SQLite, and one balance page with a data-source toggle. Add a configurable indexing delay. Make a transfer, watch the indexer-backed view lie for N seconds, then add (1) an as-of block label read from the projection's own cursor and (2) an optimistic pending row sourced from the app's submitted-transactions list. Assert the repaired view never contradicts what the user just did.
What it proves
The projection's lag cannot be engineered away, only labeled and bridged: the as-of label bounds what the screen claims, and the pending overlay covers the gap between the user's action and the indexer's cursor. Every serious dapp front end converges on these two elements — this PoC derives why in fifty lines.
Where it lands in Jayverse
- Rabbit: label every balance or wallet screen with the indexer's as-of block, plus a pending-transaction overlay. The portal's balance view is a projection, not a live read; showing which block it speaks for and overlaying the user's just-submitted transaction is what stops "silently wrong" after every send.
- Verex: apply the same as-of label to order-book and market-state reads. The CLOB UI reads an indexer or cache, not the chain directly, so a resolved market or a filled order needs the same cursor label and an optimistic row for the user's own just-placed order.
- gitboard: show the as-of block or timestamp on any aggregated number. TVL, volume or the recycling-multiple figures gitboard reports are themselves projections; the dashboard should carry the same honesty device this page derives, not just the headline number.
Key expressions
| Expression | 뜻 · 쓰이는 자리 |
|---|---|
| scale past | (그 이상으로) 확장되지 않다 · 방법이 규모가 커지면 한계에 부딪힐 때. "does not scale past one widget" |
| import (a cost) | (문제·비용을) 함께 들여오다 · 한 설계를 채택하면 그 단점도 같이 따라올 때. "imports CQRS's one cost" |
| lag (verb) | 뒤처지다, 시차를 두고 따라가다 · 읽기 모델이 쓰기 모델보다 늦을 때. "the read model lags the write model" |
| repair trust | 신뢰를 회복시키다 · UI 요소가 사용자 불신을 해소할 때. "the two UI elements that repair trust" |
| cover the gap | 간극을 메우다, 이어주다 · 대기 중 항목이 지연을 감춰줄 때. "the pending overlay covers the gap" |
| engineer away | (기술로) 없애버리다, 제거하다 · 근본적으로 해결 불가능한 지연을 말할 때. "cannot be engineered away" |
| derive (verb) | (논리적으로) 이끌어내다, 도출하다 · 짧은 코드로 원리를 증명할 때. "this PoC derives why in fifty lines" |
| CQRS | 명령과 조회 책임 분리(Command Query Responsibility Segregation) · 쓰기 모델과 읽기(프로젝션) 모델을 분리하는 아키텍처 패턴, 읽기 지연이 그 대가. "That is CQRS by necessity" |
| Ponder | 폰더 · 이더리움 이벤트를 색인하는 오픈소스 인덱서 프레임워크, PoC의 예시 도구. "a tiny indexer (Ponder or a hand-rolled event loop)" |