Improving Transaction Confirmation Latency
Drafted September 2024. Finished and published August 2026 as part of the migration away from WordPress.
A swap could be visible on Base within a couple of seconds while the frontend continued spinning for another ten. The transaction was not slow. The application was slow to learn that it had confirmed.
Where the time went
The frontend submitted the transaction through the user’s wallet and waited for that provider to deliver the receipt. That tied the interface to infrastructure outside the team’s control.
In testing, the frontend took roughly 5 to 15 seconds to mark a swap as complete. The backend was already seeing the protocol’s events in about two seconds. Changing the contracts would not help because the delay came after execution.
Racing two confirmation paths
The backend already subscribed to events emitted by the protocol contracts over a WebSocket connection. I added a transaction-status endpoint that looked up those indexed events by transaction hash.
Once the wallet returned a hash, the frontend started polling the endpoint once a second for up to ten attempts. The wallet receipt listener stayed active, and the two signals were raced. Whichever confirmed first updated the interface.
The backend event index became the fast path. The original wallet receipt remained as a fallback.
The ten-attempt limit bounded calls to the backend. It did not turn a missing event into a failed transaction. If the backend could not confirm within that window, the wallet receipt path continued as before.
This brought the interface much closer to the backend’s roughly two-second observation time without changing how transactions were signed or submitted.
Why the paths ran at different speeds
Both paths were observing the same chain. The difference was how updates reached them.
| Path | How it observed Base | Time seen in testing |
|---|---|---|
| Wallet receipt | Web3 waited for a receipt through the provider exposed by the user’s wallet | Roughly 5 to 15 seconds |
| Backend event index | A long-lived WebSocket connection received protocol events from an RPC the team controlled | About two seconds |
That points to the provider or its receipt-polling path rather than Base itself. It does not establish whether the delay came from provider capacity, polling intervals, or another part of the wallet integration.
The event-index route was not a general transaction-confirmation API. It could only see transactions that emitted events the indexer watched, which is why the wallet receipt remained as the fallback.
The application stopped relying on a single slow observation path. The transaction still confirmed at the same time; the interface simply learned about it sooner.