How to Download Solana Transaction History at Scale: RPC, APIs, Archives and Parquet
Learn how to download Solana transaction history at scale. Compare RPC, indexed APIs, raw archives and Parquet datasets, then build a reliable pipeline for backfills, analytics and backtesting.
If you need to download Solana transaction history, the right solution depends on what “history” means for your workload.
Do you need transactions involving one wallet? Every transaction for a program over six months? Raw instructions and logs? Every Pump.fun buy? A reproducible dataset that you can query hundreds of times for backtests or machine-learning features?
Those requirements sound similar, but they have very different architectures.
The common failure mode is using an RPC endpoint designed for point lookups as if it were a bulk historical warehouse. It may work for a proof of concept. It becomes slow, expensive and difficult to validate once the job includes millions of transactions or repeated analysis.
This guide compares the practical ways to get Solana history—RPC, indexed APIs, raw archives and prepared Parquet datasets—and explains how to choose and validate the right one.
Quick answer: which method should you use?
| Requirement | Usually the best starting point |
|---|---|
| Look up one known transaction | RPC getTransaction |
| List transactions referencing one address | RPC getSignaturesForAddress or an indexed API |
| Retrieve a small recent time range | RPC/API |
| Build an application that queries history interactively | Indexed API |
| Collect future events continuously | Geyser/stream + your own storage |
| Build a universal historical Solana indexer | Archive data + custom decoder/indexer |
| Study one protocol across months or years | Decoded protocol dataset |
| Run repeated analytics/backtests/ML features | Bulk Parquet in your own compute environment |
| Audit or reproduce a historical research result | Versioned files, manifest and checksums |
The key principle is simple:
Use RPC for retrieval, an archive/indexer for raw reconstruction, and bulk files for repeated analytical scans.
What does “Solana transaction history” actually contain?
A Solana transaction is not naturally a row in a simple trade table.
A transaction can contain multiple top-level instructions, nested inner instructions, program logs, token-balance changes, address lookup tables and an execution result. One transaction may create an account, invoke an aggregator, swap through several pools and transfer fees—all in one atomic execution.
The official getTransaction RPC method returns a confirmed transaction by signature, or null when it is not found at the requested commitment. Its response can include the slot, block time, message/instructions, metadata, logs, balances and inner instructions. That is excellent for inspecting a known signature. It is not yet a semantic answer to “which Pump.fun buys happened?” or “what was DEX volume?”
For analytical use, distinguish these layers:
| Layer | Typical contents | Best for |
|---|---|---|
| Transaction | Signature, account keys, top-level instructions | Audit and raw reconstruction |
| Execution metadata | Logs, inner instructions, balances, error status | Program decoding and token-flow analysis |
| Decoded instruction/event | Named protocol action and typed fields | Protocol analytics |
| Derived market/state table | Price, liquidity, balances, labels | Specific research questions |
Option 1: Use Solana RPC
Solana JSON-RPC is the right first tool for many small history jobs.
Find signatures for an address
The official getSignaturesForAddress method returns confirmed transaction signatures for transactions whose account keys reference a specified address. Results are ordered newest to oldest and include signature, slot, error, block time and confirmation status. It supports pagination controls such as before and until.
Conceptually:
address → page of signatures → fetch each signature → decode/storeThis works well when you need:
- a small wallet’s transaction list;
- activity for one mint, account or program address;
- an investigation around a known set of signatures;
- a narrow reconciliation task.
Fetch a transaction by signature
Once you have a signature, call getTransaction. The official documentation shows that the response can include the transaction version, slot, block time, execution metadata and inner instructions.
At this stage, the work shifts from retrieval to interpretation. A token transfer in raw transaction metadata is not necessarily a DEX trade. A Jupiter transaction can have multiple liquidity legs. A failed transaction may still contain useful evidence for a reliability study but should not be counted as an executed trade.
When RPC becomes the wrong architecture
RPC becomes awkward when you need to:
- crawl many addresses or every transaction involving a program;
- backfill long time ranges;
- retrieve millions of signatures and full transaction bodies;
- run the same historical scan repeatedly;
- decode many protocol versions and inner instructions;
- guarantee a reproducible research input;
- handle provider limits, availability differences and gaps.
The problem is not that RPC is bad. It is simply designed as a request/response interface, not as your long-term columnar warehouse.
Option 2: Use an indexed Solana API
Indexed APIs sit between raw RPC and a dataset you own.
They may provide higher-level queries such as transaction history by address, parsed actions, token transfers or program-specific events. They are useful for application backends and exploratory workflows because they avoid much of the raw decoding work.
Choose an indexed API when you need:
- searchable history for users or wallets;
- application queries with low integration overhead;
- current plus recent historical results;
- a small number of narrowly-scoped data products.
Ask four questions before relying on one for a historical project:
- What is the exact retention/coverage for this endpoint?
- Is the data raw, parsed or derived?
- Are failed transactions and inner instructions included?
- Can you export and retain the full result, with a stable version?
An API can be excellent for serving an app while still being the wrong foundation for a 200-run historical research program.
Option 3: Build from raw archive data
If you need arbitrary Solana history and want complete control over the output, build your own archival indexing pipeline.
The pipeline usually looks like this:
historical blocks / transactions
→ transaction parser
→ program and inner-instruction decoder
→ normalized tables
→ validation and deduplication
→ warehouse / Parquet lakeThis route is appropriate when you need to support unknown programs, preserve raw chain semantics, or develop your own canonical decoding rules.
It also carries the most engineering work.
What an archive/indexer has to handle
At minimum, plan for:
- legacy and versioned transactions;
- address lookup tables;
- outer and inner instruction paths;
- program upgrades and changing instruction layouts;
- logs and emitted events;
- failed versus successful execution;
- token decimals and Token-2022 extensions;
- slot, block-time and transaction ordering;
- skipped slots, missing metadata and retried ingestion;
- storage, compaction, reprocessing and schema evolution.
The raw chain gives you evidence. It does not give you a ready-made swap, liquidity_add or token_creation table. Those are decoders and policies you must build, test and maintain.
Option 4: Download a prepared Solana dataset
If the goal is to analyse known protocols—not to build a universal indexer—a decoded bulk dataset can remove most of the reconstruction work.
This is the model used by datastore.sh’s Solana data catalog. It provides documented protocol-level Solana data as typed, versioned Parquet files rather than a proprietary historical query API. The catalog describes decoded instructions, events and state tables, with coverage specific to each dataset and selected window.
For example, if your question is:
“Which Pump.fun tokens reached 100 unique buyers in their first minute, and how did they trade after migrating to PumpSwap?”
you want decoded creation, trade, completion/migration and PumpSwap records—not an undifferentiated collection of transaction JSON.
Prepared data is especially useful when you need to:
- query the same historical universe repeatedly;
- use DuckDB, Polars, ClickHouse, Spark or a warehouse;
- join several protocol tables;
- hand the dataset to analysts or model-training jobs;
- associate every research result with an immutable input version.
Raw transactions vs decoded protocol data
Neither is universally better.
| If you need… | Prefer… | Why |
|---|---|---|
| Unrecognized programs or custom interpretation | Raw transactions | You control the decoder |
| A chain-level audit trail | Raw transactions + metadata | Keeps full execution evidence |
| Pump.fun trade analysis | Decoded Pump.fun records | Avoids repeated instruction/event parsing |
| DEX volume by venue | Decoded DEX swaps plus route rules | Raw token transfers are ambiguous |
| Wallet history UI | Indexed API | Fast targeted retrieval |
| Repeated protocol research | Partitioned Parquet | Efficient scans and reproducible inputs |
| Live collection going forward | Stream + raw storage/decoder | Captures events as they occur |
The best systems often retain both layers: raw provenance for auditability and decoded tables for analysis.
Why Parquet is useful for large Solana history
Transaction JSON is a natural transport format. It is often a poor format for repeated analytics.
Parquet is columnar. When a query needs only six fields from a 40-column decoded event table, an analytical engine can read the relevant columns instead of reparsing complete JSON documents and nested arrays each time.
For example, this query needs no full transaction logs:
SELECT
mint,
COUNT(DISTINCT user) AS unique_buyers,
SUM(sol_amount) AS sol_volume
FROM read_parquet('pumpfun/trade_event/date=*/part-*.parquet')
WHERE is_buy = TRUE
GROUP BY mint
ORDER BY sol_volume DESC;Parquet also works with common analytical tooling:
- DuckDB;
- Polars;
- ClickHouse;
- Spark;
- Snowflake;
- BigQuery.
This makes the historical input portable. Your research should not have to depend on making the same paid API request every time a feature changes.
A reliable Solana history download architecture
For a large, repeatable historical job, structure the workflow as an ingestion project, not a script that keeps retrying API calls.
1. Write the coverage contract first
Define:
- network: mainnet-beta, devnet or another cluster;
- start/end slots and timestamps;
- target universe: accounts, programs, mints or all transactions;
- finalized versus confirmed commitment policy;
- successful-only or successful-and-failed inclusion;
- raw, decoded or derived output;
- expected order of magnitude and storage budget.
“All Solana transactions from January” is incomplete. “All successful instructions emitted by program X between finalized slot A and finalized slot B, with inner instructions and logs” is a usable contract.
2. Choose the source and retain its identity
Record:
- provider/source name;
- endpoint or dataset version;
- request parameters or coverage manifest;
- start and end cursor/slot;
- retrieval timestamp;
- any source-reported gaps or errors.
This is what lets you explain a result months later.
3. Land immutable raw or delivered files
Avoid silently overwriting history. Store the original response/file set, then create derived tables separately.
For bulk data, keep a delivery manifest that lists file paths, row counts where available, schema version and checksums. datastore.sh provides manifests and SHA-256 checksums for delivered Parquet files, which makes integrity checking part of the normal ingestion workflow rather than an afterthought.
4. Normalize and decode with explicit versioning
Use tables such as:
transactions
instructions
inner_instructions
logs
token_balance_changes
decoded_protocol_eventsEvery derived row should retain a path back to its signature and instruction position. A decoded Pump.fun trade without a traceable signature/instruction lineage is difficult to audit when the decoder changes.
5. Validate coverage before analysis
Check:
- first and last slot/time actually present;
- slot continuity within the requested range;
- row counts by day/program;
- failed/successful transaction proportions;
- duplicate transaction/event records;
- null rates in critical fields;
- sample signatures against an independent source;
- schema consistency across partitions.
Do this before running a long backtest. Fixing an unnoticed week-long gap after training a model wastes far more time than validating at ingest.
How to download history for common Solana workloads
One wallet
Start with getSignaturesForAddress or an indexed address-history API. Page through results, fetch transaction details as needed, and keep the cursor and stop condition. If you need only recent activity, this can be straightforward.
One program
For a small program or narrow date range, an indexed program API or targeted archive scan can work. For large protocol history, use a decoded protocol dataset or build a program-specific indexer. Scanning all raw transactions and filtering afterward is usually wasteful.
One mint across several DEXs
Use decoded pool-level swaps and aggregation/routing records, then define the metric: user-facing swaps, pool legs, token transfers or price observations. Do not assume every token transfer is a trade.
Full market backtesting
Land immutable bulk files locally or in a warehouse. Build event-time feature tables, preserve every input version, and simulate execution with fees, liquidity and strict causality. An API-only loop will be slow and makes experiment reproducibility harder.
Common Solana transaction-history mistakes
Mistake 1: Treating an address signature list as complete business history
getSignaturesForAddress lists transactions that reference the address in accountKeys. You still need to fetch, decode and classify them. The address may be touched for many reasons unrelated to the business event you are studying.
Mistake 2: Treating every token transfer as a swap
Transfers can represent account setup, LP operations, fee movements, airdrops, program settlement or a multi-leg route. Use protocol semantics and transaction lineage.
Mistake 3: Ignoring inner instructions
Important work can occur through cross-program invocations. Solana’s getTransaction response includes inner instruction data; omitting it can make a decoder incomplete.
Mistake 4: Ignoring failed transactions without deciding to
For executed trade-volume research, failures are normally excluded. For latency, bot behaviour or reliability research, failures may be valuable. Make it an explicit policy.
Mistake 5: Using block time as the only ordering key
Multiple actions can share a time or a slot. Retain the transaction and instruction ordering information needed by your use case.
Mistake 6: Re-running the same archive extraction for every experiment
Separate one-time acquisition/normalization from repeatable analysis. Keep partitioned, validated data that feature jobs can scan directly.
Mistake 7: No manifest, no checksums, no reproducibility
If you cannot identify the precise files and schema that fed a historical result, it will be difficult to debug or trust later.
Questions to ask a Solana historical-data provider
Before choosing a source, ask:
- What exact date and slot range is available?
- Is the source raw transaction data, decoded events or derived tables?
- Are inner instructions, logs and token-balance metadata included?
- Are failed transactions included, excluded or labelled?
- How are program upgrades and transaction versions handled?
- What is the partitioning and file format?
- Can I inspect schemas and sample rows first?
- How are duplicate/replay records handled?
- Are coverage gaps documented?
- Are files versioned and checksummed?
- Can I retain the files and query them in my own infrastructure?
- Can every decoded row be traced back to a chain signature and instruction?
The answers matter more than an advertised transaction count.
Frequently asked questions
Can I download all Solana transactions?
Yes, but “all” requires an archive-scale source and a plan for large raw data volumes, storage, indexing and decoding. For a known protocol, a decoded protocol dataset is usually much more practical than starting from every chain transaction.
How do I get Solana transaction history for an address?
Use getSignaturesForAddress or an indexed history API to obtain a paginated list of signatures, then retrieve and parse the relevant transactions. Keep the pagination cursor, coverage policy and transaction-status rule.
Is an RPC node enough for historical Solana data?
It is enough for many small or targeted retrieval tasks. It becomes a poor default for full backfills, program-wide history and repeated analytical scans because you still have to retrieve, store, decode, validate and repeatedly query large raw responses.
What is the difference between Solana archive data and a historical dataset?
Archive data is closer to raw chain history. A historical dataset may already be organized into typed, protocol-specific tables. Archive data gives you maximum flexibility; a prepared dataset reduces the indexing and decoding work for known questions.
Can I use Solana historical data for backtesting?
Yes. Keep the exact data snapshot, enforce strict event-time causality, include relevant execution costs and avoid using features that were visible only after the simulated decision.
Does datastore.sh provide Solana transaction history?
datastore.sh provides downloadable historical Solana datasets as typed, versioned Parquet files. Its focus is decoded protocol instructions, events and state tables for research and analytics, rather than serving a metered historical query API.
The key takeaway
Downloading Solana transaction history is not one task. It is a choice between four data architectures.
Use RPC for known signatures and narrow address history. Use indexed APIs for application queries. Use raw archives when you need to build and control the decoder. Use documented Parquet datasets when your objective is repeated analysis of known protocols.
Choose the architecture based on the historical question you need to answer—not simply on who can return a transaction fastest.
Explore historical Solana data on datastore.sh to inspect protocol-specific schemas, samples and coverage windows before you start a large backfill.
Data Platform
datastore.sh engineering
The team that operates capture, decoding, and reconciliation for every dataset in the catalog.