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

# Macro Runners

> Use CodSpeed's bare-metal runners for precise walltime measurements in your CI pipeline

export const CIWorkflow = ({minimal = false, enableWorkflowDispatch = true, runsOn = "ubuntu-latest", highlight = [], mode, modes, submodules = false, preSteps = [], buildSteps = ["# ...", "# Setup your environment here:", "#  - Configure your Python/Rust/Node version", "#  - Install your dependencies", "#  - Build your benchmarks (if using a compiled language)", "# ..."], benchmarkCommand = ["<Insert your benchmark command here>"], jobName = "Run benchmarks", env = {}}) => {
  const modeList = modes || (mode ? [mode] : undefined);
  if (!modeList || modeList.length === 0) {
    throw new Error("mode or modes is required");
  }
  const indent = (lines, depth) => {
    const reindentedLines = lines.map(l => l.length === 0 ? l : (" ").repeat(depth) + l);
    return reindentedLines.join("\n");
  };
  const workflowDispatchSection = enableWorkflowDispatch ? "  # `workflow_dispatch` allows CodSpeed to trigger backtest\n" + "  # performance analysis in order to generate initial data.\n" + "  workflow_dispatch:\n" : "";
  let yaml = "";
  if (!minimal) {
    yaml += `
name: CodSpeed Benchmarks

on:
  push:
    branches:
      - "main" # or "master"
  pull_request:
`;
    yaml += workflowDispatchSection;
  }
  yaml += `
jobs:
  benchmarks:
    name: ${jobName}
    runs-on: ${runsOn}`;
  if (!minimal) {
    yaml += `
    permissions: # optional for public repositories
      contents: read # required for actions/checkout
      id-token: write # required for OIDC authentication with CodSpeed`;
  }
  if (preSteps.length > 0) yaml += "\n" + indent(preSteps, 4);
  yaml += `
    steps:
      - uses: actions/checkout@v5`;
  if (submodules) {
    const value = typeof submodules === "string" ? submodules : "true";
    yaml += `\n        with:\n          submodules: ${value}`;
  }
  yaml += "\n" + indent(buildSteps, 6);
  const modeValue = modeList.join(",");
  yaml += `
      - name: Run the benchmarks
        uses: CodSpeedHQ/action@v4
        with:
          mode: ${modeValue}`;
  if (benchmarkCommand.length > 0) {
    const indentedBenchCommand = benchmarkCommand.length > 1 ? benchmarkCommand[0] + "\n" + indent(benchmarkCommand.slice(1), 12) : benchmarkCommand;
    const runLine = indent(["run: "], 10) + indentedBenchCommand;
    yaml += `\n${runLine}`;
  }
  const envEntries = Object.entries(env);
  if (envEntries.length > 0) {
    const envLines = ["env:", ...envEntries.map(([k, v]) => `  ${k}: ${v}`)];
    yaml += "\n" + indent(envLines, 8);
  }
  return <CodeBlock language="yaml" highlight={JSON.stringify(highlight)} {...minimal || ({
    filename: ".github/workflows/codspeed.yml",
    icon: "github"
  })}>
      {yaml}
    </CodeBlock>;
};

CodSpeed Macro Runners are **dedicated bare-metal machines** managed by CodSpeed
that provide a stable, isolated environment for running your benchmarks. Unlike
traditional CI runners, macro runners eliminate noise from virtualization and
shared resources, enabling **precise [walltime](/instruments/walltime)
measurements** with low variance.

<Tip>
  Read our detailed post on [the consistency of CodSpeed Macro runners compared
  to traditional CI
  runners](https://codspeed.io/blog/benchmarks-in-ci-without-noise).
</Tip>

## What are Macro Runners?

Macro runners are **16-core ARM64 bare-metal machines** with 32 GB RAM,
specifically optimized for consistency in performance measurements. They
complement CodSpeed's [CPU simulation](/instruments/cpu) by providing an
environment where walltime measurements are reliable and reproducible.

### When to Use Macro Runners

Macro runners are ideal when you need to measure:

* **System calls and I/O operations** that are excluded from the CPU Simulation
  instrument
* **End-to-end performance** including network, disk, and system interactions
* **Walltime benchmarks** where actual execution time matters
* **Integration tests** that require a complete system environment

<Tip>
  **CPU Simulation vs Walltime with Macro Runners**

  Use the [CPU Simulation instrument](/instruments/cpu) for pure algorithmic
  performance and the [Walltime instrument](/instruments/walltime) with Macro
  Runners for system-level performance that includes I/O operations.
</Tip>

## Pricing and Usage

### Free Tier

* **600 minutes per month** included with all plans
* Available for both Free and Pro plans
* Perfect for getting started with walltime measurements

### Additional Usage

* **\$0.032 per minute** after the free 600 minutes
* Volume discounts available for Enterprise plans
* Transparent, pay-as-you-use pricing

<Note>
  **Open Source Projects**

  We're happy to support open source projects with additional free minutes beyond
  the standard 600 minutes/month limit. [Contact us](mailto:contact@codspeed.io)
  with details about your project.
</Note>

## Setup with GitHub Actions

<Steps>
  <Step title="Prerequisites">
    Ensure you have:

    * `CodSpeedHQ/action >= 3.1.0`
    * A GitHub organization (macro runners don't work with personal accounts)
    * CodSpeed enabled for your repository

    <Note>
      **Organization Required**: Macro runners are only available for GitHub organizations, not personal accounts. This is due to GitHub's permission requirements for self-hosted runners.
    </Note>
  </Step>

  <Step title="Update your workflow">
    Replace `runs-on: ubuntu-latest` with `runs-on: codspeed-macro` in your GitHub Actions workflow:

    {" "}

    <CIWorkflow minimal runsOn="codspeed-macro" mode="walltime" highlight={[4]} />

    The workflow setup is identical to
    [regular CodSpeed integration](/integrations/ci/github-actions#2-create-the-benchmarks-workflow),
    just with a different runner.
  </Step>

  <Step title="Optimize caching (optional)">
    If you use caching, include `${{ runner.arch }}` in your cache keys to avoid cache misses:

    ```yaml {4} theme={null}
    - uses: actions/cache@v4
      with:
        path: # insert your cache path here
        key: pip-${{ hashFiles('pyproject.toml') }} # [!code --]
        key: pip-${{ runner.arch }}-${{ hashFiles('pyproject.toml') }} # [!code ++]
    ```
  </Step>
</Steps>

## Repository Access Configuration

### Private Repositories

Macro runners work automatically with private repositories in your organization.

### Public Repositories

For public repositories, you need to explicitly enable macro runner access:

<Steps>
  <Step title="Navigate to organization settings">
    Go to your GitHub organization settings: **Organization Settings** → **Actions** → **Runner groups** → **Default**
  </Step>

  <Step title="Enable public repository access">
    Allow the runner group to be used by public repositories:

    <Frame>
      <img src="https://mintcdn.com/codspeed/_9gjNuBHMdsdxHot/instruments/walltime/assets/github-public-repo-access.png?fit=max&auto=format&n=_9gjNuBHMdsdxHot&q=85&s=fd62b02d6c9d620f4fa8723334d568c3" className="rounded-xl w-full max-w-lg mx-auto" alt="Enabling macro runners for public repositories" width="1400" height="372" data-path="instruments/walltime/assets/github-public-repo-access.png" />
    </Frame>
  </Step>
</Steps>

## Next Steps

<CardGroup cols={2}>
  <Card title="Walltime Instrument" icon="stopwatch" href="/instruments/walltime">
    Learn how to use the walltime instrument with macro runners
  </Card>

  <Card title="Understanding Metrics" icon="chart-line" href="/features/understanding-the-metrics">
    Interpret your walltime benchmark results
  </Card>

  <Card title="Performance Checks" icon="shield-check" href="/features/performance-checks">
    Set up automated performance regression detection
  </Card>

  <Card title="Pricing Details" icon="credit-card" href="https://codspeed.io/pricing">
    View detailed pricing and plan options
  </Card>
</CardGroup>
