Cosmos - Fetching All Transactions from an Address

Retrieving all transactions for a Cosmos address is possible through the Tendermint RPC method tx_search.
However, this method is resource-intensive and can lead to long response times if not scoped properly.

This article explains how to use tx_search effectively, why it’s computationally heavy, and how to limit its impact by defining block ranges.


Using tx_search on Cosmos

tx_search allows filtering transactions by event tags such as transfer.recipient or message.sender.
A correct request looks like this:

curl --location 'https://cosmos-mainnet.gateway.tatum.io/tendermint/' \
--header 'Content-Type: application/json' \
--header 'x-api-key: {YOUR_API_KEY}' \
--data '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "tx_search",
    "params": {
        "order_by": "desc",
        "page": "1",
        "per_page": "30",
        "query": "transfer.recipient='cosmos1hgp84me0lze8t4jfrwsr05aep2kr57zrk4gecx' AND tx.height>28155409 AND tx.height<28166675"
    }
}'

This query fetches up to 30 transactions where the specified address received tokens between block 28155409 and 28166675.


Why the Request Is Heavy

The tx_search RPC endpoint performs a full index lookup in the Tendermint node’s transaction database.
If no block range is specified, the node may need to scan millions of transactions to evaluate event tags like transfer.recipient, causing:

  • Very high response time: responses often take 30–60 seconds or longer to direct timeouts
  • Increased node load: high I/O and CPU consumption

This behavior is normal for Tendermint RPC; it’s not optimized for high-frequency or large-scale address searches.


Best Practices

  1. Always define a block range
    Restrict the height range to smaller segments, for example:
    `"query": "transfer.recipient='cosmos1...' AND tx.height>28100000 AND tx.height<28105000"`
    
    A 5,000–10,000 block window is a good balance between speed and coverage.
  2. Paginate results
    Use "page": "2", "page": "3", etc. to iterate through multiple result pages within the range.
  3. Walk the chain incrementally
    Automate the process by iterating over consecutive height ranges:
    28100000–28105000  
    28105001–28110000  
    28110001–28115000  
    ...
    
    This approach prevents full-chain scans and keeps response times reasonable.
  4. Adjust query parameters
    • Use "order_by": "desc" to start from the newest blocks.
    • Focus on keeping your block range scope narrow. Overly broad height intervals can drastically slow down responses to make requests start timing out.

Summary

ApproachDescriptionPerformance
tx_search without block rangeFull-chain scan across all transactions❌ Very slow (30–60 s+)
tx_search with block rangeLimited height window⚠️ Manageable (3–10 s)
Iterative height windowsScripted queries by block segments✅ Efficient and scalable