Safeguard
Security Guides•

Static vs dynamic reachability: which approach fits which team

Static reachability reads code, dynamic reachability watches it run. Compare coverage, cost, blind spots and when to combine them for vulnerability triage.

Safeguard Security Team
3 min read

Static reachability reads code and builds a call graph without running anything. Dynamic reachability observes which functions actually execute in tests or production. Static gives broad coverage early. Dynamic gives ground truth for the paths exercised. Many teams use static first and add dynamic evidence for the findings that matter most.

What each one does

Static. The tool parses source or compiled output, builds the call graph, and checks for a path from entry points to the vulnerable function. It needs no deployment and works in a pull request.

Dynamic. A sensor, profiler or test run records the functions that load and execute. A vulnerable function that appears in the record is proven reachable for that run. One that never appears is only unobserved.

Side by side

QuestionStaticDynamic
Needs running appNoYes
CoverageEvery path in codeOnly paths exercised
Fits in CI on a branchYesOnly with good tests
Can miss dynamic callsYesLess likely
Can report unreal pathsYesNo for observed calls
Setup effortLowHigher

The blind spots are opposite

Static analysis over or under counts when calls are resolved at runtime. Dynamic analysis is silent about any path your tests and traffic never hit. A rarely used admin function can be reachable and still show no executions for months.

That second point matters. Absence in a trace is not proof of safety. It is proof you did not see it.

When static is enough

  • You triage dependency findings in pull requests.
  • Your languages have solid call graph support.
  • You want a quick first sort of a large backlog.

When to add dynamic evidence

  • A finding is critical and static says not reachable, and you need more confidence.
  • Your code relies on reflection, plugins or dependency injection.
  • You have strong test coverage or production telemetry already.

A combined workflow

  1. Run static analysis on every change.
  2. For reachable results, fix by severity and exposure.
  3. For critical unreachable results, check whether tests or telemetry ever touched the function.
  4. Record the evidence and the date.

Read the comparison of reachability limits before relying on either alone.

A short example

A service parses uploaded files with a library. Static analysis finds a path to the flawed parser and marks it reachable. Dynamic tracing from a week of staging traffic never shows the parser running, because the test uploads are all one simple format. Neither result is wrong. The static one says the path exists. The dynamic one says your tests never used it. For a flaw triggered by an unusual file type, the static result is the one to act on.

Quick check

Which is more accurate?

Neither across the board. Dynamic is exact for what ran. Static covers what could run. They answer slightly different questions.

Can I skip dynamic entirely?

Yes for most triage. Add it where the cost of a wrong not reachable call is high.

Safeguard offers reachability analysis as part of its dependency scanning. A free scan shows how it reports paths.

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.