Skip to main content

Overview

Goldsky provides curated Solana datasets with full historical data, making it easy to build pipelines for blocks, transactions, instructions, and token activity. All datasets are pre-processed and optimized for common use cases.
Solana configuration differs from EVM chains:
  • Solana uses start_block (slot number) instead of start_at. Omit start_block to start from the latest slot.
  • Use end_block (not SQL WHERE clauses) to bound a Solana job mode pipeline.
  • in_order mode is available for Solana sources (not available for EVM)
  • Batch settings are not available for Solana sources

Quick Start

Get started with Solana data - choose the dataset that fits your use case: For token transfers:
For transaction + instruction analysis:
Available datasets:
  • solana.blocks - Block data with leader info
  • solana.transactions - Transaction data with accounts and balances
  • solana.transactions_with_instructions - Transactions with nested instruction arrays
  • solana.instructions - Individual instructions (one row per instruction)
  • solana.token_transfers - SPL token transfers
  • solana.native_balances - SOL balance changes
  • solana.token_balances - SPL token balance changes
  • solana.rewards - Records of rewards distributed to validators for securing and validating the Solana network.

Dataset schemas

The tables below list the columns produced by each Solana dataset. List<Struct> columns are nested arrays; see Working with Nested Instructions for query patterns.

solana.blocks (v1.0.0)

Block-level summary, one row per block. SQL transform over the raw source. Primary key: slot.

solana.transactions (v1.0.0)

One row per transaction. SQL transform over the raw source. Primary key: id (sl_transaction_{block_hash}_{index}).

solana.instructions (v1.0.0)

One row per (flattened) instruction. solana_transform (transform: instructions). Primary key: id.

solana.token_transfers (v1.0.0)

SPL token transfers. Plugin + SQL (transform: token_transfers then SQL reshape). Primary key: id.

solana.token_transfers (v1.1.0)

Same as v1.0.0 plus two fee columns (for transfers carrying a token fee):

solana.native_balances (v1.0.0)

Native SOL balance changes, one row per account balance delta. Derived from solana.transactions via SQL. Primary key: id ({block_hash}_NATIVE_{tx_index}_{index}).

solana.token_balances (v1.0.0)

SPL token balances per (owner, mint) per transaction. Derived from solana.transactions via SQL (pre/post union). Primary key: id ({block_hash}_{tx_index}_{index}).

solana.rewards (v1.0.0)

Staking/validator rewards, one row per reward entry. SQL transform over the raw source. Primary key: id (sl_reward_{block_hash}_{index}).

solana.transactions_with_instructions (v1.0.0)

One row per transaction with its grouped instructions and token balances inline — the base for dex_swaps. solana_transform (transform: transactions_with_instructions). Primary key: id.

Starting position

Solana sources use start_block to specify a starting slot number. This differs from EVM chains which use start_at: latest or start_at: earliest.
To start from the latest slot on Solana, simply omit the start_block parameter. This is different from EVM chains where you would use start_at: latest.

Multiple block ranges

Solana sources accept an optional block_ranges field so a single pipeline can process several disjoint slot windows. This is useful for backfilling specific historical ranges without replaying everything in between, or for splitting a large backfill into several sharded pipelines. Syntax: block_ranges takes a JSON-encoded string (not a YAML list) of [start, end] pairs. Both bounds are inclusive.
Rules:
  • Ranges must be non-empty, non-overlapping, and strictly increasing. The engine panics at startup if these invariants are violated.
  • A range’s start must be at or after the network’s earliest available block.
  • block_ranges takes precedence over start_block / end_block. If you set both, the legacy fields are ignored and a warning is logged.
  • After a checkpoint restore, the engine skips ahead to the next slot that falls inside any remaining range.
Use with job: true to run a bounded backfill that terminates cleanly once every range is processed — the pipeline exits after the epoch covering the final range’s end slot finalizes:
Changing block_ranges on a running pipeline triggers a rewind, just like changing start_block or end_block. See Source checkpoints and rewinds.

Guide: Track Specific SPL Tokens

Monitor transfers for specific tokens like USDC:

Guide: Track Large SOL Balance Changes

Monitor accounts with significant SOL movement:

Guide: Decode Program Instructions

Decode Solana program instructions using IDL (Interface Definition Language):
Decoding functions:
  • _gs_decode_instruction_data(idl, data) - Decode instruction data using an IDL
  • _gs_decode_log_message(idl, log_messages) - Decode program log messages using an IDL
  • _gs_fetch_abi(url, 'raw') - Fetch IDL from a URL
The decoded result includes the instruction/event name and parameters.

Guide: Decode Program Log Messages

Decode Solana program log messages to extract structured event data. This is useful for tracking program events like swaps, liquidations, or other on-chain actions that emit logs.
Log message decoding works best with Anchor-based programs that emit structured events. The IDL must match the program version to decode correctly.

Guide: Analyze Transaction Success Rates

Track transaction patterns and success rates using SQL:

Guide: Track Specific Programs

Monitor all instructions for a specific program using SQL:

Guide: Multi-Account Monitoring with Dynamic Tables

Track transfers involving specific accounts:
Add accounts to track:

Guide: Working with Transactions and Instructions Together

The transactions_with_instructions dataset provides a transaction-centric view with all instructions nested in an array. This is ideal when you need both transaction-level data and instruction details without joining separate datasets.

When to Use transactions_with_instructions

Use transactions_with_instructions

  • Analyzing multi-instruction transactions - Counting instructions per transaction - Transaction-level aggregations with instruction filtering - Examining instruction sequences within transactions

Use separate datasets

  • Simple instruction filtering by program - Individual instruction analysis
  • Better SQL performance for instruction-only queries - Joining instructions with other data

Schema Overview

Each row represents one transaction with nested arrays: Transaction fields: id, index, block_slot, block_hash, block_timestamp, accounts, balance_changes, pre_token_balances, post_token_balances, recent_block_hash, signature, err, status, compute_units_consumed, fee, log_messages Nested instruction array: instructions - Array of instruction structs, each containing:
  • id, index, parent_index (null for top-level, set for inner instructions), signature, block_slot, block_timestamp, block_hash, tx_fee, tx_index
  • program_id, data, accounts
  • status, err
You can see a sample of the transactions_with_instructions dataset here

Example: Analyze Multi-Step Swap Transactions

Find transactions with multiple Jupiter swap instructions:

Example: Examine Inner Instructions

Analyze transactions with inner instructions (Cross-Program Invocations):

Example: Transaction Success Analysis by Program

Analyze transaction success rates grouped by the programs involved:

Working with Nested Instructions

To access individual instructions from the instructions array: Array indexing (1-based):
Filtering arrays:
Counting:
Use array_filter() and array_filter_first() SQL functions to work efficiently with the nested instruction arrays. See the SQL Functions Reference for more details.

Guide: Recreating Solana’s Transaction Counter

Stream every Solana transaction in real-time to power a live counter, similar to the Total transactions to date counter on Solana’s homepage. This example includes any and all transactions, including failed ones.

Source checkpoints and rewinds

Turbo pipelines use checkpoints to track processing progress. Understanding how checkpoints work helps you avoid unintended rewinds when updating pipeline configurations.

How checkpoints work

Checkpoints use a hash of your source configuration (start_block, end_block, and block_ranges) to identify the user’s intent:
  • Same hash: The pipeline resumes from the existing checkpoint
  • Different hash: The pipeline treats this as a “source change” and rewinds to the new start_block

Preventing unintended rewinds

A common issue occurs when re-applying a pipeline with a different start_block than the currently running configuration. For example:
If you re-apply with an earlier start_block, the pipeline will rewind:
Changing start_block, end_block, or block_ranges triggers a deliberate rewind. The pipeline will restart from the new start_block, reprocessing all data.

Best practices

1

Fetch the current configuration before re-applying

Always check the current pipeline definition before making changes:Using the CLI:
Using the UI: Navigate to your pipeline in the dashboard to view the current configuration.
2

Keep start_block consistent

When updating other pipeline settings (transforms, sinks, resource size), keep the start_block the same as the running configuration to preserve your checkpoint.
If you intentionally want to reprocess data from a specific block, changing the start_block is the correct approach. The rewind behavior is by design to give you control over reprocessing.

Filtering by Account or Program

When you only need data for specific accounts or programs, add a filter to your source configuration. This enables fast scan mode, which skips irrelevant slots during backfills by querying an index of which accounts and programs are active in each slot. This can dramatically speed up historical data processing. We index all accounts and programs referenced in Solana transactions, instructions, and cross-program invocations (CPIs). Program addresses should be specified in the program_ids field, while account addresses, including wallet public keys, Program Derived Addresses (PDAs), and token mint addresses, should be specified in the account_ids field.

Filter syntax

The filter parameter is a YAML mapping with two optional fields: You can specify one or both fields. When both are provided, slots containing activity from either the specified accounts or the specified programs are processed (the conditions are OR’d together).
The following addresses are not indexed and should be excluded from account_ids and program_ids when using fast scan:

Example: Backfill token balances for specific accounts

Example: Backfill transactions for a specific program

The filter parameter speeds up backfills only — when processing historical data from a start_block. During real-time processing (when the pipeline has caught up to the chain tip), all slots are processed regardless of the filter.

Performance Tips

Use the most specific dataset:
  • Token transfers? Use solana.token_transfers
  • Balance changes? Use solana.native_balances or solana.token_balances
  • Transaction-level analysis with instruction details? Use solana.transactions_with_instructions
  • Individual instruction analysis? Use solana.instructions
  • Transaction metadata only? Use solana.transactions
If you only need data for specific accounts or programs, use the filter parameter on your source to skip irrelevant slots during backfills:
This is much faster than filtering in SQL transforms alone, as it skips entire slots that don’t contain relevant data.
Apply filters in SQL as early as possible:
Solana has high throughput. Start with medium or large: