Geyser Plugins
Geyser plugins let Agave validators stream account and transaction updates to external sinks for indexing without polling JSON-RPC.
Recipe
Quick-reference recipe card - copy-paste ready.
{
"libpath": "/path/to/libgeyser_plugin.so",
"accounts_selector": { "owners": ["YOUR_PROGRAM_ID"] },
"transaction_selector": { "mentions": ["YOUR_PROGRAM_ID"] }
}agave-validator --geyser-plugin-config geyser.json ...When to reach for this:
- Self-hosted validator with custom indexing pipeline.
- Lowest-level access to slot-ordered account updates.
- Building proprietary data products on your own stake.
- Filtering at source before network egress costs.
Working Example
# geyser.json (illustrative - match your plugin's schema)
cat > geyser.json <<'EOF'
{
"libpath": "/opt/geyser/libmy_sink.so",
"kafka": { "bootstrap.servers": "localhost:9092", "topic": "solana-events" },
"accounts_selector": {
"owners": ["YOUR_PROGRAM_ID"]
}
}
EOF
agave-validator \
--ledger /data/ledger \
--geyser-plugin-config geyser.json \
--rpc-port 8899What this demonstrates:
- Plugin
.soloads into validator process space. - Selectors limit firehose to relevant owners/mentions.
- Downstream Kafka/Postgres consumers process normalized events.
Deep Dive
How It Works
- Validator calls plugin hooks on account writes and committed transactions.
- Updates carry slot, write version, and account pubkeys/data.
- Plugin must be fast - blocking slows validator if misimplemented.
- Yellowstone gRPC is a popular distribution pattern built on Geyser interfaces.
Plugin Responsibilities
| Concern | Plugin | Your indexer |
|---|---|---|
| Filtering | owner/mention selectors | business logic |
| Durability | forward to queue | DB commits |
| Replay | slot checkpoints | idempotent upserts |
| Upgrades | versioned .so | schema migrations |
bash Notes
# Verify plugin loads at validator start - check logs for geyser init lines
tail -f /data/validator.log | grep -i geyserGotchas
- Slow plugin callbacks - validator falls behind on slots. Fix: async handoff to queue, minimal work in hook.
- No selector - full mainnet firehose overwhelms network. Fix: strict owner filters.
- Plugin/version skew - Agave 4.1.1 requires matching plugin ABI. Fix: rebuild plugin on validator upgrades.
- Assuming delivery guarantees - crashes lose in-flight events without checkpointing. Fix: store last slot in durable queue.
- Running plugin on public RPC only - you do not control hosted provider plugins. Fix: self-host or use Yellowstone provider.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Yellowstone gRPC | Managed streaming | You already operate validator |
| Webhooks | HTTP push simplicity | Ultra-low latency needs |
| RPC backfill | Small history | Live high-volume programs |
| DAS API | Asset reads only | Arbitrary instruction indexing |
FAQs
Do I need my own validator?
For custom plugins yes; managed Yellowstone gives gRPC without operating stake.
What languages for plugins?
Rust/C++ .so dynamic libraries per Agave geyser plugin interface.
Can plugins filter transactions only?
Yes - transaction_selector with mentions of program IDs.
How do I recover from crash?
Replay from last committed slot stored in your DB using RPC backfill gap fill.
Are account updates compressed?
Plugin receives full account data on writes relevant to selector - plan bandwidth.
Devnet plugin testing?
Run test validator with plugin against devnet ledger clone for lighter load.
Relation to Yellowstone?
Yellowstone exposes Geyser-style streams over gRPC to remote clients.
Security concerns?
Plugin runs inside validator - supply chain critical; audit .so sources.
Can one plugin fan out to Kafka?
Common pattern - plugin produces; consumers scale horizontally.
Ops cost vs provider?
Self-host plugin ops heavy - provider webhooks/Yellowstone cheaper for small teams.
Related
- Yellowstone gRPC - remote streaming
- Building an Indexer - consumer logic
- Indexing Basics - why index
- RPC Providers - hosted options
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.