Safeguard
Developer Tools•

How do you shrink a fuzzing corpus without losing coverage?

Use libFuzzer's merge mode into an empty directory. It keeps inputs that add new coverage and drops the rest. Keep crash regressions in a separate folder.

Safeguard Security Team
4 min read

With libFuzzer, run the fuzz binary with -merge=1 and an empty directory first, followed by your old corpus directory. Inputs that trigger new coverage are copied into the first directory, giving a smaller corpus with the same reach. Keep crash regression files in a separate folder so they are never dropped.

Why a corpus grows too big

A fuzzer saves every input that reaches new code. Over weeks the folder fills with thousands of files, and many overlap. Large corpora slow down CI start up, take space in caches and make pull request runs heavy.

Minimizing keeps the inputs that matter and removes redundant ones.

What the documentation says

The LLVM libFuzzer docs describe merge mode this way: inputs from the second and later corpus directories that trigger new coverage are copied into the first directory. The example uses a new, empty directory as the first argument to hold the minimized corpus.

So the command has the shape:

./my_fuzzer -merge=1 new_corpus/ old_corpus/

After it finishes, new_corpus holds the useful subset. Check it, then replace the old directory.

Steps

  1. Back up the old corpus, or confirm it is in version control or a cache you can restore.
  2. Create an empty directory.
  3. Run merge mode with the empty directory first.
  4. Run the fuzzer over the new corpus without fuzzing, to confirm it still executes cleanly.
  5. Compare coverage if your build reports it. It should match the old corpus closely.
  6. Swap the directories and update the cache key in CI.

What not to merge

ItemTreat as
Working corpusMerge freely
Crash reproducers from past bugsKeep separately, never merge away
Hand written seeds for important formatsKeep in a seed directory
Files from untrusted usersReview for personal data first

Crash reproducers deserve special care. A past crash input may add no new coverage at all once the bug is fixed, which means merge mode could drop it. But you want it forever as a regression check. The docs say that passing files instead of directories reruns them without fuzzing, so store them apart and replay them as a quick CI step.

How often to do it

Monthly is plenty for most teams, or when the corpus passes a size you set. Do it after a large refactor too, since old inputs may no longer reach what they once did.

What QA should check afterwards

Run the replay of the minimized corpus on the current build and on the previous release. The same inputs should pass on both. If a minimized input crashes the new build, you may have a fresh defect, not a corpus problem. Report it as you would any security bug.

Also note the date and the size before and after in the test log. It helps explain a sudden drop in CI time, and it gives an auditor a record of how the testing evolved.

Try it yourself

Click through it at your own pace, or open it full screen. Watch how removing what does not matter makes the useful signal clearer, the same goal as corpus merging.

Safeguard's reachability analysis applies that idea to dependency findings. Start with the free scan to see it on your own code.

Quick check

Will merging lose bug finding power?

It keeps inputs that add coverage, so reach stays about the same. It can drop inputs that were only redundant.

Should crash files be in the merged directory?

No. Store them separately and replay them as regression checks.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.