Safeguard
Developer Tools•

Fuzzing in CI: short runs on pull requests or continuous runs?

How to schedule fuzzing: replay the corpus on every pull request, run time-boxed fuzzing nightly, and keep a long running job for critical parsers.

Safeguard Security Team
3 min read

Use three tiers. On every pull request, replay the saved corpus so old bugs stay fixed. Nightly, run each fuzz target for a fixed time. For the few parsers that handle the most untrusted data, run continuously on dedicated machines and feed results into your tracker.

Tier 1: corpus replay on every pull request

Replaying known inputs is fast and deterministic. In Go, a plain test run treats a fuzz test like a unit test and runs each seed entry against the target, reporting any failure. That makes the committed corpus a regression suite at no extra effort.

This tier should finish in seconds to a couple of minutes and block merges on failure.

Tier 2: time-boxed fuzzing on a schedule

New bugs need new inputs, and that takes run time. A nightly or weekly job runs each target for a set duration. Go supports this with a fuzz time setting that, by default, is indefinite, so always set it in CI or the job never ends.

Practical settings:

  • Ten to thirty minutes per target for a nightly run.
  • Save the corpus between runs as a cache or artifact so coverage accumulates instead of starting over each time.
  • Upload any new failing input as an artifact and open a ticket automatically.

Tier 3: continuous fuzzing for critical code

OSS-Fuzz is a public example of continuous fuzzing for established open source projects. Its FAQ says it uses several engines, including libFuzzer, AFL++ and Honggfuzz, and that it runs with sanitizers. It also states that it accepts established projects with a critical impact on infrastructure and user security, so it is not an option for every codebase.

For private code, you can copy the shape of it: a few machines, a build that produces sanitized fuzz binaries, a shared corpus store and a triage rota.

What to avoid

Do not run unbounded fuzzing on shared CI runners, since it can starve other jobs. Do not let new findings land in a channel nobody owns. Do not fail every pull request on a fuzz finding unrelated to the change, because the bug was already there. Route those to a ticket, and keep the pull request gate for corpus replay.

Measure whether it works

Track the number of targets, total fuzzing hours, coverage of the target code, and the time from crash report to fix. If coverage is flat for weeks, improve the seeds or the harness, or accept that the target is exhausted. The OSS-Fuzz FAQ lists exhausted coverage among the reasons a long run finds nothing.

Try it yourself

The continuous monitoring demo shows the idea of watching a codebase over time instead of once. Look at how findings appear after the initial scan, then compare that to a nightly fuzz job.

Click through it at your own pace, or open it full screen.

Quick check

Should a fuzz finding block the release?

If it is a memory corruption reachable from untrusted input, yes. Otherwise create a ticket with a due date and an owner.

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.