Waiting for Transaction Finality on Polygon PoS: A Two-Tier Confirmation Policy
Polygon PoS blocks arrive every ~2 seconds, but inclusion is not finality. A two-tier policy: act after a few confirmations for UX, gate irreversible actions on checkpoint finality.
26 Dec 2025, 15:40 UTC

The problem: fast inclusion is not finality
Polygon PoS (Bor layer) produces a block roughly every two seconds, so a receipt appears quickly — but a receipt is just inclusion, not finality. Short-lived reorgs can remove recently included transactions. The useful takeaway: treat finality as a two-tier decision. Act optimistically after a few confirmations for low-risk state, and gate irreversible actions (withdrawals, large transfers, cross-chain messages) on checkpoint finality, which arrives when Heimdall commits a checkpoint covering your block range to Ethereum, typically minutes later.
Prerequisites
- A funded wallet with POL (or MATIC on older tooling) for gas on the target network.
- An RPC endpoint: a provider-hosted endpoint or your own node. Public endpoints can be rate-limited or briefly inconsistent during reorgs.
- A client library (examples use ethers.js v6).
- The correct chain ID: 137 for mainnet; for testnet, verify the currently supported network — Mumbai was deprecated in favor of Amoy, and testnet names and IDs change over time, so confirm against the official docs before configuring tooling.
The two-tier policy
Tier 1 — optimistic: after ~5–10 block confirmations (tens of seconds), update UI state for low-risk purposes. Tier 2 — final: wait for checkpoint inclusion of the block range containing your transaction. A checkpoint is a periodic commitment to Ethereum of a range of Bor blocks; once the range containing your block is checkpoint-final, reorgs past that point are not expected. The threshold for tier 1 is an operational heuristic, not a protocol guarantee — size it to the value at risk.
Procedure
Send the transaction, then record the block number and block hash from the receipt. Poll for additional confirmations, then for checkpoint finality. Only then mark the operation complete in your application state.
Example with ethers.js v6:
const provider = new ethers.JsonRpcProvider(process.env.POLYGON_RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const tx = await wallet.sendTransaction({ to: recipient, value: amount });
const receipt = await tx.wait();
const blockNumber = receipt.blockNumber;
const blockHash = receipt.blockHash;
// Tier 1: wait for N confirmations
const current = await provider.getBlockNumber();
const confirmations = current - blockNumber + 1;
// Reorg check: block hash at that height must still match
const laterBlock = await provider.getBlock(blockNumber);
if (laterBlock.hash !== blockHash) {
// reorged — transaction may need resubmission
}
// Tier 2: check checkpoint finality for the block range
// via a Heimdall-compatible endpoint or explorer API
// (e.g., the Heimdall checkpoint status for the range containing blockNumber)
Expected checks
receipt.statusis 1 (success).- Re-querying the block hash at the recorded height still matches — no reorg occurred.
- The checkpoint status for the range reports finalized.
Recovery options
Transaction disappeared after a reorg: resubmit with the same nonce and a competitive EIP-1559-style fee (maxFeePerGas and maxPriorityFeePerGas).
Transaction stalls pending: send a replacement with the same nonce and a higher fee. Hardcoded low fees can leave transactions stuck — Polygon's base fee behavior is chain-specific.
Receipt shows failure (status 0): inspect revert data before retrying; don't blindly resubmit.
Verification
On the Amoy testnet: send a small test transaction, record block number and hash, and re-query the block hash after several minutes to confirm it was not reorganized. Query checkpoint/milestone status for the containing range via a Heimdall-compatible endpoint or explorer and confirm finalized. Deliberately submit with a too-low fee, observe stalling, then replace with a higher-fee same-nonce transaction and confirm the replacement is mined.
Limitations
Confirmation thresholds and checkpoint timing are heuristics, not guarantees. Public RPC endpoints may be inconsistent during reorgs; using multiple providers or your own node reduces false negatives. Verify the active testnet name, chain ID, and recommended practices against the current official Polygon developer documentation before relying on any specific number.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.