> ## Documentation Index
> Fetch the complete documentation index at: https://whatsapp-rust.jlucaso.com/llms.txt
> Use this file to discover all available pages before exploring further.

# June 12, 2026 — Binary size CI: per-PR budget gate and historical tracking

> Every PR now runs a release build and checks stripped size and .text growth against an absolute budget. A Chart.js series on gh-pages tracks every main merge over time.

PR [#859](https://github.com/oxidezap/whatsapp-rust/pull/859) adds a `Binary Size` GitHub Actions workflow. It gates PRs on binary growth and keeps a historical size series. This closes the feedback loop that previously allowed dependency bloat and cross-crate monomorphization creep to go undetected between audits.

## What is tracked

All metrics come from a single release build. This build uses `fat LTO`, `codegen-units=1`, and keeps symbols so `cargo bloat` can reuse it without recompiling.

| Metric                                         | Signal                                                                                                      |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **Stripped file size**                         | Shows how much the shipping binary grew                                                                     |
| **`.text` section**                            | Measures code bloat from generic instantiation that persists even in stripped builds                        |
| **Allocated size** (`text+data+bss`)           | Catches static data tables that never appear in `.text`                                                     |
| **`.text` per crate** (`cargo bloat --crates`) | Attributes `.text` growth to individual workspace crates and `std`; everything else appears as "other deps" |
| **LLVM IR lines/copies** (`cargo llvm-lines`)  | Detects monomorphization growth before linking, cheaply                                                     |
| **Crate count** (`Cargo.lock`)                 | Signals when a new dependency was added                                                                     |

## PR gate

Every PR gets a sticky comment with all metric deltas and a per-crate top-movers table. The job **fails** when either of the two gated metrics exceeds its absolute per-PR budget:

| Metric          | Budget   |
| --------------- | -------- |
| Δ stripped size | ≤ 64 KiB |
| Δ `.text`       | ≤ 32 KiB |

Absolute budgets catch real regressions on large binaries that percentage thresholds would hide. Sizes are deterministic across the pinned toolchain, so deltas are noise-free.

## Escape hatch

Add the **`size-increase-ok`** label to a PR and re-run the failed job to downgrade the gate to a warning. Use this for expected jumps such as toolchain bumps, accepted new dependencies, or deliberate feature additions. The size increase still lands in the historical series.

<Note>
  The workflow queries the label live at gate time (not from the frozen event payload), so adding the label and re-running always works, even after the workflow has already triggered.
</Note>

## Historical series

The push job stores every main-branch measurement at `dev/binary-size` on gh-pages via [`github-action-benchmark`](https://github.com/benchmark-action/github-action-benchmark). A `102%` alert threshold posts a comment on the offending commit as a post-merge safety net for regressions that slipped through the PR gate (e.g. via the label).

Charts: [https://oxidezap.github.io/whatsapp-rust/dev/binary-size/](https://oxidezap.github.io/whatsapp-rust/dev/binary-size/)

## Baseline semantics

The PR baseline is the `size-metrics` artifact from the **latest successful main run**, not the `merge-base` commit. A long-lived stale PR can therefore show deltas inherited from main merges that happened while it sat open — rebase to clear them.

## Fork PRs

Fork PRs run with a read-only token and receive the job summary and gate result but no PR comment.
