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

# Orchestrator Incentive Model

> How Orchestrators earn - the two revenue streams, cost structure, payment flow, pricing configuration, and what the earnings case looks like in practice.

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 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 ScrollableDiagram = ({children, title = '', maxHeight = '500px', minWidth = '100%', showControls = false, className = '', style = {}, ...rest}) => {
  const buildDiagramKey = (currentTitle = '', currentClassName = '') => {
    const source = `${currentTitle}|${currentClassName}|scrollable-diagram`;
    let hash = 0;
    for (let index = 0; index < source.length; index += 1) {
      hash = hash * 31 + source.charCodeAt(index) >>> 0;
    }
    return `docs-diagram-${hash.toString(36)}`;
  };
  const diagramKey = buildDiagramKey(title, className);
  const zoomName = `${diagramKey}-zoom`;
  const zoomLevels = [{
    label: '75%',
    value: 0.75
  }, {
    label: '100%',
    value: 1
  }, {
    label: '125%',
    value: 1.25
  }, {
    label: '150%',
    value: 1.5
  }];
  const containerStyle = {
    overflow: 'auto',
    maxHeight,
    border: '1px solid var(--lp-color-border-default)',
    borderRadius: "8px",
    padding: "var(--lp-spacing-4)",
    background: 'var(--lp-color-bg-card)',
    position: 'relative'
  };
  return <div className={className} style={{
    position: 'relative',
    marginBottom: "var(--lp-spacing-4)",
    ...style
  }} {...rest}>
      {title && <p style={{
    textAlign: 'center',
    fontStyle: 'italic',
    color: 'var(--lp-color-text-secondary)',
    marginBottom: "var(--lp-spacing-2)",
    fontSize: '0.875rem'
  }}>
          {title}
        </p>}

      {showControls ? <style>{`
          [data-docs-diagram-key="${diagramKey}"] [data-docs-diagram-content] {
            transform: scale(1);
            transform-origin: top left;
            width: max-content;
          }
          ${zoomLevels.map(zoomLevel => `
          #${diagramKey}-${zoomLevel.label.replace('%', '')}:checked ~ [data-docs-diagram-shell] [data-docs-diagram-content] {
            transform: scale(${zoomLevel.value});
          }
          #${diagramKey}-${zoomLevel.label.replace('%', '')}:checked ~ [data-docs-diagram-controls] label[for="${diagramKey}-${zoomLevel.label.replace('%', '')}"] {
            background: var(--lp-color-accent);
            color: var(--lp-color-on-accent);
            border-color: var(--lp-color-accent);
          }`).join('\n')}
        `}</style> : null}

      {showControls ? zoomLevels.map(zoomLevel => {
    const inputId = `${diagramKey}-${zoomLevel.label.replace('%', '')}`;
    return <input key={inputId} id={inputId} type="radio" name={zoomName} defaultChecked={zoomLevel.value === 1} style={{
      position: 'absolute',
      opacity: 0,
      pointerEvents: 'none'
    }} />;
  }) : null}

      <div data-docs-diagram-key={diagramKey} data-docs-diagram-shell style={containerStyle}>
        <div data-docs-diagram-content style={{
    minWidth,
    transformOrigin: 'top left',
    width: 'max-content'
  }}>
          {children}
        </div>
      </div>

      {showControls ? <div data-docs-diagram-controls style={{
    display: 'flex',
    justifyContent: 'flex-end',
    alignItems: 'center',
    gap: "var(--lp-spacing-2)",
    marginTop: "var(--lp-spacing-2)",
    flexWrap: 'wrap'
  }}>
          <span style={{
    fontSize: "0.75rem",
    color: 'var(--lp-color-text-muted)',
    marginRight: 'auto'
  }}>
            Scroll to pan
          </span>
          {zoomLevels.map(zoomLevel => {
    const inputId = `${diagramKey}-${zoomLevel.label.replace('%', '')}`;
    return <label key={inputId} htmlFor={inputId} style={{
      background: 'transparent',
      color: 'var(--lp-color-text-secondary)',
      border: '1px solid var(--lp-color-border-default)',
      borderRadius: "4px",
      padding: '4px 10px',
      cursor: 'pointer',
      fontSize: "0.75rem",
      fontWeight: '600'
    }}>
                {zoomLevel.label}
              </label>;
  })}
        </div> : null}
    </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 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 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 style={{ width: '90%' }}>
  <Tip>Orchestrators earn from two independent sources: ETH service fees for processing jobs, and LPT inflation rewards for protocol participation. Both require Active Set membership. Earnings from fees depend on workload volume; earnings from rewards depend on total stake and the Reward Cut configuration.</Tip>
</CenteredContainer>

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

## Two Revenue Streams

An Orchestrator's total earnings combine two streams that are structurally independent.

```mermaid theme={"theme":{"light":"github-light","dark":"dark-plus"}}
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#18794E', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3CB540', 'lineColor': '#3CB540', 'mainBkg': '#18794E', 'nodeBorder': '#3CB540', 'clusterBkg': 'transparent', 'clusterBorder': '#3CB540', 'titleColor': '#3CB540', 'edgeLabelBackground': 'transparent', 'textColor': '#3CB540', 'nodeTextColor': '#fff'}}}%%
flowchart LR
    subgraph FEES["Stream 1: Service Fees (ETH)"]
        A["Gateway sends job\n+ payment ticket"] --> B["Orchestrator\nexecutes work"]
        B --> C["Winning ticket redeemed\non TicketBroker"]
        C --> D["ETH paid to Orchestrator\n(fee cut retained;\nremainder to fee pool)"]
    end

    subgraph REWARDS["Stream 2: Inflation Rewards (LPT)"]
        E["Orchestrator calls\nrewards each round"] --> F["Protocol calculates\nshare based on stake"]
        F --> G["LPT minted and distributed\n(reward cut retained;\nremainder to delegator pool)"]
    end

    classDef default fill:#1a1a1a,color:#fff,stroke:#2d9a67,stroke-width:2px
    style FEES fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
    style REWARDS fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
```

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Stream</TableCell>
      <TableCell header>Currency</TableCell>
      <TableCell header>Source</TableCell>
      <TableCell header>Frequency</TableCell>
      <TableCell header>Depends on</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Service fees**</TableCell>
      <TableCell>ETH</TableCell>
      <TableCell>Gateways paying for compute (transcoding or AI inference)</TableCell>
      <TableCell>Per job (ticket redemption is probabilistic)</TableCell>
      <TableCell>Volume of work received; price configuration; uptime</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Inflation rewards**</TableCell>
      <TableCell>LPT</TableCell>
      <TableCell>Protocol inflation (new LPT minted per round)</TableCell>
      <TableCell>Once per round (\~22 hours) via reward call</TableCell>
      <TableCell>Total bonded stake (self-stake + delegated); Reward Cut setting</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

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

## Service Fees (ETH)

Service fees are paid by Gateways via **probabilistic micropayment (PM) tickets**. Each job segment
or inference request carries a ticket with a face value and a win probability. When a ticket "wins"
(determined cryptographically), the Orchestrator redeems it on the TicketBroker contract on Arbitrum
for the face value in ETH.

The expected value of a ticket equals its face value multiplied by the win probability. Over a large
number of tickets, actual earnings converge to the expected value.

### Pricing units

Fee income per job is determined by the price the Orchestrator charges and the volume it processes:

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Workload</TableCell>
      <TableCell header>Pricing unit</TableCell>
      <TableCell header>Configuration flag</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Video transcoding**</TableCell>
      <TableCell>Wei per pixel per segment</TableCell>
      <TableCell>`-pricePerUnit`</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Batch AI inference**</TableCell>
      <TableCell>Wei per pixel or per millisecond (pipeline-dependent)</TableCell>
      <TableCell>`-pricePerCapability` (per pipeline and model)</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Real-time AI (Cascade)**</TableCell>
      <TableCell>Interval-based during stream duration</TableCell>
      <TableCell>`-livePaymentInterval`</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

Setting prices too high means Gateways will not select the Orchestrator (their `-maxPricePerUnit`
ceiling acts as a filter). Setting prices too low reduces earnings per job. The network forms a
market price - use `livepeer_cli` to survey current rates before setting your own.

### Fee distribution

The Orchestrator's **Fee Cut** determines what share of collected fees goes to the Orchestrator versus
the shared fee pool distributed to Delegators.

```
Total fee ticket value = Orchestrator fee cut + Delegator fee pool
```

For example, at a Fee Cut of 5%: the Orchestrator keeps 5% of ticket value; 95% goes to the fee pool
distributed proportionally among Delegators.

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

## Inflation Rewards (LPT)

The Livepeer Protocol mints new LPT each round to incentivise participation. Orchestrators in the
Active Set earn a share of this inflation proportional to their total bonded stake.

### The reward call

To claim LPT rewards for a round, the Orchestrator (or an automated process) must call the reward
function on the BondingManager contract **once per round**. Missing a reward call means forgoing that
round's LPT rewards entirely - this is not recoverable.

Most production Orchestrators automate reward calling. The go-livepeer node can be configured to do
this automatically. See <LinkArrow href="/v2/orchestrators/guides/staking-and-rewards/rewards-and-fees" label="Rewards and Fees" newline={false} /> for configuration details.

### Reward distribution

The Orchestrator's **Reward Cut** determines what share of the round's LPT goes to the Orchestrator
versus Delegators:

```
Total round reward = Orchestrator reward cut + Delegator reward pool
```

A Reward Cut of 25% means the Orchestrator keeps 25% of the LPT earned; 75% is distributed to
Delegators in proportion to their bonded stake.

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Reward Cut setting</TableCell>
      <TableCell header>Orchestrator keeps</TableCell>
      <TableCell header>Delegators receive</TableCell>
      <TableCell header>Implication</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>0%</TableCell>
      <TableCell>None</TableCell>
      <TableCell>100%</TableCell>
      <TableCell>Maximum incentive to attract delegated stake; operator earns nothing from rewards</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>25%</TableCell>
      <TableCell>25%</TableCell>
      <TableCell>75%</TableCell>
      <TableCell>Common production setting; balances operator return with Delegator appeal</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>100%</TableCell>
      <TableCell>100%</TableCell>
      <TableCell>None</TableCell>
      <TableCell>Maximum operator return; Delegators receive no LPT rewards from this Orchestrator</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

### Active Set requirement

Only the top 100 Orchestrators by total bonded stake (self-stake + delegated stake) are in the
**Active Set** in any given round. Only Active Set members receive inflation rewards and can receive
Gateway jobs. Stake below the threshold for Active Set membership means no earnings from either stream.

The Active Set threshold varies with network participation. Monitor your rank on the
[Livepeer Explorer](https://explorer.livepeer.org) to ensure you remain in the Active Set.

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

## Orchestrator Costs

Earnings must be weighed against operational costs. Orchestrator costs fall into three categories:

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Cost category</TableCell>
      <TableCell header>What it covers</TableCell>
      <TableCell header>Notes</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Hardware**</TableCell>
      <TableCell>GPU(s), server, networking</TableCell>
      <TableCell>Capital expenditure; amortised over Orchestrator lifetime</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Infrastructure**</TableCell>
      <TableCell>Electricity, bandwidth, colocation or cloud fees</TableCell>
      <TableCell>Ongoing operating expense; electricity is the largest recurring cost for GPU operators</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Staking opportunity cost**</TableCell>
      <TableCell>LPT locked in self-bond cannot be sold or used elsewhere</TableCell>
      <TableCell>Relevant when evaluating ROI against alternative LPT uses (delegating to another Orchestrator)</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

<Note>
  Unlike Gateways, Orchestrators do not pay for the jobs they process - they are paid. The cost structure
  is infrastructure and staking, not service fees.
</Note>

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

## Payment Flow End-to-End

This is the complete flow from Gateway payment through Orchestrator receipt to Delegator distribution.

```mermaid theme={"theme":{"light":"github-light","dark":"dark-plus"}}
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#18794E', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3CB540', 'lineColor': '#3CB540', 'mainBkg': '#18794E', 'nodeBorder': '#3CB540', 'clusterBkg': 'transparent', 'clusterBorder': '#3CB540', 'titleColor': '#3CB540', 'edgeLabelBackground': 'transparent', 'textColor': '#3CB540', 'nodeTextColor': '#fff'}}}%%
flowchart LR
    A["Gateway"] -->|"PM tickets\n(ETH on Arbitrum)"| B["Orchestrator"]
    B -->|"Fee cut\n(% retained)"| C["Orchestrator earnings"]
    B -->|"Fee pool\n(% to delegators)"| D["Delegator pool"]

    E["Protocol inflation"] -->|"LPT rewards\neach round"| B
    B -->|"Reward cut\n(% retained)"| F["Orchestrator LPT"]
    B -->|"Reward pool\n(% to delegators)"| G["Delegator LPT pool"]

    classDef default fill:#1a1a1a,color:#fff,stroke:#2d9a67,stroke-width:2px
```

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

## Operator Models

Orchestrators operate for different reasons. The earnings model looks different depending on context.

<AccordionGroup>
  <Accordion title="GPU miner (earning from idle hardware)" icon="microchip">
    If you have GPU hardware already running - mining, rendering, or sitting idle - adding Livepeer
    Orchestrator workloads converts spare capacity into ETH service fees and LPT rewards.

    The incremental cost is electricity and a small slice of GPU time. The marginal earnings are
    service fees (proportional to workload volume) plus LPT rewards (proportional to stake).

    This model favours operators with high-end consumer or prosumer GPUs (RTX 3090, 4090, A100, H100)
    and reliable connectivity. The solo-operator path is documented in the
    <LinkArrow href="/v2/orchestrators/quickstart" label="Orchestrator Quickstart" newline={false} />.
  </Accordion>

  <Accordion title="Commercial GPU operator (serving workloads at scale)" icon="building">
    Commercial Orchestrators serving application workloads (Daydream, Livepeer Studio, custom AI
    products) operate differently from solo GPU miners.

    Revenue is primarily from service fees rather than inflation rewards. The key metrics are
    throughput, latency, and reliability - not stake size. Pricing strategy matters more, and
    direct relationships with high-volume Gateways are common.

    This model requires understanding Gateway selection mechanics in depth. See
    <LinkArrow href="/v2/orchestrators/concepts/capabilities" label="Gateway Selection" newline={false} /> for
    the factors Gateways weigh.
  </Accordion>

  <Accordion title="Infrastructure business (pool operation)" icon="server">
    Pool operators run the Orchestrator process and LPT staking infrastructure, then accept GPU
    workers from contributors who want to earn without managing the on-chain complexity.

    Revenue for pool operators typically comes from a fee charged to workers (percentage of their
    earnings) or from running some of the GPUs in the pool themselves.

    This model combines the earnings from running GPU compute with revenue from managing the protocol
    layer on behalf of workers.
  </Accordion>

  <Accordion title="Delegator-focused (earning rewards without compute)" icon="coins">
    An Orchestrator that holds substantial self-stake but operates at low capacity or joins a pool
    earns primarily from inflation rewards rather than service fees.

    High Reward Cut retains more LPT per round. Low Reward Cut attracts more delegated stake, which
    increases the Orchestrator's share of the total round reward.

    This model is most relevant for large LPT holders evaluating whether to self-operate versus
    delegating to an existing Orchestrator.
  </Accordion>
</AccordionGroup>

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

## Configuring Prices

Orchestrators set three categories of pricing parameter at startup or via `livepeer_cli`:

### Base price

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
# Price per pixel per second for video transcoding
-pricePerUnit=1000

# Enable automatic price adjustment based on network conditions
-autoAdjustPrice=true
```

### AI capability pricing

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
# Per-pipeline, per-model AI pricing (JSON file path)
-pricePerCapability=/path/to/ai-prices.json
```

Example `ai-prices.json`:

```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
{
  "capabilities_prices": [
    {
      "pipeline": "text-to-image",
      "model_id": "stabilityai/stable-diffusion-3-medium-diffusers",
      "price_per_unit": 4768371,
      "pixels_per_unit": 1
    },
    {
      "pipeline": "audio-to-text",
      "model_id": "openai/whisper-large-v3",
      "price_per_unit": 15000,
      "pixels_per_unit": 1
    }
  ]
}
```

### Per-Gateway pricing

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
# Set a different price for a specific Gateway address
-pricePerGateway='{"0xGatewayAddress": 800}'
```

Per-Gateway pricing allows commercial Orchestrators to negotiate rates with high-volume Gateways
independently of the base network price.

See <LinkArrow href="/v2/orchestrators/guides/payments-and-pricing/pricing-strategy" label="Pricing Strategy" newline={false} /> for competitive pricing guidance and current network rate benchmarks.

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

## Attracting Delegators

Delegated stake increases an Orchestrator's share of inflation rewards and improves its Active Set
ranking. Attracting and retaining Delegators is therefore an economic lever for Orchestrators.

Delegators evaluate Orchestrators on:

* **Reward Cut** - lower Reward Cut means more LPT to Delegators per round
* **Fee Cut** - lower Fee Cut means more ETH to Delegators from service fees
* **Reliability** - missed reward calls mean Delegators receive no rewards for that round
* **Reputation** - track record of uptime, performance, and community engagement
* **Stake already committed** - larger self-stake signals greater operator commitment

The Livepeer Explorer shows all active Orchestrators and their current cut settings, stake, and
recent reward-calling history. Delegators use this to compare options.

See <LinkArrow href="/v2/orchestrators/guides/staking-and-rewards/attracting-delegates" label="Attracting Delegators" newline={false} /> for operator strategies.

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

## Related Pages

<CardGroup cols={2}>
  <Card title="Orchestrator Role" icon="user-gear" href="/v2/orchestrators/concepts/role" arrow horizontal>
    What Orchestrators are and how the role has evolved.
  </Card>

  <Card title="Orchestrator Capabilities" icon="gears" href="/v2/orchestrators/concepts/capabilities" arrow horizontal>
    Workload types and how Gateways select Orchestrators.
  </Card>

  <Card title="Pricing Strategy" icon="tag" href="/v2/orchestrators/guides/payments-and-pricing/pricing-strategy" arrow horizontal>
    How to set competitive prices for video and AI workloads.
  </Card>

  <Card title="Gateway Business Model" icon="chart-line" href="/v2/gateways/concepts/business-model" arrow horizontal>
    The buy-side view - how Gateways pay and what they maximise.
  </Card>
</CardGroup>
