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

# Join a Pool

> Contribute GPU capacity to an existing Livepeer orchestrator and earn rewards without running protocol infrastructure.

export const DynamicTable = ({tableTitle = null, headerList = [], itemsList = [], monospaceColumns = [], columnWidths = {}, contentFitColumns = [], showSeparators = false, margin, className = "", style = {}, ...rest}) => {
  if (!headerList.length) {
    return <div>No headers provided</div>;
  }
  const safeContentFitColumns = Array.isArray(contentFitColumns) ? contentFitColumns : [];
  const usesContentFitColumns = safeContentFitColumns.length > 0;
  const isContentFitColumn = header => safeContentFitColumns.includes(header);
  const getColumnStyle = header => {
    const widthStyle = columnWidths[header] ? {
      width: columnWidths[header],
      minWidth: columnWidths[header],
      maxWidth: columnWidths[header]
    } : {};
    const contentFitStyle = !columnWidths[header] && isContentFitColumn(header) ? {
      width: "1%",
      whiteSpace: "nowrap"
    } : {};
    return {
      ...contentFitStyle,
      ...widthStyle
    };
  };
  return <div className={className} style={style} {...rest}>
      {tableTitle && <div style={{
    fontStyle: "italic",
    margin: 0
  }}>
          <strong>{tableTitle}</strong>
        </div>}
      <div style={{
    overflowX: "auto",
    ...margin != null && ({
      margin
    })
  }} role="region" tabIndex={0} aria-label={tableTitle ? `Scrollable table: ${tableTitle}` : "Scrollable table"}>
        <table data-docs-dynamic-table style={{
    width: "100%",
    tableLayout: usesContentFitColumns ? "auto" : "fixed",
    borderCollapse: "collapse",
    fontSize: "0.9rem",
    marginTop: 0
  }}>
          <thead>
            <tr style={{
    backgroundColor: "var(--lp-color-accent)",
    color: "var(--lp-color-on-accent)",
    borderBottom: "1px solid var(--lp-color-border-default)"
  }}>
              {headerList.map((header, index) => <th key={index} style={{
    padding: "10px 8px",
    textAlign: "left",
    fontWeight: "600",
    color: "var(--lp-color-on-accent)",
    ...getColumnStyle(header)
  }}>
                  {header}
                </th>)}
            </tr>
          </thead>
          <tbody>
            {itemsList.filter(item => showSeparators || !item?.__separator).map((item, rowIndex) => item?.__separator ? <tr key={rowIndex} style={{
    backgroundColor: "var(--lp-color-accent)",
    color: "var(--lp-color-on-accent)",
    borderBottom: "1px solid var(--lp-color-accent)"
  }}>
                  <td colSpan={headerList.length} style={{
    padding: "6px 8px",
    fontWeight: "700",
    color: "var(--lp-color-on-accent)",
    letterSpacing: "0.01em"
  }}>
                    {(item[headerList[0]] ?? item.Category) ?? "Category"}
                  </td>
                </tr> : <tr key={rowIndex} style={{
    borderBottom: "1px solid var(--lp-color-border-default)"
  }}>
                  {headerList.map((header, colIndex) => {
    const value = (item[header] ?? item[header.toLowerCase()]) ?? "-";
    const isMonospace = monospaceColumns.includes(colIndex);
    return <td key={colIndex} style={{
      padding: "8px 8px",
      fontFamily: isMonospace ? "monospace" : "inherit",
      wordWrap: "break-word",
      overflowWrap: "break-word",
      ...getColumnStyle(header)
    }}>
                        {isMonospace ? <code>{value}</code> : value}
                      </td>;
  })}
                </tr>)}
          </tbody>
        </table>
      </div>
    </div>;
};

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 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>;
};

export const Quote = ({children, className = "", style = {}, ...rest}) => {
  const quoteStyle = {
    fontSize: "1rem",
    textAlign: 'center',
    opacity: 1,
    fontStyle: 'italic',
    color: 'var(--lp-color-accent)',
    border: '1px solid var(--lp-color-border-default)',
    borderRadius: "8px",
    padding: "var(--lp-spacing-4)",
    margin: '1rem 0',
    ...style
  };
  return <blockquote className={className} style={quoteStyle} {...rest}>{children}</blockquote>;
};

<Quote> Orchestrator pools are operator-run GPU pools where multiple GPU providers contribute hardware to a single Livepeer Orchestrator, which aggregates capacity, routes jobs, and distributes rewards. </Quote>

## About Pools

Joining a community-run pool is a low-lift way to get started with the Livepeer Network.
Pools are run by experienced operators who manage the day-to-day operations of the network.

<Tip> Pools are not official Livepeer infrastructure. They are community-run and vary in terms of pricing, rewards, and management. Always research and choose a pool that best fits your needs.</Tip>

Pool operators handle tasks such as staking, delegating, and managing the Orchestrator node, so you don't need to have LPT or deal with on-chain actions.
The trade-off is that you have less control over pricing, routing, and delegation decisions, and the revenue is shared with the pool operator.

<DynamicTable
  tableTitle="Pool vs Orchestrator Comparison"
  headerList={["Feature", "Orchestrator Pool", "Run an Orchestrator"]}
  itemsList={[
    { "Feature": "Setup & Maintenance", "Orchestrator Pool": "✅ No protocol setup required. GPU connects to an existing orchestrator's infrastructure.", "Run an Orchestrator": "❌ Requires installing, configuring, and maintaining a Livepeer orchestrator node." },
    { "Feature": "LPT required?", "Orchestrator Pool": "✅ GPU owners do not stake, delegate, or manage any on-chain assets.", "Run an Orchestrator": "❌ Requires staking LPT and managing delegation." },
    { "Feature": "Operational Lift", "Orchestrator Pool": "✅ Orchestrator handles node operations, upgrades, routing, monitoring, and incidents.", "Run an Orchestrator": "❌ Full responsibility for uptime, upgrades, monitoring, and incident response." },
    { "Feature": "Pricing control", "Orchestrator Pool": "❌ Pricing is set at the pool level. Individual GPUs cannot price independently.", "Run an Orchestrator": "✅ Full control over pricing, service offerings, and workload specialization." },
    { "Feature": "Rewards", "Orchestrator Pool": "❌ Rewards are shared. The pool takes a percentage before payouts.", "Run an Orchestrator": "✅ Keep 100% of fees and inflation rewards (subject to costs)." },
    { "Feature": "Protocol Reputation", "Orchestrator Pool": "❌ On-chain reputation accrues to the orchestrator, not individual GPU contributors.", "Run an Orchestrator": "✅ Reputation accrues directly to your orchestrator address." },
    { "Feature": "Flexibility", "Orchestrator Pool": "✅ GPUs can join or leave pools without affecting the orchestrator's on-chain identity.", "Run an Orchestrator": "❌ Stake unbonding periods and delegation relationships reduce exit flexibility." }
]}
/>

## Join a Pool

<StyledSteps>
  <StyledStep title="Choose a Pool">
    Joining a pool is akin to entering an operational partnership, rather than being a permissionless protocol action.

    <Note>
      There is currently no canonical directory of pools, discovery is off‑chain and social, similar to mining pools.
      One of the only public Orchestrator pools is the [Titan Node](https://titan-node.com/).
    </Note>

    The first step is to find, research and choose a pool that best fits your needs.

    <Accordion title="Finding a Pool" icon="magnifying-glass">
      You can find out about reputable pools through social channels, but ensure you do your own research and due diligence before joining any pool.

      Common discovery channels include:

      * Livepeer community [Discord](https://discord.gg/livepeer)
      * [Forum](https://forum.livepeer.org) posts and announcements
      * Direct outreach to Orchestrators
      * Existing infrastructure or GPU communities
    </Accordion>

    <Accordion title="Pool Due Diligence Checklist" icon="check-to-slot" defaultOpen={false}>
      ***Before committing hardware, confirm:***

      * How earnings are calculated
      * How usage is measured
      * How disputes are handled
      * Whether GPUs can be removed at any time
      * What happens during downtime or network changes
      * On-chain identity and reputation

      <br />

      ***A legitimate Orchestrator pool will clearly publish:***

      1. **Whether it accepts external GPUs**
         * Some Orchestrators operate only their own hardware
         * Pools explicitly accept third‑party GPU providers
      2. **Supported hardware**
         * GPU models (e.g. RTX 3090, A6000, A100, L40S)
         * VRAM requirements
         * Single‑GPU vs multi‑GPU nodes
      3. **Supported workloads**
         * Transcoding (video encoding)
         * AI inference
         * Real‑time pipelines (e.g. ComfyUI / ComfyStream)
         * Latency‑sensitive vs batch jobs
      4. **Revenue split**
         * Percentage paid to GPU owner vs pool operator
         * Any performance multipliers or penalties
      5. **Payout details**
         * Asset used (ETH, USDC, fiat, etc.)
         * Payout frequency
         * Minimum payout thresholds
      6. **Operational requirements**
         * Uptime expectations
         * Monitoring or alerting requirements
         * Geographic or networking constraints
    </Accordion>
  </StyledStep>

  <StyledStep title="Connect your GPU">
    Once a pool is selected, the GPU must be connected to the Orchestrator’s infrastructure.

    There are three common connection models:

    <Accordion title="BYO Container (Preferred)" icon="cube">
      In this model, your GPU never runs protocol code. It only runs workloads dispatched by the Orchestrator.

      **Best For:**

      * Most GPU owners
      * Anyone prioritising security and portability
      * Those who want to run other workloads on the same GPU

      **Process:**

      * The Orchestrator provides a container image and configuration
      * You run the container on your GPU machine
      * The container exposes standardised endpoints
      * The Orchestrator schedules work to the container

      <Columns cols={2}>
        <div>
          **Pros**

          * Clear security boundaries
          * Reproducible environments
          * Easier upgrades and rollbacks
          * Minimal trust required between parties
        </div>

        <div>
          **Cons**

          * Slightly higher setup complexity
          * Slightly lower performance (due to extra network hop)
        </div>
      </Columns>
    </Accordion>

    <Accordion title="Bare Metal" icon="server">
      The Orchestrator will provide a remote access protocol (e.g. SSH) to connect to their infrastructure.
      The GPU owner is responsible for installing and managing the GPU driver and Livepeer software.

      **Best For:**

      * GPU owners with physical machines
      * Home labs or data‑centre colocations

      **Process:**

      * You provision a Linux machine with the required GPU drivers
      * The Orchestrator provides setup instructions or scripts
      * Secure access (SSH / VPN) is established
      * The GPU is registered internally by the Orchestrator

      <Columns cols={2}>
        <div>
          **Pros**

          * Full Hardware Control
          * No vendor lock‑in or cloud markup
          * Lower latency
          * Easier to manage
        </div>

        <div>
          **Cons**

          * Requires physical presence
          * More complex setup & management
          * Responsible for hardware uptime
          * Requires sysadmin experience
        </div>
      </Columns>
    </Accordion>

    <Accordion title="Cloud GPU" icon="cloud">
      The Orchestrator will provide a cloud GPU instance for the GPU owner to use. The GPU owner is responsible for managing the instance and the Livepeer software.

      **Best For:**

      * Flexible capacity providers
      * Burst or on‑demand contributors

      **Process:**

      * You launch a GPU instance on a cloud provider
      * Required drivers and runtime are installed
      * The Orchestrator connects the instance to their pool
      * Jobs are routed when capacity is needed

      <Columns cols={2}>
        <div>
          **Pros**

          * Fast to scale up or down
          * No physical hardware management
        </div>

        <div>
          **Cons**

          * Higher cost base
          * Margin depends heavily on utilisation
        </div>
      </Columns>
    </Accordion>
  </StyledStep>

  <StyledStep title="Orchestrator Aggregates Your GPU ">
    Once connected, your GPU becomes part of the Orchestrator’s capacity pool.

    Your GPU is not visible individually to the protocol.

    <Accordion title="Aggregation Details" icon="circle-nodes">
      Aggregation is entirely managed by the Orchestrator and includes:

      * Adding your GPU to internal capacity tracking
      * Advertising aggregate capacity to Gateways
      * Routing jobs across all pooled GPUs
      * Load‑balancing based on performance and availability

      From the Livepeer Network’s perspective:

      * There is one Orchestrator
      * Backed by pooled stake
      * Offering pooled capacity
    </Accordion>

    <Accordion title="Scheduling and Utilisation" icon="business-time">
      The Orchestrator:

      * Chooses which jobs run on which GPUs
      * Balances latency, cost, and reliability
      * May rotate workloads across contributors

      Utilisation depends on:

      * Demand on the network
      * Your GPU’s performance
      * Pool pricing strategy
    </Accordion>

    <Accordion title="Uptime, Pricing, and Reputation" icon="chart-line">
      The Orchestrator is responsible for:

      * Maintaining uptime SLAs
      * Setting prices for services
      * Preserving on‑chain reputation

      If the Orchestrator performs well:

      * More jobs are routed to the pool
      * Delegation may increase
      * Earnings rise for all pool contributors

      If performance degrades:

      * Job volume drops
      * Earnings decline
    </Accordion>
  </StyledStep>

  <StyledStep title="Earn Rewards">
    <Warning> There are no on-chain records of individual GPU contributions, so the pool's reputation and rewards are entirely dependent on the Orchestrator's performance and reputation. </Warning>

    All rewards are earned *by the Orchestrator* and distributed **off‑chain** to GPU contributors.
    GPU owners *do not earn rewards on-chain*.

    * Earnings are pooled and split
    * Payouts are made **off‑chain**
    * No on‑chain rewards for individual GPUs

    <Accordion title="Reward Sources" icon="coins">
      1. Usage fees

      * Paid by applications and Gateways
      * Based on actual work performed
      * Increasingly dominant as network usage grows

      2. Inflation rewards

      * Minted by the protocol
      * Earned by the Orchestrator’s stake
      * Typically shared with pool participants
    </Accordion>

    <Accordion title="Payouts" icon="calculator-simple">
      Payouts are defined by the pool’s terms and may include:

      * Asset type (ETH, USDC, fiat, etc.)
      * Payout schedule (daily, weekly, monthly)
      * Performance adjustments
      * Minimum thresholds

      **All payouts are off‑chain** and depend on the operator’s accounting systems.
    </Accordion>
  </StyledStep>
</StyledSteps>

{/* <DynamicTable
headerList={["Dimension", "How Orchestrator Pools Work"]}
itemsList={[
  { "Dimension": "On-chain identity", "How Orchestrator Pools Work": "Single orchestrator with one stake and delegation set" },
  { "Dimension": "GPU composition", "How Orchestrator Pools Work": "Many GPUs behind the pool, often owned by different providers" },
  { "Dimension": "Capacity advertising", "How Orchestrator Pools Work": "Operators advertise pooled capacity, not individual GPUs" },
  { "Dimension": "Pricing", "How Orchestrator Pools Work": "Unified pricing set by the pool operator" },
  { "Dimension": "Scheduling & routing", "How Orchestrator Pools Work": "GPUs are centrally scheduled and load-balanced across the pool" },
  { "Dimension": "Uptime & reputation", "How Orchestrator Pools Work": "Managed at the pool level and reflected in a shared on-chain reputation" },
  { "Dimension": "Reward flow", "How Orchestrator Pools Work": "Usage fees and inflation rewards are earned by the orchestrator and split internally" },
  { "Dimension": "Joining & leaving", "How Orchestrator Pools Work": "GPU owners can join or exit without affecting the on-chain identity" },
  { "Dimension": "Benefits", "How Orchestrator Pools Work": "Easier onboarding, lower operational risk, stronger demand aggregation, flexible participation" },
  { "Dimension": "Tradeoffs", "How Orchestrator Pools Work": "Less control over pricing and routing, revenue sharing with the pool, higher internal competition" }
]}
/> */}

{/*
_Benefits of a pool:_
- **Easier to get started**: No need to stake, delegate, or manage your own node
- **Lower risk**: Pools are run by experienced operators
- **Higher rewards**: Pools can negotiate better pricing and earn more revenue
- **Flexibility**: You can join multiple pools and switch at any time

_Tradeoffs:_
- **Less control**: Pools make pricing, routing, and delegation decisions
- **Lower rewards**: Pools take a cut of the revenue
- **More competition**: Pools are more attractive to applications    */}
