Fuel Core Storage Backends: Local RocksDB and S3 Implementation Guide
Fuel Core supports three storage backends: Local (RocksDB) for embedded key-value storage, S3 (Publish) for writing blocks to Amazon S3, and S3NoPublish for read-only access to existing S3 buckets.
The Fuel Labs fuel-core repository implements a pluggable storage architecture that allows blockchain operators to choose between local embedded databases and cloud object storage. Understanding these storage backends is essential for node operators who need to balance performance, durability, and operational costs when running Fuel Core nodes.
Local Storage Backend: RocksDB Implementation
Core Architecture and File Structure
The Local storage backend uses RocksDB as its embedded key-value store. According to the Fuel Core source code, the core DB layer is a thin wrapper around RocksDB that provides type-safe access to on-chain and off-chain data columns.
The implementation resides in [crates/fuel-core/src/state/rocks_db.rs](https://github.com/FuelLabs/fuel-core/blob/master/crates/fuel-core/src/state/rocks_db.rs#L13-L180), where the RocksDb<T> generic struct provides the foundation for all local storage operations. This file defines the interaction patterns for opening databases, managing column families, and handling snapshots.
The [crates/fuel-core/src/combined_database.rs](https://github.com/FuelLabs/fuel-core/blob/master/crates/fuel-core/src/combined_database.rs) file aggregates all RocksDB column families, including:
- OnChain: Block headers, transactions, and receipts
- OffChain: Indexing data and cached metadata
- Relayer: Bridge and message relay data
Key-Value Operations and Traits
The RocksDb<T> implementation provides several critical traits that abstract storage operations:
KeyValueMutate: Handles insertions, updates, and deletionsKeyValueInspect: Provides read access to individual keysIterableStore: Enables range queries and full table scans
These traits allow higher-level services to remain agnostic of the underlying RocksDB implementation while maintaining ACID guarantees through transactional views.
S3 Storage Backends: Publish and Read-Only Modes
S3 Publish Backend
The S3 storage backend enables nodes to publish newly produced blocks, receipts, and metadata to Amazon S3 buckets. This creates a durable, cloud-hosted copy of blockchain data that downstream services can consume without querying the node directly.
When StorageMethod::S3 { bucket, endpoint_url, requester_pays } is selected, the block-aggregator service creates an AWS S3 client using the aws-sdk-s3 crate. The implementation in [crates/services/block_aggregator_api/src/service.rs](https://github.com/FuelLabs/fuel-core/blob/master/crates/services/block_aggregator_api/src/service.rs#L71-L98) handles:
- Custom endpoint URLs for S3-compatible services (MinIO, Ceph, etc.)
- The requester-pays flag for accessing buckets where the requester bears data transfer costs
- Streaming serialization of block data to S3 objects
S3NoPublish Backend
The S3NoPublish variant provides read-only access to existing S3 buckets without attempting to upload new blocks. This mode suits RPC nodes that serve historical data while another node handles the publishing workload.
The same S3 client construction logic applies, but the S3NoPublish { … } enum variant signals the block-aggregator to disable write-side calls. The BlocksProvider trait implementation in the storage provider modules handles the read-only semantics, ensuring that any write attempts return appropriate errors.
Configuring Fuel Core Storage Backends
Command-Line Configuration
Node operators select storage backends using the --storage-method flag and related S3 options. The CLI handling resides in [bin/fuel-core/src/cli/run/rpc.rs](https://github.com/FuelLabs/fuel-core/blob/master/bin/fuel-core/src/cli/run/rpc.rs).
# Local RocksDB (default)
fuel-core run --storage-method local
# Publish to S3
fuel-core run \
--storage-method s3 \
--s3-bucket my-fuel-bucket \
--s3-endpoint https://s3.us-west-2.amazonaws.com \
--s3-requester-pays false
# Read-only S3 mode
fuel-core run \
--storage-method s3-no-publish \
--s3-bucket shared-fuel-blocks \
--s3-requester-pays true
Programmatic Configuration
Rust developers can configure storage backends programmatically using the Config struct from fuel_core::service.
use fuel_core::service::{Config, StorageMethod};
// Local RocksDB configuration
let local_cfg = Config {
storage_method: StorageMethod::Local,
..Default::default()
};
// S3 publishing configuration
let s3_cfg = Config {
storage_method: StorageMethod::S3 {
bucket: "my-fuel-bucket".into(),
endpoint_url: Some("https://s3.us-east-1.amazonaws.com".into()),
requester_pays: false,
},
..Default::default()
};
// S3 read-only configuration
let s3_read_cfg = Config {
storage_method: StorageMethod::S3NoPublish {
bucket: "shared-fuel-blocks".into(),
endpoint_url: None, // Use default AWS endpoint
requester_pays: true,
},
..Default::default()
};
Summary
- Fuel Core storage backends include Local (RocksDB), S3 (Publish), and S3NoPublish (read-only) modes, selectable via the
storage_methodconfiguration field. - Local storage uses a RocksDB wrapper in
crates/fuel-core/src/state/rocks_db.rsthat implementsKeyValueMutate,KeyValueInspect, andIterableStoretraits for ACID-compliant operations. - S3 backends leverage the
aws-sdk-s3crate incrates/services/block_aggregator_api/src/service.rsto stream block data to cloud storage, supporting custom endpoints and requester-pays buckets. - Trait-based abstraction ensures that higher-level services remain backend-agnostic, requesting generic
Arc<dyn BlocksProvider>handles regardless of whether data resides locally or in S3.
Frequently Asked Questions
What is the default storage backend for Fuel Core?
The default storage backend is Local, which uses RocksDB as the embedded key-value store. When running fuel-core run without specifying --storage-method, the node automatically initializes a RocksDB instance in the configured data directory, providing ACID guarantees for all on-chain and off-chain data columns.
Can Fuel Core switch between storage backends without data migration?
No, switching between storage backends requires careful consideration of data persistence. The Local backend stores data in RocksDB format on disk, while S3 backends expect data in cloud object storage. To migrate from Local to S3, you would need to sync the node against the network while configured for S3 publishing, as there is no automated conversion tool between the RocksDB files and S3 object formats.
How does the S3 backend handle authentication?
The S3 backend uses the standard AWS SDK credential chain provided by the aws-sdk-s3 crate. It automatically checks for credentials in environment variables (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY), AWS credential files (~/.aws/credentials), IAM instance profiles, and other standard AWS authentication methods. The implementation in crates/services/block_aggregator_api/src/service.rs constructs the S3 client without explicit credential parameters, delegating authentication entirely to the AWS SDK's default provider chain.
What are the performance characteristics of RocksDB versus S3 storage?
RocksDB (Local) provides low-latency, high-throughput access to blockchain state with microsecond-range read latencies and ACID transaction support, making it ideal for validator nodes and RPC services requiring fast state access. S3 storage introduces network latency (typically 10-100ms) and higher throughput costs, but offers unlimited scalability, durability, and cost-effective archival storage. S3 is optimized for write-once-read-many patterns suitable for block publishing and historical data serving, while RocksDB excels at random access to hot state data.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →