Safeguard
Application Security

How Snyk Code's incremental scanning speeds up repeated s...

Snyk Code speeds up repeat SAST scans on large codebases by re-analyzing only changed files instead of the whole repository each time.

Aman Khan
AppSec Engineer
Updated 7 min read

When a monorepo grows past a few hundred thousand lines, static analysis security testing (SAST) starts to hurt. A full scan that took 90 seconds on a 20,000-line service can stretch to 20 or 30 minutes once the codebase crosses into the millions of lines, and if every pull request triggers a full re-scan, developers either wait or start ignoring the results. Snyk Code, Snyk's SAST engine, addresses this with incremental scanning: rather than re-analyzing every file on every run, it identifies what changed since the last scan and limits the heavy analysis work to that delta. This post walks through how that mechanism works, why it matters for large codebases, where it fits into CI/CD, and where its limits are — as a technical explainer, not a vendor comparison.

What is incremental scanning in Snyk Code?

Incremental scanning is the practice of re-analyzing only the files that changed since a previous scan, instead of re-running static analysis across the entire codebase from scratch. Snyk Code's engine builds an internal program representation — including symbol tables, control-flow, and data-flow information — for the files it analyzes. On a full first scan, it does this for every file in the project. On subsequent scans, Snyk Code compares the current working tree (or the latest commit) against what it last analyzed, and confines the expensive rebuild-and-rule-evaluation work to files that are new or modified, reusing previously computed results for everything untouched. This is the same general pattern used by incremental compilers and incremental type-checkers: full analysis is expensive, but most of a large codebase doesn't change between two runs, so there's no reason to redo work whose inputs haven't moved.

How does Snyk Code decide which files to re-scan?

It decides by diffing the current state of the repository against the last analyzed snapshot, typically using file content hashes or commit-level changes rather than timestamps alone. Snyk's CLI and IDE integrations track what was last submitted for analysis — for the CLI (snyk code test), this is scoped to the local project state between invocations; for IDE plugins (VS Code, IntelliJ, and others), it happens continuously as a developer edits and saves files, so only the file being worked on, plus files it directly affects, needs fresh analysis. For SCM-integrated checks on GitHub, GitLab, and Bitbucket, Snyk evaluates the pull request diff against the target branch, which naturally narrows the set of files under fresh scrutiny to whatever the PR actually touches — often a handful of files even in a repository with tens of thousands of them.

Why does this matter more as codebases get larger?

It matters because scan time in naive SAST tools tends to scale with total lines of code, not with the size of a change, and that gap widens as a codebase grows. A team merging 15 pull requests a day against a 2-million-line monorepo, each touching an average of 5-10 files, is doing a trivial amount of net new analysis work per PR — but a full-scan-on-every-push model would force each of those 15 checks to pay the cost of analyzing the other 1.99 million lines that didn't change. Incremental scanning collapses that cost down toward the size of the diff, which is what makes SAST feasible to run as a blocking check on every pull request rather than as an overnight batch job. This is the same economic argument that pushed CI systems toward incremental test selection and pushed compilers toward incremental builds: the marginal cost of a change should track the size of the change.

How does incremental scanning fit into pull request checks?

It fits in by letting Snyk post results on a PR within the time budget of a normal CI job instead of a separate overnight pipeline. When Snyk Code is wired into a GitHub, GitLab, or Bitbucket integration, opening or updating a pull request triggers analysis scoped to the changed files in that diff, and the results — new issues introduced by the PR — are surfaced as check annotations or PR comments. Because the analysis is bounded by the diff rather than the whole repository, a PR that changes three files gets feedback in roughly the time it takes to analyze three files plus any code they call into, not the time it takes to analyze the entire service. That turnaround is what allows SAST feedback to arrive before a reviewer even opens the PR, rather than as a nightly report that lands long after the code has already merged.

Does incremental scanning ever miss issues that a full scan would catch?

Yes, which is why incremental scanning is a complement to full scans rather than a full replacement for them. Static analysis for vulnerability classes like taint-style injection or path traversal often requires reasoning about data flow across file and function boundaries — a source in one file, a sink in another file that wasn't touched by the current change. If the last full analysis is stale relative to how the surrounding, unchanged code actually behaves at runtime (for example, after a large refactor several weeks prior that was itself scanned incrementally in slices), there's a theoretical risk of drift between the cached understanding of unchanged files and their true current state. This is a known characteristic of incremental-analysis systems generally, not unique to any one vendor, and it's the reason most SAST workflows still schedule periodic full scans — commonly on a cadence like nightly or weekly against the default branch — alongside incremental PR-level checks, so cached results get refreshed and any drift gets corrected before it compounds.

How does caching interact with rule and engine updates?

Rule and engine updates typically invalidate the relevant cached results, since a changed rule set or model can produce different findings on code that hasn't changed at all. When Snyk ships an update to its Snyk Code analysis engine or its vulnerability rule set, cached results computed under the previous version no longer reliably represent what the current version would report, so an update event of this kind is a natural trigger for a broader re-scan rather than continued reliance on the incremental cache. This is one of the reasons SAST vendors, including Snyk, recommend not treating incremental CI scans as the sole source of truth indefinitely — cache invalidation on engine or rule changes, combined with scheduled full scans, is what keeps the incremental fast path from silently going stale.

How Safeguard Helps

Safeguard doesn't replace or compete with a SAST engine like Snyk Code — it sits downstream, correlating whatever SAST findings your toolchain produces with the rest of your software supply chain: dependency provenance, SBOM data, build attestations, and CI/CD pipeline integrity. That matters specifically because incremental scanning, as described above, introduces a legitimate question every security team should be able to answer on demand: when was this service last fully scanned, versus incrementally, and does that gap line up with an actual risk window? Safeguard ingests scan metadata — timestamps, scope, and tool version — alongside SBOM and build provenance data, so a team can see at a glance whether a service's last full SAST pass predates a dependency change or a rule-engine update that should have triggered a re-check. Rather than trusting that "the PR check passed" is equivalent to "this code has been fully analyzed," Safeguard gives security and platform teams a single place to verify scan coverage, freshness, and provenance across every repository, regardless of which SAST, SCA, or secrets-scanning tool produced the underlying result. For organizations running SAST at scale across dozens or hundreds of repositories, that visibility layer is what turns "we run scans" into "we can prove what was scanned, when, and how completely."

Never miss an update

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