> ## 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.

# Gateway Requirements

> Hardware, operating system, network, and skills requirements for running a Livepeer gateway. Covers both off-chain and on-chain deployment modes.

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 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 CenteredContainer = ({children, maxWidth = "800px", padding = "0", preset = "default", width = "", minWidth = "", marginRight = "", marginBottom = "", textAlign = "", style = {}, className = "", ...rest}) => {
  const presets = {
    default: {},
    fitContent: {
      width: "fit-content",
      minWidth: "fit-content"
    },
    readable70: {
      width: "70%",
      minWidth: "fit-content"
    },
    readable80: {
      width: "80%",
      minWidth: "fit-content"
    },
    readable90: {
      width: "90%"
    },
    wide900: {
      maxWidth: "900px"
    }
  };
  const presetStyle = presets[preset] || presets.default;
  return <div className={className} style={{
    maxWidth: presetStyle.maxWidth || maxWidth,
    margin: "0 auto",
    padding: padding,
    ...presetStyle.width ? {
      width: presetStyle.width
    } : {},
    ...presetStyle.minWidth ? {
      minWidth: presetStyle.minWidth
    } : {},
    ...width ? {
      width
    } : {},
    ...minWidth ? {
      minWidth
    } : {},
    ...marginRight ? {
      marginRight
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...textAlign ? {
      textAlign
    } : {},
    ...style
  }} {...rest}>
      {children}
    </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 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>;
};

<CenteredContainer preset="readable90">
  <Tip>Gateways are software nodes that require network optimisations (bandwidth and latency) and only minimal hardware (CPU and RAM).</Tip>
</CenteredContainer>

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

A Livepeer Gateway routes jobs between your application and the compute network. It does not run AI models or transcode video - Orchestrator nodes handle that.
Requirements vary by deployment mode: off-chain Gateways have a lighter setup, while on-chain Gateways need Ethereum infrastructure.

## Hardware

Hardware requirements are the same across deployment modes. The Gateway is a routing layer, not a compute layer.

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Requirement</TableCell>
      <TableCell header>Minimum</TableCell>
      <TableCell header>Recommended</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**CPU**</TableCell>
      <TableCell>2 cores</TableCell>
      <TableCell>4-8 cores</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**RAM**</TableCell>
      <TableCell>4 GB</TableCell>
      <TableCell>16-32 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Storage**</TableCell>
      <TableCell>20 GB SSD</TableCell>
      <TableCell>100 GB NVMe SSD</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Network**</TableCell>
      <TableCell>50 Mbps symmetric</TableCell>
      <TableCell>1 Gbps, low latency</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**GPU**</TableCell>
      <TableCell>Not required</TableCell>
      <TableCell>Not required</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

Gateways are lightweight routing nodes. Minimum specs are sufficient for development and low-traffic deployments.

<Note>
  **Node type differences:** <Badge color="purple">AI</Badge> or <Badge color="green">Dual</Badge> Gateways require Linux. <Badge color="blue">Video</Badge> Gateways also support Windows via WSL2/Docker and macOS (build from source). On-chain Gateways additionally require a public IP, static IP or domain, and ports 1935 (RTMP), 8935 (HTTP), and optionally 7935 (CLI).
</Note>

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

## Operating Systems

Not all operating systems support all node types.

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>OS</TableCell>
      <TableCell header>Video</TableCell>
      <TableCell header>AI</TableCell>
      <TableCell header>Notes</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Linux** (Ubuntu 20.04+)</TableCell>
      <TableCell>✅ Full support</TableCell>
      <TableCell>✅ Full support</TableCell>
      <TableCell>Recommended for all production Gateways</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Linux** (other distros)</TableCell>
      <TableCell>✅ Generally supported</TableCell>
      <TableCell>✅ Generally supported</TableCell>
      <TableCell>Debian, CentOS, Arch - verify binary compatibility</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**macOS** (Intel / Apple Silicon)</TableCell>
      <TableCell>⚠️ Dev only - build from source</TableCell>
      <TableCell>❌ No binaries available</TableCell>
      <TableCell>Local dev/routing only; Docker often fails for AI Gateway</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Windows** (native)</TableCell>
      <TableCell>⚠️ Limited support</TableCell>
      <TableCell>❌ Not supported</TableCell>
      <TableCell>No native AI Gateway binary for Windows</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Windows** (WSL2 + Docker)</TableCell>
      <TableCell>✅ Supported via Docker</TableCell>
      <TableCell>⚠️ Fragile - use Linux VM instead</TableCell>
      <TableCell>Linux in WSL</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Docker** (Linux host)</TableCell>
      <TableCell>✅ Supported</TableCell>
      <TableCell>✅ Supported</TableCell>
      <TableCell>Recommended deployment method for most setups</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

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

## Networking Needs

Your Gateway is a routing layer. Network quality directly determines job latency and stream reliability.

<Tabs>
  <Tab title="Off-chain">
    Off-chain Gateways initiate outbound connections to Orchestrators. They do not need to be publicly reachable.

    <StyledTable variant="bordered">
      <thead>
        <TableRow header>
          <TableCell header>Requirement</TableCell>
          <TableCell header>Detail</TableCell>
          <TableCell header>Node Type</TableCell>
        </TableRow>
      </thead>

      <tbody>
        <TableRow>
          <TableCell>**Bandwidth**</TableCell>
          <TableCell>Sufficient for your request volume. AI inference payloads (images, audio) are smaller than video streams.</TableCell>
          <TableCell><Badge color="purple">AI</Badge> lower; <Badge color="blue">Video</Badge> <Badge color="green">Dual</Badge> higher</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>**Latency**</TableCell>
          <TableCell>Low latency to Orchestrators improves response times. Colocation in regions with strong Orchestrator presence helps.</TableCell>
          <TableCell>All node types</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>**Public IP**</TableCell>
          <TableCell>Not required - Gateway initiates all connections outbound</TableCell>
          <TableCell>All node types</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>**Outbound access**</TableCell>
          <TableCell>To Orchestrators (port 443 or as configured) and remote signer endpoint</TableCell>
          <TableCell>All node types</TableCell>
        </TableRow>
      </tbody>
    </StyledTable>

    <Note>
      **Ports:** Outbound to Orchestrators on port 443 (or as configured). No inbound ports required.
    </Note>
  </Tab>

  <Tab title="On-chain">
    On-chain Gateways must be publicly reachable. Bandwidth is the primary constraint - the Gateway receives ingest streams and relays transcoded output.

    <StyledTable variant="bordered">
      <thead>
        <TableRow header>
          <TableCell header>Requirement</TableCell>
          <TableCell header>Detail</TableCell>
          <TableCell header>Node Type</TableCell>
        </TableRow>
      </thead>

      <tbody>
        <TableRow>
          <TableCell>**Bandwidth**</TableCell>
          <TableCell>High sustained throughput. Scale with concurrent stream count or inference request volume.</TableCell>
          <TableCell><Badge color="blue">Video</Badge> <Badge color="green">Dual</Badge> highest; <Badge color="purple">AI</Badge> moderate</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>**Latency**</TableCell>
          <TableCell>Low latency to Orchestrators and viewers. Live video is latency-sensitive - every hop adds delay.</TableCell>
          <TableCell><Badge color="blue">Video</Badge> <Badge color="green">Dual</Badge> critical; <Badge color="purple">AI</Badge> important</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>**Public IP or domain**</TableCell>
          <TableCell>Required (`-serviceAddr`) - Orchestrators and encoders must reach your Gateway. Static IP or domain recommended.</TableCell>
          <TableCell>All node types</TableCell>
        </TableRow>

        <TableRow>
          <TableCell>**Uptime**</TableCell>
          <TableCell>High availability expected - live streams drop if the Gateway goes down. VPS or cloud instance strongly recommended over home connections.</TableCell>
          <TableCell><Badge color="blue">Video</Badge> <Badge color="green">Dual</Badge> critical; <Badge color="purple">AI</Badge> recommended</TableCell>
        </TableRow>
      </tbody>
    </StyledTable>

    <Note>
      **Ports:** RTMP ingest on 1935, HTTP API on 8935, CLI on 7935 (optional, keep internal). Ensure these are open and reachable.
    </Note>
  </Tab>
</Tabs>

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

## On-Chain Requirements

On-chain deployment mode requires Ethereum infrastructure. Off-chain operators can skip this section.

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Requirement</TableCell>
      <TableCell header>Detail</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Arbitrum RPC URL**</TableCell>
      <TableCell>Connection to Arbitrum One where Livepeer's smart contracts are deployed. Options: public RPC (`https://arb1.arbitrum.io/rpc`), third-party (Alchemy, Infura, QuickNode), community (`https://arb1.livepeer.community`), or self-hosted. See the [Arbitrum RPC reference](/v2/Gateways/resources/compendium/Arbitrum-rpc).</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Ethereum wallet**</TableCell>
      <TableCell>An Ethereum account on Arbitrum to hold funds and sign payment tickets. Go-livepeer can auto-create on first run, or bring an existing wallet via `-ethAcctAddr`. See the [on-chain setup guide](/v2/Gateways/setup/requirements/on-chain-setup/on-chain).</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**ETH on Arbitrum**</TableCell>
      <TableCell>Minimum for testing: **0.1 ETH**. Production: **0.065 ETH deposit + 0.03 ETH reserve**. Must be bridged from Ethereum mainnet. See [Bridge LPT to Arbitrum](/v2/Gateways/setup/requirements/on-chain-setup/bridge-LPT-to-Arbitrum) and the [fund Gateway guide](/v2/Gateways/guides/payments-and-pricing/fund-Gateway).</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

<Note>
  Gateways pay in ETH, not LPT. LPT is used for staking and governance by Orchestrators - Gateways never need LPT.
</Note>

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

## Off-Chain Requirements

Off-chain deployment mode removes all Ethereum requirements from your Gateway. You need three things instead.

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Requirement</TableCell>
      <TableCell header>Detail</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Linux server**</TableCell>
      <TableCell>Ubuntu 20.04 or later, or Docker on Linux</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Remote signer**</TableCell>
      <TableCell>Either self-hosted or a community-hosted endpoint</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Orchestrator list**</TableCell>
      <TableCell>One or more AI-capable Orchestrator addresses for `-orchAddr`</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**`-httpIngest` flag**</TableCell>
      <TableCell>Required: enables HTTP job ingestion</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

<Note>
  **Remote signer:** The remote signer handles Ethereum payment signing on behalf of your Gateway, so you do not need a funded wallet on the Gateway node itself. Options: community signer (`https://signer.eliteencoder.net/` - free) or self-hosted for full control.
</Note>

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

## Integration Notes

* **Off-chain Gateways** supply Orchestrator addresses directly via `-orchAddr`. On-chain Gateways discover Orchestrators automatically through the Livepeer Protocol.
* <Badge color="purple">AI</Badge> or <Badge color="green">Dual</Badge> node types require Orchestrators running `ai-runner` containers. <Badge color="blue">Video</Badge> node types work with any Orchestrator advertising transcoding capabilities.

{/* j0sh noted in Discord: "I'll also try to publish docs soon." */}

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

## Technical Skills

Technical skills required depend on your deployment mode and stage.

<AccordionGroup>
  <Accordion title="Minimum: comfortable with a terminal and Docker">
    You can get an AI Gateway running with:

    * Basic Linux command line (navigate directories, run commands, read logs)
    * Docker: pull an image, run a container, read container logs
    * Ability to edit a configuration file or Docker Compose YAML
    * An understanding of what a REST API is (for connecting your application)

    This is the minimum for an off-chain Gateway. On-chain deployment mode adds the Ethereum steps below.
  </Accordion>

  <Accordion title="On-chain: also need Ethereum basics">
    Running a Gateway in on-chain deployment mode requires:

    * Creating and managing an Ethereum wallet
    * Understanding the Arbitrum L2 network (not the same as Ethereum mainnet)
    * Bridging ETH from Ethereum to Arbitrum
    * Running `livepeer_cli` to allocate deposit and reserve funds
    * Monitoring your ETH balance and topping up when needed

    None of this requires deep crypto expertise, but it is more involved than the off-chain path. If you have never used a crypto wallet before, budget extra time for the on-chain setup steps.
  </Accordion>

  <Accordion title="Production: systems administration">
    For a production Gateway handling production traffic, you additionally want:

    * Linux systems administration (systemd services, log rotation, process monitoring)
    * Basic networking (firewall rules, DNS, reverse proxy configuration)
    * Docker Compose or equivalent for managing multi-container deployments
    * Familiarity with Prometheus/Grafana or equivalent monitoring stack

    These are not requirements to get started, but they become important for any Gateway you plan to rely on.
  </Accordion>
</AccordionGroup>

## Related Pages

<CardGroup cols={2}>
  <Card title="Install with Docker" icon="docker" href="/v2/gateways/setup/install/docker-install" arrow horizontal>
    Quickest path to a running Gateway. Docker handles dependencies automatically.
  </Card>

  <Card title="Install on Linux" icon="linux" href="/v2/gateways/setup/install/linux-install" arrow horizontal>
    Install the go-livepeer binary directly on your Linux host.
  </Card>

  <Card title="AI Gateway Quickstart" icon="bolt" href="/v2/gateways/quickstart/gateway-setup" arrow horizontal>
    Step-by-step from zero to a running AI Gateway, including Docker command and test request.
  </Card>

  <Card title="Community Install Methods" icon="people-group" href="/v2/gateways/guides/deployment-details/gwid-single-click-deploy" arrow horizontal>
    Ansible, Docker Compose, and community-maintained install scripts.
  </Card>
</CardGroup>
