Skip to main content

Get your own node endpoint today

Start for free and get your app to production levels immediately. No credit card required.You can sign up with your GitHub, X, Google, or Microsoft account.

Parameters

  • string — a keyword identifying the type of event to subscribe to, logs in this case.
  • function — (optional) a callback function that will be called every time a new event of the specified type is received. This function takes two parameters: error and result. The error parameter contains any error that occurred while subscribing to the event, and the result parameter contains the data for the event that was received.

Response

  • object — the following sync object when the node is currently syncing:
    • startingBlock — the block number from which the node began syncing.
    • currentBlock — the latest block number the node has synced to.
    • highestBlock — the estimated highest block number that needs to be synced.
    • pulledStates — the number of state entries that have already been downloaded.
    • knownStates — the estimated number of state entries to be downloaded during the sync.
  • boolean — returns False when the node is already in sync.

subscribe("syncing") code example

Note that ethers.js subscriptions require a WebSocket connection.
Use a WebSocketProvider and the provider event listeners to react to sync status updates:
  • provider.send("eth_syncing", []) — queries the current sync status on demand.
  • provider.on("block", ...) — activates for each new block, so you can re-check the sync status in real time.
  • provider.on("error", ...) — activates if an error is detected on the connection.
  • provider.destroy() — closes the connection and removes all listeners.
const { ethers } = require("ethers");
const NODE_URL = "CHAINSTACK_WSS_URL";
const provider = new ethers.WebSocketProvider(NODE_URL);

async function subscribeToSync() {
    try {
        // Log the initial sync status on connection
        const status = await provider.send("eth_syncing", []);
        handleConnected(status);

        // Re-check the sync status on every new block
        provider.on("block", handleSync);

        // React to connection errors
        provider.on("error", handleError);

    } catch (error) {
        console.error(`Error subscribing to sync: ${error}`);
    }
}

/* Fallback functions to react to the different events */

// Event listener that logs the initial sync status
function handleConnected(status) {
    console.log(`Initial sync status: ${JSON.stringify(status)}`);
}

// Event listener that logs the current sync status
async function handleSync() {
    const status = await provider.send("eth_syncing", []);
    console.log(status);
}

// Event listener that logs any errors that occur
function handleError(error) {
    console.error(`Error: ${error}`);
}

subscribeToSync();

Use case

A practical use case for subscribe("syncing") is a DApp that continuously listens for the status of a node and notifies the developer if the node falls behind a certain number of blocks. The following is an implementation of this concept using ethers.js subscriptions, this program will leave a notification in the console if the node falls more than 100 blocks behind.
const { ethers } = require("ethers");
const NODE_URL = "CHAINSTACK_WSS_URL";
const provider = new ethers.WebSocketProvider(NODE_URL);

async function subscribeToSync() {
    try {
        // Log the initial sync status on connection
        handleConnected();

        // Re-check the sync status on every new block
        provider.on("block", handleSync);

        // React to connection errors
        provider.on("error", handleError);

    } catch (error) {
        console.error(`Error: ${error}`);
    }
}

/* Fallback functions to react to the different events */

// Event listener that logs a message when the connection is ready
function handleConnected() {
    console.log("Subscribed to sync status updates.");
}

// Event listener that compares the current and highest blocks
async function handleSync() {
    const status = await provider.send("eth_syncing", []);

    // eth_syncing returns false when the node is already in sync
    if (status === false) {
      console.log("The node is in sync with the network.");
      return;
    }

    const currentBlock = Number(status.currentBlock);
    const highestBlock = Number(status.highestBlock);

    if (!Number.isNaN(currentBlock) && !Number.isNaN(highestBlock)) {
      const blocksBehind = highestBlock - currentBlock;
      console.log(`The node is ${blocksBehind} blocks behind the network.`);

      if (blocksBehind > 1000) {
        alert(`The node is ${blocksBehind} blocks behind the network. Please check your connection.`);
      }
    }
  }

// Event listener that logs any errors that occur
function handleError(error) {
    console.error(`Error receiving new blocks: ${error}`);
}

subscribeToSync();
This code monitors the sync status over a WebSocket connection using a WebSocketProvider. It listens for new blocks with provider.on("block", ...) and queries the current sync status on each block with provider.send("eth_syncing", []). The code defines three event listener functions that are attached to the provider: handleConnected, handleSync, and handleError. The handleConnected function is called when the connection is ready, and it logs a message. The handleSync function is called on every new block, reads the currentBlock and the highestBlock fields from the eth_syncing result, and then compares them. If the node is more than 1,000 blocks behind, the user will receive an alert. The handleError function is called when an error occurs, and it logs an error message. Finally, the code calls the subscribeToSync function, which attaches the event listeners. When a new block is received, the handleSync function is called to query the sync status and log it to the console.
Last modified on June 25, 2026