Skip to main content
CodSpeed provides dedicated integrations for several languages, but you do not need one to start benchmarking. The CodSpeed CLI can benchmark any executable program: define the commands to measure in a codspeed.yml configuration file, and run them locally or in CI. This approach works for any language or toolchain, even if it does not have a dedicated integration yet, e.g., Zig, OCaml, or Swift. It is also a good fit for benchmarking a program end to end, like a CLI tool or a compiler.
Benchmarks defined this way measure a whole command, including process startup. If your language has a dedicated integration, prefer it to benchmark individual functions. Otherwise, you can also build a custom harness to measure only a subpart of your program.If you would like a dedicated integration for your language, let us know on Discord or open a GitHub issue.

Installing the CodSpeed CLI

Install the CodSpeed CLI using the installation script:
curl -fsSL https://codspeed.io/install.sh | sh
After installation, authenticate with your CodSpeed account by running codspeed auth login.

Defining the benchmarks

Create a codspeed.yml file at the root of your repository. Each item in the benchmarks list describes a command to benchmark:
codspeed.yml
$schema: https://raw.githubusercontent.com/CodSpeedHQ/codspeed/refs/heads/main/schemas/codspeed.schema.json

benchmarks:
  - name: parse large file
    exec: ./my-tool parse fixtures/large.json

  - name: render template
    exec: ./my-tool render fixtures/template.html
    options:
      max-time: 2s
The exec field is the command to run. Build the executable beforehand with your usual toolchain, CodSpeed measures the command as is. See the CLI configuration reference for all available fields and options.

Running the benchmarks locally

Build your program, then run all the benchmarks defined in the configuration file with the walltime instrument:
terminal
$ codspeed run -m walltime

►►► Running the benchmarks

Executing: parse large file
Completed 13 warmup rounds
Warmup done, now performing 20 rounds

Executing: render template
Completed 23 warmup rounds
Warmup done, now performing 68 rounds

►►► Uploading results
Linked repository: [...]
Performance data uploaded

►►► Benchmark results

┌──────────────────┬─────────────┐
│ Benchmark        │ Measurement │
├──────────────────┼─────────────┤
│ parse large file │ 14.10 ms    │
├──────────────────┼─────────────┤
│ render template  │ 6.91 ms     │
└──────────────────┴─────────────┘

To see the full report, visit: https://app.codspeed.io/[...]

Running the benchmarks in your CI

To generate performance reports, you need to run the benchmarks in your CI. This allows CodSpeed to automatically run benchmarks and warn you about regressions during development.
If you want more details on how to configure the CodSpeed action, you can check out the Continuous Reporting section.
Here is an example of a GitHub Actions workflow that runs the benchmarks and reports the results to CodSpeed on every push to the main branch and every pull request: The walltime instrument runs on CodSpeed Macro Runners, bare-metal machines that deliver low-variance measurements:
Contrary to other CI usages, the run input is intentionally omitted here: this is what makes the action run the benchmarks defined in your configuration file.

Advanced

Benchmarking a subpart of your program

Benchmarks defined with exec measure the whole command, including process startup. To measure only a specific section of your program, e.g., its core processing loop, you can build a custom harness with the instrument-hooks library. A custom harness instruments your program directly: it tells CodSpeed exactly when the measured section starts and stops. The library is a single C file that integrates with virtually any language through FFI. Follow the custom harness guide to build one. Since your program then embeds its own harness, declare it with entrypoint instead of exec in the configuration file:
codspeed.yml
benchmarks:
  - name: parse large file
    exec: ./my-tool parse fixtures/large.json
    entrypoint: ./my-tool parse fixtures/large.json
Similarly, to benchmark a harness-equipped command without a configuration file, use codspeed run instead of codspeed exec:
codspeed run -m walltime -- ./my-tool parse fixtures/large.json

Next Steps

CodSpeed CLI

Explore all the commands, instruments, and configuration options of the CodSpeed CLI.

Walltime instrument

Learn more about the walltime instrument and how to use it.

Profiling

Learn how to use flamegraphs and profiling data to optimize your code.

Performance checks

Catch regressions automatically on every pull request.