> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livepeer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitor a Livepeer Gateway on Docker, Linux, or Windows

> Set up production monitoring for a Livepeer Gateway - Prometheus, Grafana, log monitoring, Explorer, and automated alerts on Docker, Linux, or Windows.

export const linuxGroup = () => <div style={{
  display: 'flex',
  gap: '0.5rem',
  alignItems: 'center',
  marginBottom: '1rem'
}}>
    <span>
      <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
    </span>
    <span>
      <Icon icon="apple" color="#60ba47" size={22} /> <Badge> macOS </Badge>
    </span>
  </div>;

export const dockerGroup = () => <div style={{
  display: 'flex',
  gap: '0.5rem',
  alignItems: 'center',
  marginBottom: '1rem'
}}>
    <span>
      <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
    </span>
    <span>
      <Icon icon="windows" color="#0078d6" size={22} /> <Badge> Windows </Badge>
    </span>
    <span>
      <Icon icon="apple" color="#60ba47" size={22} /> <Badge> macOS </Badge>
    </span>
  </div>;

export const docker = () => <span>
    <Icon icon="docker" color="#2496ed" size={22} /> <Badge> Docker </Badge>
  </span>;

export const windows = () => <span>
    <Icon icon="windows" color="#0078d6" size={22} /> <Badge> Windows </Badge>
  </span>;

export const linux = () => <span>
    <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
  </span>;

export const dual = () => <Badge color="green">Dual-mode</Badge>;

export const ai = () => <Badge color="purple">AI</Badge>;

export const video = () => <Badge color="blue">Video</Badge>;

export const StyledStep = ({title, icon, titleSize = 'h3', iconColor = null, titleColor = null, children, className = '', style = {}, ...rest}) => {
  const styledTitle = titleColor ? <span style={{
    color: titleColor
  }}>{title}</span> : title;
  return <Step title={styledTitle} icon={icon} iconColor={iconColor || undefined} titleSize={titleSize} className={className} style={style} {...rest}>
      {children}
    </Step>;
};

export const StyledSteps = ({children, iconColor, titleColor, lineColor, iconSize = '24px', className = '', style = {}, ...rest}) => {
  const resolvedIconColor = iconColor || 'var(--accent-dark, #18794E)';
  const resolvedTitleColor = titleColor || 'var(--lp-color-accent)';
  const resolvedLineColor = lineColor || 'var(--lp-color-accent)';
  return <div className={['docs-styled-steps', className].filter(Boolean).join(' ')} style={style} {...rest}>
      <style>{`
        .docs-styled-steps .steps > div > div.absolute > div {
          background-color: ${resolvedIconColor};
        }
        .docs-styled-steps .steps > div > div.w-full > p {
          color: ${resolvedTitleColor};
        }
        .docs-styled-steps .steps > div > div.absolute.w-px {
          background-color: ${resolvedLineColor};
        }
        .docs-styled-steps .steps > div:last-child > div.absolute.w-px::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 50%;
          transform: translateX(-50%);
          width: 6px;
          height: 6px;
          background-color: ${resolvedLineColor};
          transform: translateX(-50%) rotate(45deg);
        }
      `}</style>
      <div>
        <Steps>{children}</Steps>
      </div>
    </div>;
};

export const TableCell = ({children, align = "left", header = false, style = {}, className = "", ...rest}) => {
  const Component = header ? "th" : "td";
  return <Component className={className} style={{
    padding: "0.75rem 1rem",
    textAlign: align,
    border: header ? "none" : "1px solid var(--lp-color-border-default)",
    ...style
  }} {...rest}>
      {children}
    </Component>;
};

export const TableRow = ({children, header = false, hover = false, style = {}, className = "", ...rest}) => {
  const rowId = `table-row-${Math.random().toString(36).substr(2, 9)}`;
  return <>
      {hover && <style>{`
          #${rowId}:hover {
            background-color: var(--lp-color-bg-card);
          }
        `}</style>}
      <tr id={rowId} className={className} style={{
    ...header && ({
      backgroundColor: "var(--lp-color-accent-strong)",
      color: "var(--lp-color-on-accent)",
      fontWeight: "bold"
    }),
    ...style
  }} {...rest}>
        {children}
      </tr>
    </>;
};

export const StyledTable = ({children, variant = "default", style = {}, className = "", ...rest}) => {
  const wrapperVariants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)",
      overflow: "hidden"
    },
    bordered: {
      border: "2px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-page)",
      overflow: "hidden"
    },
    minimal: {
      border: "none",
      backgroundColor: "transparent",
      overflow: "visible"
    }
  };
  return <div data-docs-styled-table-shell className={className} style={{
    width: "100%",
    padding: 0,
    margin: 0,
    ...wrapperVariants[variant],
    ...style
  }} {...rest}>
      <table data-docs-styled-table style={{
    width: "100%",
    borderCollapse: "collapse",
    borderSpacing: 0,
    margin: 0,
    backgroundColor: "transparent"
  }}>
        {children}
      </table>
    </div>;
};

export const BorderedBox = ({children, variant = "default", padding = "var(--lp-spacing-4)", borderRadius = "var(--lp-spacing-px-8)", margin = "", accentBar = "", style = {}, className = "", ...rest}) => {
  const variants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    accent: {
      border: "1px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    muted: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "transparent"
    }
  };
  const accentBarColors = {
    accent: "var(--lp-color-accent)",
    positive: "var(--green-9)"
  };
  return <div data-docs-bordered-box="" data-accent-bar={accentBarColors[accentBar] ? "" : undefined} className={className} style={{
    ...variants[variant],
    padding: padding,
    borderRadius: borderRadius,
    ...margin ? {
      margin
    } : {},
    ...accentBarColors[accentBar] ? {
      position: "relative",
      '--accent-bar-color': accentBarColors[accentBar]
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

export const LinkArrow = ({href, label, description, newline = true, borderColor, className = '', style = {}, ...rest}) => {
  const linkArrowStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: "var(--lp-spacing-1)",
    width: 'fit-content',
    ...borderColor && ({
      borderColor
    })
  };
  return <span className={className} style={style} {...rest}>
      {newline && <br />}
      <span style={linkArrowStyle}>
        <a href={href} target="_blank" rel="noopener noreferrer">
          {label}
        </a>
        <Icon icon="arrow-up-right" size={14} color="var(--lp-color-accent)" />
      </span>
      {description && description}
      {description && <div style={{
    height: "var(--lp-spacing-3)"
  }} />}
    </span>;
};

<CustomDivider style={{margin: "0 0 -1rem 0"}} />

# <Icon icon="chart-line" size={26} /> Production Monitoring

This guide sets up ongoing observability for a Livepeer Gateway running in production. It covers Prometheus metrics collection, Grafana dashboards, log monitoring, the Livepeer Explorer, and automated health alerts.

*This guide includes:*

* Monitoring setup for {video()}, {ai()} Pipelines and {dual()} service routing
* Installation guides for {Docker()} ***(recommended)***, {linux()}, and {windows()}

<Tip>
  This page is about **ongoing production monitoring** - watching the Gateway over time with metrics, dashboards, and alerts.
  For one-time verification that the Gateway started correctly, see the verify step in the setup journey.
</Tip>

<CustomDivider />

<BorderedBox>
  <Tabs>
    <Tab title="Docker" icon="docker">
      ## <Icon icon="docker" iconType="solid" size={32} /> Docker Monitoring Guide

      {dockerGroup()}

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Enable Metrics">
          Add the `-monitor` flag to the Gateway's Docker Compose command block. Without it, the `/metrics` endpoint is not exposed.

          ```yaml icon="docker" docker-compose.yml theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          services:
            gateway:
              image: livepeer/go-livepeer:master
              container_name: "gateway"
              ports:
                - 8935:8935
                - 5935:5935
              command:
                - "-gateway"
                - "-monitor"
                - "-metricsPerStream"
                - "-httpAddr=0.0.0.0:8935"
                # ... Other flags
          ```

          **Monitoring flags:**

          <StyledTable>
            <TableRow header>
              <TableCell header>Flag</TableCell>
              <TableCell header>Purpose</TableCell>
              <TableCell header>Recommendation</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-monitor`</TableCell>
              <TableCell>Enables the `/metrics` Prometheus endpoint</TableCell>
              <TableCell>Always enable in production</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-metricsPerStream`</TableCell>
              <TableCell>Groups metrics by individual stream</TableCell>
              <TableCell>Enable for per-stream debugging; increases metric cardinality</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-metricsClientIP`</TableCell>
              <TableCell>Includes client IP as a metric label</TableCell>
              <TableCell>Enable only for per-client breakdown</TableCell>
            </TableRow>
          </StyledTable>

          Verify metrics are exposed:

          ```bash icon="terminal" Verify Metrics theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl http://localhost:8935/metrics | head -30
          ```

          Prometheus-format output with `livepeer_` prefixed metric names confirms the endpoint is active.
        </StyledStep>

        <StyledStep title="Prometheus and Grafana">
          The `livepeer/livepeer-monitoring` repository bundles Prometheus, Grafana, and starter dashboard templates in a single Docker deployment.

          ```bash icon="terminal" Start Monitoring Stack theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          git clone https://github.com/livepeer/livepeer-monitoring
          cd livepeer-monitoring
          docker compose up -d
          ```

          The stack starts:

          * **Prometheus** on port `9090` - scraping the Gateway at `localhost:8935`
          * **Grafana** on port `3000` - default credentials `admin / admin`

          Update `prometheus.yml` in the repository to point to the Gateway host if it is not on `localhost`. When the Gateway runs in a Docker container, use the container name or Docker network address instead of `localhost`:

          ```yaml icon="terminal" prometheus.yml theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          scrape_configs:
            - job_name: 'livepeer-gateway'
              static_configs:
                - targets: ['gateway:8935']
              metrics_path: '/metrics'
              scrape_interval: 15s
              labels:
                node_type: 'dual'
                environment: 'production'
          ```

          <Tip>
            Ensure both the monitoring stack and the Gateway container are on the same Docker network so Prometheus can reach the Gateway's metrics endpoint.
          </Tip>

          **Enhanced monitoring flags** can be added to the Gateway's Docker Compose command:

          ```yaml icon="docker" Additional Compose Flags theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          command:
            # ... Existing flags
            - "-metricsPerStream=true"
            - "-metricsClientIP=true"
          ```
        </StyledStep>

        <StyledStep title="Log Monitoring">
          Monitor Gateway logs in real time:

          ```bash icon="terminal" Follow Logs theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          docker logs -f gateway
          ```

          Enable verbose logging by adding `-v=6` to the Docker Compose command block. Key log events to watch:

          * `Received live video AI request` - AI job arrived
          * `Orchestrator selected` - routing decision made
          * `Transcoding completed` - job finished
          * Payment processing events

          Save logs to a file for later analysis:

          ```bash icon="terminal" Save Logs theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          docker logs gateway > gateway.log 2>&1
          ```
        </StyledStep>

        <StyledStep title="Automated Health Notifications">
          Add a `HEALTHCHECK` to the Docker Compose service definition or Dockerfile to let Docker monitor the Gateway process:

          ```yaml icon="docker" docker-compose.yml theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          services:
            gateway:
              # ... Existing config
              healthcheck:
                test: ["CMD", "curl", "--silent", "--fail", "http://localhost:8935/health"]
                interval: 30s
                timeout: 10s
                retries: 3
          ```

          Docker marks the container as `unhealthy` after three consecutive failures. Combine with a restart policy:

          ```yaml icon="docker" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          restart: unless-stopped
          ```

          For email or webhook alerts, use the Prometheus alert rules described below the tabs on this page.
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Troubleshooting" icon="triangle-exclamation" href="/v2/gateways/guides/monitoring-and-tooling/troubleshooting" horizontal arrow>
        Fix common Gateway errors by symptom
      </Card>
    </Tab>

    <Tab title="Linux" icon="linux">
      ## <Icon icon="linux" iconType="solid" size={32} /> Linux Monitoring Guide

      {linuxGroup()}

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Enable Metrics">
          Add the `-monitor` flag when starting the Gateway. Without it, the `/metrics` endpoint is not exposed.

          ```bash icon="terminal" Start with Monitoring theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          ./livepeer \
            -gateway \
            -monitor \
            -metricsPerStream \
            -httpAddr 0.0.0.0:8935 \
            [other flags...]
          ```

          If the Gateway runs as a **systemd service**, add `-monitor` to the `ExecStart` line:

          ```ini icon="terminal" /etc/systemd/system/livepeer.service theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          [Unit]
          Description=Livepeer Gateway

          [Service]
          Type=simple
          User=livepeer
          Restart=always
          RestartSec=4
          ExecStart=/usr/local/bin/livepeer \
            -gateway \
            -monitor \
            -metricsPerStream \
            -httpAddr=0.0.0.0:8935 \
            -v 6

          [Install]
          WantedBy=default.target
          ```

          ```bash icon="terminal" Reload and Restart theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          sudo systemctl daemon-reload
          sudo systemctl restart livepeer
          ```

          **Monitoring flags:**

          <StyledTable>
            <TableRow header>
              <TableCell header>Flag</TableCell>
              <TableCell header>Purpose</TableCell>
              <TableCell header>Recommendation</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-monitor`</TableCell>
              <TableCell>Enables the `/metrics` Prometheus endpoint</TableCell>
              <TableCell>Always enable in production</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-metricsPerStream`</TableCell>
              <TableCell>Groups metrics by individual stream</TableCell>
              <TableCell>Enable for per-stream debugging; increases metric cardinality</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-metricsClientIP`</TableCell>
              <TableCell>Includes client IP as a metric label</TableCell>
              <TableCell>Enable only for per-client breakdown</TableCell>
            </TableRow>
          </StyledTable>

          Verify metrics are exposed:

          ```bash icon="terminal" Verify Metrics theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl http://localhost:8935/metrics | head -30
          ```

          Prometheus-format output with `livepeer_` prefixed metric names confirms the endpoint is active.
        </StyledStep>

        <StyledStep title="Prometheus Setup">
          Install Prometheus via the package manager or download the binary.

          **Ubuntu/Debian:**

          ```bash icon="terminal" Install Prometheus theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          sudo apt update && sudo apt install -y prometheus
          ```

          **Binary (any distro):**

          ```bash icon="terminal" Download Prometheus theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          wget https://github.com/prometheus/prometheus/releases/latest/download/prometheus-*.linux-amd64.tar.gz
          tar xvfz prometheus-*.linux-amd64.tar.gz
          cd prometheus-*
          ```

          Create or update `/etc/prometheus/prometheus.yml` to scrape the Gateway:

          ```yaml icon="terminal" prometheus.yml theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          global:
            scrape_interval: 15s
            evaluation_interval: 15s

          scrape_configs:
            - job_name: 'livepeer-gateway'
              static_configs:
                - targets: ['localhost:8935']
              metrics_path: '/metrics'
              scrape_interval: 15s
              scrape_timeout: 10s
              labels:
                node_type: 'dual'
                environment: 'production'
          ```

          Adjust the `node_type` label to match the deployment: `video`, `ai`, or `dual`.

          ```bash icon="terminal" Start Prometheus theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          sudo systemctl enable --now prometheus
          ```

          Prometheus runs on port `9090` by default. Confirm the Gateway target appears at `http://localhost:9090/targets`.
        </StyledStep>

        <StyledStep title="Grafana Setup">
          **Ubuntu/Debian:**

          ```bash icon="terminal" Install Grafana theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          sudo apt install -y apt-transport-https software-properties-common
          wget -q -O - https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/grafana.gpg
          echo "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
          sudo apt update && sudo apt install -y grafana
          sudo systemctl enable --now grafana-server
          ```

          Access Grafana at `http://localhost:3000` (default credentials `admin / admin`).

          **Add Prometheus as a data source:**

          1. Navigate to **Configuration > Data Sources > Add data source**
          2. Select **Prometheus**
          3. Set the URL to `http://localhost:9090`
          4. Click **Save & Test**

          Import the Livepeer starter dashboards from the `livepeer/livepeer-monitoring` repository, or build custom panels using the metrics described below the tabs on this page.
        </StyledStep>

        <StyledStep title="Log Monitoring">
          If the Gateway runs as a **systemd service**, use `journalctl`:

          ```bash icon="terminal" Follow Logs theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          journalctl -u livepeer -f
          ```

          If running the binary directly, pipe output to a log file:

          ```bash icon="terminal" Log to File theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          ./livepeer -gateway -monitor [flags] 2>&1 | tee /var/log/livepeer-gateway.log
          ```

          Enable verbose logging with `-v 6`. Key log events to watch:

          * `Received live video AI request` - AI job arrived
          * `Orchestrator selected` - routing decision made
          * `Transcoding completed` - job finished
          * Payment processing events
        </StyledStep>

        <StyledStep title="Automated Health Notifications">
          Create a health check script that runs on a schedule via cron:

          ```bash icon="terminal" /usr/local/bin/gateway-health.sh theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          #!/usr/bin/env bash
          # gateway-health.sh - run every 5 minutes via cron
          GATEWAY_PORT="${1:-8935}"
          ALERT_EMAIL="ops@example.com"

          if ! curl --silent --fail --max-time 5 \
            http://localhost:${GATEWAY_PORT}/health > /dev/null 2>&1; then
            echo "Gateway on port ${GATEWAY_PORT} is not responding" | \
              mail -s "ALERT: Livepeer Gateway Down" "$ALERT_EMAIL"
          fi
          ```

          ```bash icon="terminal" Add to Crontab theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          chmod +x /usr/local/bin/gateway-health.sh
          # Add to crontab
          (crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/gateway-health.sh 8935") | crontab -
          ```

          For richer alerting (Slack, PagerDuty, webhook), configure Prometheus Alertmanager with the alert rules described below the tabs on this page.
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Troubleshooting" icon="triangle-exclamation" href="/v2/gateways/guides/monitoring-and-tooling/troubleshooting" horizontal arrow>
        Fix common Gateway errors by symptom
      </Card>
    </Tab>

    <Tab title="Windows" icon="windows">
      ## <Icon icon="windows" iconType="brands" size={32} /> Windows Monitoring Guide

      <Badge color="blue">Video Only</Badge> <Icon icon="windows" />

      <Note>
        The AI Gateway binary is not available for Windows. For AI or Dual monitoring on Windows, use <LinkArrow href="/v2/gateways/setup/install" label="Docker via WSL2" newline={false} /> and follow the Docker tab instead.
      </Note>

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Enable Metrics">
          Add `-monitor=true` to the Gateway `.bat` file or startup command. Without it, the `/metrics` endpoint is not exposed.

          ```batch icon="terminal" gateway.bat theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          livepeer.exe ^
            -gateway ^
            -monitor=true ^
            -metricsPerStream=true ^
            -httpAddr=0.0.0.0:8935 ^
            -v=6
          PAUSE
          ```

          **Monitoring flags:**

          <StyledTable>
            <TableRow header>
              <TableCell header>Flag</TableCell>
              <TableCell header>Purpose</TableCell>
              <TableCell header>Recommendation</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-monitor`</TableCell>
              <TableCell>Enables the `/metrics` Prometheus endpoint</TableCell>
              <TableCell>Always enable in production</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-metricsPerStream`</TableCell>
              <TableCell>Groups metrics by individual stream</TableCell>
              <TableCell>Enable for per-stream debugging; increases metric cardinality</TableCell>
            </TableRow>

            <TableRow>
              <TableCell>`-metricsClientIP`</TableCell>
              <TableCell>Includes client IP as a metric label</TableCell>
              <TableCell>Enable only for per-client breakdown</TableCell>
            </TableRow>
          </StyledTable>

          Verify metrics are exposed (PowerShell):

          ```powershell icon="terminal" Verify Metrics theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          Invoke-WebRequest -Uri http://localhost:8935/metrics | Select-Object -First 30
          ```

          Or via WSL2:

          ```bash icon="terminal" Verify Metrics (WSL2) theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl http://localhost:8935/metrics | head -30
          ```

          Prometheus-format output with `livepeer_` prefixed metric names confirms the endpoint is active.
        </StyledStep>

        <StyledStep title="Prometheus Setup">
          Download the Prometheus Windows binary from the [Prometheus releases page](https://github.com/prometheus/prometheus/releases).

          1. Extract the archive to a directory (e.g. `C:\prometheus\`)
          2. Create or update `prometheus.yml` in that directory:

          ```yaml icon="terminal" prometheus.yml theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          global:
            scrape_interval: 15s
            evaluation_interval: 15s

          scrape_configs:
            - job_name: 'livepeer-gateway'
              static_configs:
                - targets: ['localhost:8935']
              metrics_path: '/metrics'
              scrape_interval: 15s
              scrape_timeout: 10s
              labels:
                node_type: 'video'
                environment: 'production'
          ```

          3. Start Prometheus:

          ```powershell icon="terminal" Start Prometheus theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          cd C:\prometheus
          .\prometheus.exe --config.file=prometheus.yml
          ```

          Prometheus runs on port `9090` by default. Confirm the Gateway target appears at `http://localhost:9090/targets`.

          <Tip>
            To run Prometheus as a Windows service, use [NSSM](https://nssm.cc/):

            ```powershell icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            nssm install Prometheus C:\prometheus\prometheus.exe --config.file=C:\prometheus\prometheus.yml
            nssm start Prometheus
            ```
          </Tip>
        </StyledStep>

        <StyledStep title="Grafana Setup">
          Download the Grafana Windows installer from the [Grafana downloads page](https://grafana.com/grafana/download?platform=windows).

          Run the installer and start the Grafana service. Access Grafana at `http://localhost:3000` (default credentials `admin / admin`).

          **Add Prometheus as a data source:**

          1. Navigate to **Configuration > Data Sources > Add data source**
          2. Select **Prometheus**
          3. Set the URL to `http://localhost:9090`
          4. Click **Save & Test**

          Import the Livepeer starter dashboards from the `livepeer/livepeer-monitoring` repository, or build custom panels using the metrics described below the tabs on this page.
        </StyledStep>

        <StyledStep title="Log Monitoring">
          If running via `.bat` file, the console window displays logs in real time.

          Redirect output to a log file for later analysis:

          ```batch icon="terminal" gateway-with-logs.bat theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          livepeer.exe -gateway -monitor=true -v=6 > gateway.log 2>&1
          ```

          Key log events to watch:

          * `Orchestrator selected` - routing decision made
          * `Transcoding completed` - job finished
          * Payment processing events

          **Process monitoring:**

          Check if the Gateway is running via Task Manager or PowerShell:

          ```powershell icon="terminal" Check Process theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          Get-Process livepeer -ErrorAction SilentlyContinue
          ```

          Check port availability:

          ```powershell icon="terminal" Check Port theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          netstat -ano | findstr :8935
          ```
        </StyledStep>

        <StyledStep title="Automated Health Notifications">
          Use Windows Task Scheduler to run a health check script on a schedule.

          Create `gateway-health.ps1`:

          ```powershell icon="terminal" gateway-health.ps1 theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          $port = 8935
          try {
              $response = Invoke-WebRequest -Uri "http://localhost:$port/health" `
                -TimeoutSec 5 -ErrorAction Stop
              if ($response.StatusCode -ne 200) { throw "Non-200 response" }
          } catch {
              # Replace with your preferred notification method
              Write-EventLog -LogName Application -Source "Livepeer" `
                -EventId 1001 -EntryType Error `
                -Message "Livepeer Gateway on port $port is not responding"
          }
          ```

          **Add to Task Scheduler:**

          1. Open Task Scheduler and select **Create Basic Task**
          2. Set a trigger to run every 5 minutes
          3. Set the action to run `powershell.exe -File C:\path\to\gateway-health.ps1`

          For richer alerting (Slack, PagerDuty, webhook), configure Prometheus Alertmanager with the alert rules described below the tabs on this page.
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Troubleshooting" icon="triangle-exclamation" href="/v2/gateways/guides/monitoring-and-tooling/troubleshooting" horizontal arrow>
        Fix common Gateway errors by symptom
      </Card>
    </Tab>
  </Tabs>
</BorderedBox>

<CustomDivider />

## Livepeer Explorer

The [Livepeer Explorer](https://explorer.livepeer.org/gateways) provides a network-level view of all registered Gateways on Arbitrum One. It is accessible from any OS and requires no local installation.

<iframe src="https://explorer.livepeer.org/gateways" height="600px" width="100%" style={{marginTop: "1rem", borderRadius: "8px", border: "1px solid var(--border)"}} title="Livepeer Gateway Explorer" />

### Explorer columns

The Gateway Explorer table displays the following for each registered Gateway:

<StyledTable>
  <TableRow header>
    <TableCell header>Column</TableCell>
    <TableCell header>What it shows</TableCell>
    <TableCell header>Why it matters</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Address**</TableCell>
    <TableCell>The Gateway's Ethereum wallet address on Arbitrum</TableCell>
    <TableCell>Search for this address to confirm the Gateway is registered on-chain. Matches the ETH Account shown in `livepeer_cli` Option 1</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Deposit**</TableCell>
    <TableCell>ETH locked in the TicketBroker contract as the Gateway's working balance (in ETH)</TableCell>
    <TableCell>When this reaches zero, job routing stops silently. Compare against the `livepeer_gateway_deposit` Prometheus metric to verify node-reported values match chain state</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Reserve**</TableCell>
    <TableCell>ETH held in reserve for ticket redemption (in ETH)</TableCell>
    <TableCell>Required for Orchestrators to redeem winning tickets. If zero, Orchestrators reject payment tickets and jobs fail</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Total Volume**</TableCell>
    <TableCell>Cumulative ETH volume processed by the Gateway since first activation</TableCell>
    <TableCell>Indicates the Gateway's lifetime throughput. Useful for benchmarking against other operators on the network</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**90-Day Volume**</TableCell>
    <TableCell>ETH volume processed in the last 90 days</TableCell>
    <TableCell>Shows recent activity level. A Gateway with high total volume but zero 90-day volume is inactive</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**First Active**</TableCell>
    <TableCell>Date the Gateway first appeared on-chain</TableCell>
    <TableCell>Indicates operator tenure on the network</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Last Active**</TableCell>
    <TableCell>Date of the Gateway's most recent on-chain activity</TableCell>
    <TableCell>Confirms the Gateway is still operational. A stale date indicates the node may be offline or the deposit is exhausted</TableCell>
  </TableRow>
</StyledTable>

<Tip>
  After registering an on-chain Gateway, it may take a few minutes to appear in the Explorer. Search by the ETH address shown in `livepeer_cli` Option 1 (under **BROADCASTER STATS**).
</Tip>

For off-chain Gateways, the Explorer does not show the node directly. Use <LinkArrow href="https://tools.livepeer.cloud" label="Livepeer Tools" newline={false} /> for network-wide AI Orchestrator visibility instead.

<CardGroup cols={2}>
  <Card title="Gateway Explorer" icon="gauge-high" href="https://explorer.livepeer.org/gateways">
    View registered Gateways, deposit balances, and network activity on Arbitrum.
  </Card>

  <Card title="Livepeer Tools" icon="chart-line" href="https://tools.livepeer.cloud">
    Community dashboard for Gateway performance metrics and AI Orchestrator status.
  </Card>
</CardGroup>

<CustomDivider />

## Key Metrics Reference

All Gateway types (Video, AI, Dual) expose metrics on the same `-httpAddr` port (default 8935). A single Prometheus scrape job covers all workload types.

Full metric table: <LinkArrow href="/v2/gateways/resources/reference/technical/go-livepeer/prometheus-metrics" label="Prometheus Metrics Reference" newline={false} />

<BorderedBox variant="accent">
  <Tabs>
    <Tab title="Video" icon="video">
      <Badge color="blue">Video</Badge> - on-chain Gateways.

      **Performance metrics:**

      <StyledTable>
        <TableRow header>
          <TableCell header>Metric</TableCell>
          <TableCell header>What it shows</TableCell>
          <TableCell header>Alert threshold</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_segment_transcoded_total`</TableCell>
          <TableCell>Successfully transcoded segments (counter)</TableCell>
          <TableCell>Calculate success rate (see queries below)</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_transcode_overall_latency_seconds`</TableCell>
          <TableCell>End-to-end transcoding latency</TableCell>
          <TableCell>Alert when avg `> 5s`</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_segment_transcode_failed_total`</TableCell>
          <TableCell>Cumulative failed transcode count</TableCell>
          <TableCell>Alert on rate increase</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_current_sessions_total`</TableCell>
          <TableCell>Active transcoding sessions</TableCell>
          <TableCell>Capacity planning</TableCell>
        </TableRow>
      </StyledTable>

      **Payment metrics:**

      <StyledTable>
        <TableRow header>
          <TableCell header>Metric</TableCell>
          <TableCell header>What it shows</TableCell>
          <TableCell header>Alert threshold</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_gateway_deposit`</TableCell>
          <TableCell>Remaining ETH deposit (wei)</TableCell>
          <TableCell>Alert when `< 0.01 ETH`</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_gateway_reserve`</TableCell>
          <TableCell>Remaining ETH reserve (wei)</TableCell>
          <TableCell>Alert when `< 0.005 ETH`</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_payment_create_errors`</TableCell>
          <TableCell>Failed ticket creation</TableCell>
          <TableCell>Alert on any increase</TableCell>
        </TableRow>
      </StyledTable>

      <Warning>
        When the deposit reaches zero, job routing stops immediately with no warning to clients.
        Monitor `livepeer_gateway_deposit` proactively.
      </Warning>

      **Useful queries:**

      ```promql icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
      # Success rate over last 5 minutes
      rate(livepeer_segment_transcoded_total[5m]) /
      rate(livepeer_segment_source_appeared_total[5m])

      # ETH deposit remaining in ETH (not wei)
      livepeer_gateway_deposit / 1e18

      # Average transcoding latency
      rate(livepeer_transcode_overall_latency_seconds_sum[5m]) /
      rate(livepeer_transcode_overall_latency_seconds_count[5m])

      # Deposit depletion rate (wei per second)
      deriv(livepeer_gateway_deposit[1h])
      ```
    </Tab>

    <Tab title="AI" icon="brain">
      <Badge color="purple">AI</Badge> Both on-chain and off-chain Gateways.

      <StyledTable>
        <TableRow header>
          <TableCell header>Metric</TableCell>
          <TableCell header>What it shows</TableCell>
          <TableCell header>Alert threshold</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_current_sessions_total`</TableCell>
          <TableCell>Active AI sessions</TableCell>
          <TableCell>Capacity planning</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_max_sessions_total`</TableCell>
          <TableCell>Configured session limit</TableCell>
          <TableCell>Alert when `current > 0.8 x max`</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_discovery_errors_total`</TableCell>
          <TableCell>Orchestrator discovery failures</TableCell>
          <TableCell>Alert on any increase</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>`livepeer_segment_source_upload_failed_total`</TableCell>
          <TableCell>Failed job submissions</TableCell>
          <TableCell>Alert on rate increase</TableCell>
        </TableRow>
      </StyledTable>

      <Note>
        AI-specific inference latency (per-pipeline, per-model) is not currently exposed via `/metrics`. For AI inference latency, use <LinkArrow href="https://tools.livepeer.cloud" label="Livepeer Tools" newline={false} /> or instrument the application layer.
      </Note>

      **Useful queries:**

      ```promql icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
      # Sessions approaching capacity
      livepeer_current_sessions_total / livepeer_max_sessions_total

      # Discovery error rate
      rate(livepeer_discovery_errors_total[5m])
      ```
    </Tab>

    <Tab title="Dual" icon="clone">
      <Badge color="green">Dual</Badge> - on-chain Gateways running both video and AI.

      Run all video metrics AND all AI metrics. The additional concern is GPU resource contention.

      **GPU monitoring via HTTP API:**

      ```bash icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
      # Poll hardware stats every 30 seconds
      watch -n 30 'curl -s http://localhost:8935/hardware/stats | python3 -m json.tool'
      ```

      Key fields to watch:

      * `gpu_memory_used` / `gpu_memory_total` - approach to 100% precedes model load failures
      * `gpu_utilization` - sustained 100% during low-volume periods indicates a bottleneck

      **When to separate workloads:**

      Consider splitting video and AI onto separate nodes when:

      * GPU memory is consistently above 85%
      * AI model loading causes video transcoding latency spikes
      * `livepeer_orchestrator_swaps` rate increases during AI inference peaks

      See <LinkArrow href="/v2/gateways/guides/advanced-operations/scaling" label="Scaling" newline={false} /> for architecture patterns.
    </Tab>
  </Tabs>
</BorderedBox>

<CustomDivider />

## Grafana Dashboards

The `livepeer/livepeer-monitoring` Docker stack includes three starter Grafana dashboards:

<AccordionGroup>
  <Accordion title="Node overview" icon="gauge-high">
    Active sessions, success rate, transcoding latency, and Orchestrator connectivity. The primary operational dashboard for day-to-day monitoring.
  </Accordion>

  <Accordion title="Payment overview" icon="coins">
    ETH deposit and reserve over time, ticket value sent, and payment creation errors. Critical for on-chain Gateways to track deposit depletion rate.
  </Accordion>

  <Accordion title="Transcoding performance" icon="chart-line">
    Realtime ratios, latency distribution (p50, p95, p99), and segment success/failure breakdown. Useful for identifying quality degradation patterns.
  </Accordion>
</AccordionGroup>

**Custom panels to consider adding:**

* Deposit depletion forecast (linear regression on `livepeer_gateway_deposit` over 24h)
* Session count vs `-maxSessions` limit as a percentage gauge
* AI discovery error rate overlaid with session count (correlation check)

<CustomDivider />

## Alert Rules

Configure these rules in Prometheus to receive automated notifications when the Gateway needs attention.

### <Icon icon="circle" iconType="solid" color="red" /> Critical

```yaml icon="circle-exclamation" Critical Alerts theme={"theme":{"light":"github-light","dark":"dark-plus"}}
groups:
  - name: livepeer-gateway-critical
    rules:
      - alert: GatewayDown
        expr: up{job=~"livepeer.*"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Livepeer Gateway is unreachable"

      - alert: DepositExhausted
        expr: livepeer_gateway_deposit < 10000000000000000
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Gateway ETH deposit critically low ({{ $value | humanize }} wei)"

      - alert: SuccessRateCritical
        expr: |
          rate(livepeer_segment_transcoded_total[5m]) /
          rate(livepeer_segment_source_appeared_total[5m]) < 0.90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Transcoding success rate below 90%"
```

### <Icon icon="circle" iconType="solid" color="orange" /> Warning

```yaml icon="warning" Warning Alerts theme={"theme":{"light":"github-light","dark":"dark-plus"}}
      - alert: DepositLow
        expr: livepeer_gateway_deposit < 50000000000000000
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Gateway ETH deposit below 0.05 ETH - top up soon"

      - alert: HighTranscodeLatency
        expr: |
          rate(livepeer_transcode_overall_latency_seconds_sum[5m]) /
          rate(livepeer_transcode_overall_latency_seconds_count[5m]) > 5
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Average transcoding latency exceeds 5 seconds"

      - alert: PaymentCreateErrors
        expr: rate(livepeer_payment_create_errors[5m]) > 0
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Ticket creation errors - check Arbitrum RPC health"

      - alert: AIDiscoveryErrors
        expr: rate(livepeer_discovery_errors_total[5m]) > 0
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Orchestrator discovery failing - check -orchAddr list"
```

<CustomDivider />

## Related Pages

<CardGroup cols={3}>
  <Card title="Prometheus Metrics" icon="table" href="/v2/gateways/resources/reference/technical/go-livepeer/prometheus-metrics">
    Full table of all livepeer\_\* metrics.
  </Card>

  <Card title="On-Chain Metrics" icon="cube" href="/v2/gateways/guides/monitoring-and-tooling/on-chain-metrics">
    TicketBroker events and Arbitrum contract monitoring.
  </Card>

  <Card title="Tools & Dashboards" icon="gauge-high" href="/v2/gateways/guides/monitoring-and-tooling/tools-and-dashboards">
    Explorer, Livepeer Tools, livepeer\_cli.
  </Card>
</CardGroup>
