---
title: Code style
description: OpenPerf rules for code and tests, on top of the shared rules in AGENTS.md.
---

## Code

- Write code for cases that occur. No fallbacks, duplicate checks or values without a consumer.
- Make each decision in one place: the layer that owns it. Others rely on it.
- An arrow function whose body doesn't fit on one line gets a block with `return`. Components returning JSX are the exception.
- Document what a published package exports from its entry points, such as `@openperf/sdk/node`, only where the name and type don't tell the whole story: defaults, limits, value formats, errors and when it does nothing. Skip a JSDoc that restates the name. Write one or two plain sentences, state each fact once where it applies, put defaults in `@default` and errors in `@throws`. Types, interfaces and classes get no JSDoc; document their properties instead. Internal code stays without comments.

## Tests

- Test logic that can break on its own: branching, parsing, edge cases, security checks. Don't test code that only restates itself, such as templates, lookup tables or config.
- A test that needs live stores is `*.integration.test.ts`. Everything else is `*.test.ts` with mocks.

## ClickHouse migrations

- One statement per file, and every statement can run twice (`IF NOT EXISTS`, no unguarded backfills): dbmate may run a file again after a partial failure.
- Retention is a `TTL` in the table DDL; change it with `ALTER TABLE … MODIFY TTL` in a new migration.

## ClickHouse reads

- Lists, summaries and charts read hourly rollups through `buildRollupSource`: full hours come from the rollup, the edges of the window from the raw table. Raw tables answer drill-downs by a selective key: a trace, a fingerprint, a log page, the hours a rollup picked for samples.
- Each rollup in `telemetry/libs/rollups` mirrors its materialized view. `rollups.integration.test.ts` fails when the two drift.
- Keep aggregate states bounded: `quantilesTDigest` for durations, `uniqCombined(12)` for unique counts.
- Measure a read change with `bun run bench --project <id> --from <iso> --to <iso>` on a dense dataset. It reports time, rows, bytes and peak memory per scenario with caches off.
