# eth_syncing - Arbitrum RPC Method

Returns the sync status of your Arbitrum node - either `false` when fully synced, or an object describing the sync progress.

> **Why Arbitrum?** Build on Ethereum's leading Layer 2 with 46% L2 market share and $12B+ TVL with full EVM compatibility, 1.5M daily transactions, and $3B+ DAO treasury for ecosystem growth.

## When to Use This Method

`eth_syncing` is essential for DeFi developers, protocol teams, and dApp builders seeking Ethereum scalability:

- **Node Health Checks** - Verify your node is fully synced before processing transactions
- **Sync Progress Monitoring** - Track how far behind your node is during initial sync or after downtime
- **Load Balancer Routing** - Route requests only to fully synced nodes in multi-node setups
- **dApp Reliability** - Display sync warnings to users when data may be stale

## Request Parameters

This method accepts no parameters.

## Request Example

```json
{
  "jsonrpc": "2.0",
  "method": "eth_syncing",
  "params": [],
  "id": 1
}
```

## Response Fields

- `startingBlock` (`QUANTITY, required`): Block number where sync started
- `currentBlock` (`QUANTITY, required`): Current block being processed
- `highestBlock` (`QUANTITY, required`): Estimated highest block

## Successful Response

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": false
}
```

## Code Examples

cURL
JavaScript
Python
Go

```bash
curl -X POST https://api-arbitrum-mainnet-archive.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_syncing",
    "params": [],
    "id": 1
  }'
```

```javascript
import { JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://api-arbitrum-mainnet-archive.n.dwellir.com/YOUR_API_KEY');

const syncing = await provider.send('eth_syncing', []);

if (syncing === false) {
  console.log('Arbitrum node is fully synced');
} else {
  const current = parseInt(syncing.currentBlock, 16);
  const highest = parseInt(syncing.highestBlock, 16);
  const progress = ((current / highest) * 100).toFixed(2);
  console.log(`Syncing: ${progress}% (block ${current} / ${highest})`);
}
```

```python
from web3 import Web3

w3 = Web3(Web3.HTTPProvider('https://api-arbitrum-mainnet-archive.n.dwellir.com/YOUR_API_KEY'))

sync_status = w3.eth.syncing

if sync_status is False:
    print('Arbitrum node is fully synced')
else:
    current = sync_status['currentBlock']
    highest = sync_status['highestBlock']
    progress = (current / highest) * 100
    print(f'Syncing: {progress:.2f}% (block {current} / {highest})')
```

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
    client, err := ethclient.Dial("https://api-arbitrum-mainnet-archive.n.dwellir.com/YOUR_API_KEY")
    if err != nil {
        log.Fatal(err)
    }

    progress, err := client.SyncProgress(context.Background())
    if err != nil {
        log.Fatal(err)
    }

    if progress == nil {
        fmt.Println("Arbitrum node is fully synced")
    } else {
        fmt.Printf("Syncing: block %d / %d\n", progress.CurrentBlock, progress.HighestBlock)
    }
}
```

## Common Use Cases

### 1. Node Health Monitor

Continuously check sync status and alert on issues:

```javascript
async function monitorNodeHealth(provider, interval = 30000) {
  setInterval(async () => {
    const syncing = await provider.send('eth_syncing', []);

    if (syncing === false) {
      const blockNumber = await provider.getBlockNumber();
      const block = await provider.getBlock(blockNumber);
      const age = Date.now() / 1000 - block.timestamp;

      if (age > 60) {
        console.warn(`Node synced but block is ${age.toFixed(0)}s old`);
      } else {
        console.log(`Healthy - block ${blockNumber}`);
      }
    } else {
      const current = parseInt(syncing.currentBlock, 16);
      const highest = parseInt(syncing.highestBlock, 16);
      console.warn(`Syncing: ${highest - current} blocks behind`);
    }
  }, interval);
}
```

### 2. Wait for Sync Before Processing

Block application startup until the node is ready:

```javascript
async function waitForSync(provider, pollInterval = 5000) {
  while (true) {
    const syncing = await provider.send('eth_syncing', []);

    if (syncing === false) {
      console.log('Node synced - ready to process transactions');
      return;
    }

    const current = parseInt(syncing.currentBlock, 16);
    const highest = parseInt(syncing.highestBlock, 16);
    console.log(`Waiting for sync: ${highest - current} blocks remaining...`);
    await new Promise(r => setTimeout(r, pollInterval));
  }
}
```

## Best Practices

- Poll `eth_syncing` at application startup and block all transaction operations until `false` is returned
- Check both the sync status AND the latest block timestamp age -- a node can report synced but still have stale data
- In multi-node setups, route read requests to synced nodes and avoid sending transactions to nodes still catching up
- For long-running services, implement a health check that raises alerts if the sync gap exceeds a threshold
- Some client implementations return a sync object with additional fields like `knownStates` and `pulledStates` during state sync

## Related Methods

- [`eth_blockNumber`](https://www.dwellir.com/docs/arbitrum/eth_blockNumber) - Get current block height
- [`net_peerCount`](https://www.dwellir.com/docs/arbitrum/net_peerCount) - Check peer connections
- [`net_listening`](https://www.dwellir.com/docs/arbitrum/net_listening) - Verify node is accepting connections
- [`web3_clientVersion`](https://www.dwellir.com/docs/arbitrum/web3_clientVersion) - Get node client info
