A transaction is "in the mempool" when a node has accepted it but not yet included it in a block. For a few seconds — sometimes longer — it's been seen but isn't settled. If you're building a service that submits transactions, you often want to confirm yours is pending rather than lost.
gOuroboros exposes this via the LocalTxMonitor mini-protocol. The starter-kit demonstrates it in cmd/tx-monitor.
What LocalTxMonitor Does
LocalTxMonitor is a Node-to-Client protocol. You connect to a local socket, acquire a mempool snapshot, then iterate the transactions in that snapshot one at a time. Two queries are common:
Query
Returns
GetSizes()
(capacity, size, numberOfTxs) — mempool capacity, current bytes used, tx count
NextTx()
The next pending transaction, or nil when the snapshot is exhausted
The program uses both: prints the sizes, then iterates the snapshot and prints each transaction's hash, fee, and CBOR.
Prerequisites
- Completed 101.1 (starter-kit set up,
CARDANO_NODE_SOCKET_PATHandCARDANO_NODE_MAGICexported) - Dolos running
- Ideally, a preprod wallet that can submit a transaction (so you have something to look at in the mempool)
Step 1: Run tx-monitor on an Empty Mempool
With nothing pending on your local view, you'll still get the sizes:
go run ./cmd/tx-monitor
Mempool size (bytes): 0 Mempool capacity (bytes): 131072 Transactions: 0
Three things to notice:
- Capacity is fixed by the protocol. 128 KB is the standard limit for mempool size per node.
- Size 0 with Transactions 0 is the steady state on a quiet network.
- The program exits. It doesn't stream — each run is a single snapshot.
Step 2: Submit a Transaction, Then Re-Run
In Module 102 you'll build and submit a real transaction. For this lesson any submitted transaction will do — from a wallet, a faucet request, or an earlier course exercise.
Submit something, then immediately (within 20–40 seconds, before the next block) re-run:
go run ./cmd/tx-monitor
You should see:
Mempool size (bytes): 512 Mempool capacity (bytes): 131072 Transactions: 1
Transaction:
- Hash: 62396165deadbeef...
- Fee: 168317
- CBOR: 84a40081825820...
Once the transaction lands in a block, the next run returns to size 0. That's the window you're watching.
The Code Shape
From cmd/tx-monitor/main.go (paraphrased):
o, _ := ouroboros.NewConnection(
ouroboros.WithNetworkMagic(cfg.Magic),
ouroboros.WithErrorChan(errorChan),
ouroboros.WithNodeToNode(false), // NtC, Unix socket
)
o.Dial("unix", cfg.SocketPath)
capacity, size, numberOfTxs, _ := o.LocalTxMonitor().Client.GetSizes()
for {
tx, _ := o.LocalTxMonitor().Client.NextTx()
if tx == nil {
break
}
// decode tx bytes, print hash/fee/CBOR
}
The NextTx() loop is a snapshot iterator, not a live subscription. You see every transaction that was pending at the moment of the acquire, then you're done. To see a newer snapshot, run the program again.
Use Cases for a Mempool Check
In a production Go service you might call LocalTxMonitor to:
- Confirm your submission was accepted by the node — after
LocalTxSubmission.SubmitTxreturns success, verify the tx is visible in the mempool before telling the user "submitted." - Estimate network congestion —
sizerelative tocapacitytells you how full the mempool is right now. A near-full mempool may reject your submission with anoverfullerror. - Detect a stalled tx — if your tx hash keeps showing up in repeated snapshots, it's pending a long time. Worth investigating why (too low a fee, expired validity window, etc.).
Common Issues
Size is never > 0 even after you submit a transaction
Your wallet submitted through a public relay, not through Dolos. The mempool you see here is only your local node's mempool. Transactions submitted via Blockfrost or a public node won't appear unless they propagate back to Dolos before being mined.
protocol not supported on handshake
LocalTxMonitor is not enabled on every node implementation. Dolos supports it; some lightweight forks may not. If you switch to a different upstream, check its feature list.
Mempool is full and your tx is rejected elsewhere
Capacity is 128 KB and fills up during busy periods (especially on mainnet). This isn't a tx-monitor issue — it's a protocol reality you detect with tx-monitor.
You'll Know You're Successful When
tx-monitorprints sizes when you run it- You've seen your own submitted transaction appear in the mempool at least once
- You understand this is a snapshot-and-iterate model, not a live stream
Practice Tasks
- Submit a transaction, then run
tx-monitorevery 5 seconds until size returns to 0. How long did your tx spend in the mempool? - Compare the tx hash from your wallet's UI against the hash printed by
tx-monitor. They should match exactly. - Read
cmd/tx-monitor/main.goand find thefor { NextTx() }loop. What would break if you replacedbreakwithcontinue?
What's Next
Module 101 is now complete — you can connect to a node, fetch blocks, check the tip, and inspect the mempool. In Module 102 you'll build and sign transactions, and use the starter-kit's tx-submission command to submit them back to the same node you've been querying here.