# How the Gas Price Service in Fuel Core Adjusts Prices Based on Network Activity

> Discover how Fuel Core's gas price service dynamically adjusts fees based on network activity. Learn about sliding-window averages and scaling for responsive transaction costs.

- Repository: [Fuel Labs/fuel-core](https://github.com/FuelLabs/fuel-core)
- Tags: internals
- Published: 2026-03-06

---

**The gas price service in Fuel Core continuously monitors block-level execution gas consumption and data-availability costs, applying a sliding-window average and dynamic scaling to keep transaction fees responsive to network congestion.**

The gas price service operates as an autonomous background task within the Fuel Core node, ensuring that transaction fees reflect real-time network conditions. According to the FuelLabs/fuel-core source code, the service maintains three distinct price components—execution, data-availability (DA), and combined total—updating them after every finalized block through an asynchronous adjustment loop.

## Components of the Gas Price Calculation

The algorithm tracks separate cost drivers that combine to form the final gas price presented to users and RPC clients.

### Execution Gas Price

The **execution gas price** measures average computational demand across recent blocks. After each finalized block, the service reads the total execution gas consumption from the `GasPriceMetadata` table and maintains a simple moving average over a configurable window (default 30 blocks). When average usage exceeds a high-watermark threshold, the service increases the price by a configurable percentage; when usage drops below a low-watermark, it decreases the price proportionally.

### DA Gas Price

The **DA gas price** reflects the cost of storing transaction data on the underlying data-availability layer (e.g., Celestia). The service queries the injected DA source service (`fuel_core_gas_price_service::v1::da_source_service`) to obtain the latest per-byte cost, then multiplies that value by a protocol-defined "bytes per gas" ratio to derive the per-gas DA price component.

### Total Gas Price Calculation

The **total gas price** equals the sum of execution and DA prices, clamped between user-defined minimum and maximum bounds (`min_gas_price` and `max_gas_price`). The final value is atomically persisted to the `GasPriceMetadata` table and broadcast to the rest of the node via the shared `gas_price_service` handle, ensuring all components read identical pricing data.

## The Block-Driven Adjustment Loop

The gas price service implements a six-step update cycle that triggers immediately upon block finalization:

1. **Block Finalization Trigger** – When a block reaches finality, the node's state watcher notifies the gas price service (`StateWatcher::started()`), initiating the update sequence.

2. **Metric Extraction** – The service extracts the block's total execution gas used and total data bytes stored from the block header and receipts.

3. **Window-Based Averaging** – A sliding window stores recent usage statistics. New values push into the window while the oldest values drop out, and the service recomputes the average gas consumption across the entire window.

4. **Dynamic Scaling** – 
   - If `avg_usage > high_watermark` → `exec_price = exec_price * (1 + change_percent)`
   - If `avg_usage < low_watermark` → `exec_price = exec_price * (1 - change_percent)`

5. **DA Price Refresh** – The DA source service supplies the current `da_cost_per_byte`, which the service multiplies by the configured `da_gas_per_byte` ratio to update the DA component.

6. **Persistence and Broadcast** – The combined price is written atomically to `GasPriceMetadata`, and the service notifies awaiting RPC callers through its `SharedData` handle (`await_synced`), guaranteeing price continuity across node restarts and upgrades.

## Key Source Files and Implementation

The algorithm implementation spans multiple crates within the repository:

- **[`crates/services/gas_price_service/src/v1/algorithm.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/gas_price_service/src/v1/algorithm.rs)** – Contains the moving-average calculation and percentage-based scaling logic for execution price adjustments.

- **[`crates/services/gas_price_service/src/v1/service.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/gas_price_service/src/v1/service.rs)** – Orchestrates the periodic update loop, coordinates DA cost fetching, and manages metadata persistence.

- **`crates/services/gas_price_service/src/v1/da_source_service/`** – Houses the DA layer integration that provides real-time per-byte storage costs.

- **[`crates/services/gas_price_service/src/common/fuel_core_storage_adapter/storage.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/gas_price_service/src/common/fuel_core_storage_adapter/storage.rs)** – Implements read/write operations for the `GasPriceMetadata` table.

- **[`crates/fuel-core/src/service/sub_services.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/fuel-core/src/service/sub_services.rs)** – Bootstraps the gas price service and injects it into the node's main Service struct during initialization.

## Code Examples

### Querying the Current Gas Price via Node API

```rust
use fuel_core::service::Service;
use fuel_core_gas_price_service::v1::service::SharedData;

// Assume you have a running `service: Service` instance.
let shared = &service.runner.shared.gas_price_service;
let current = shared.await_synced().await?.latest_price();
println!("Current total gas price: {}", current.total);

```

*Source:* [`crates/fuel-core/src/service.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/fuel-core/src/service.rs)

### Core Price Adjustment Algorithm

```rust
fn update_price(
    window: &mut Vec<u64>,
    exec_price: &mut u64,
    usage: u64,
    high: u64,
    low: u64,
    change_pct: f64,
) {
    // Slide window
    if window.len() == WINDOW_SIZE {
        window.remove(0);
    }
    window.push(usage);

    // Calculate average usage
    let avg: u64 = window.iter().sum::<u64>() / window.len() as u64;

    // Adjust execution price based on watermark thresholds
    if avg > high {
        *exec_price = ((*exec_price as f64) * (1.0 + change_pct)).ceil() as u64;
    } else if avg < low {
        *exec_price = ((*exec_price as f64) * (1.0 - change_pct)).floor() as u64;
    }
}

```

*Source:* [`crates/services/gas_price_service/src/v1/algorithm.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/gas_price_service/src/v1/algorithm.rs)

### DA Price Refresh Pattern

```rust
// Fetch current DA layer cost and compute DA gas price component
let da_cost_per_byte = da_source_service.current_cost_per_byte().await?;
let da_price = da_cost_per_byte * config.da_gas_per_byte;

```

*Source:* [`crates/services/gas_price_service/src/v1/da_source_service/service.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/gas_price_service/src/v1/da_source_service/service.rs)

## Summary

- The gas price service in Fuel Core runs as an asynchronous background task that updates after every block finalization.
- **Execution prices** adjust based on a sliding-window average of gas consumption, scaling up or down when usage crosses configurable high or low watermarks.
- **DA prices** synchronize with external data-availability networks, converting per-byte storage costs into per-gas fees using a fixed ratio.
- All price components are atomically persisted to `GasPriceMetadata`, ensuring nodes resume with accurate pricing after restarts.
- The implementation resides primarily in `crates/services/gas_price_service/src/v1/`, with clear separation between algorithm logic, DA integration, and storage adapters.

## Frequently Asked Questions

### How does Fuel Core determine when to increase gas prices?

The service compares the moving-average execution gas usage against a configurable high-watermark threshold. When the average exceeds this threshold, indicating network congestion, the algorithm multiplies the current execution price by `(1 + change_percent)` as defined in `gas_price_config`, typically implemented in [`algorithm.rs`](https://github.com/FuelLabs/fuel-core/blob/main/algorithm.rs).

### What is the data availability (DA) gas price component?

The DA component represents the cost to post transaction data to an external DA layer like Celestia. The gas price service queries the DA source service for the current `da_cost_per_byte`, then calculates the per-gas DA price by multiplying this value by the protocol's `da_gas_per_byte` conversion factor.

### How does the gas price service handle node restarts?

Because the service writes the latest calculated price to the `GasPriceMetadata` table atomically before broadcasting it, any node that restarts reads the most recent price from the database during initialization. This design guarantees price continuity and prevents fee market disruption across upgrades or crashes.

### Where is the gas price configuration defined?

Configuration parameters including `window_size`, `high_watermark`, `low_watermark`, `change_percent`, `min_gas_price`, and `max_gas_price` are defined in the gas price service configuration and injected during node startup in [`crates/fuel-core/src/service/sub_services.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/fuel-core/src/service/sub_services.rs), allowing operators to tune the fee market responsiveness for their specific network conditions.