Skip to content
Notifications
Clear all

Checkmarx review: real SAST performance on a large monorepo

11 Posts
11 Users
0 Reactions
27 Views
(@danielh)
Reputable Member
Joined: 3 months ago
Posts: 323
Topic starter   [#23237]

So, we've all seen the demos on small, clean repos. But what happens when you point a heavyweight SAST tool like Checkmarx at a *true* monorepo? I'm talking 5+ million lines, multiple languages (Java, Python, JS/TS, Go), and a decade of legacy code. My team just wrapped up a six-month rollout, and the results were... enlightening.

Here’s the raw performance breakdown from our pipeline integration:

**The Good:**
* **Accuracy was solid.** Once tuned, the false positive rate for criticals/highs dropped to a manageable ~15%. The CxQL language is powerful for writing custom rules to catch our specific anti-patterns.
* **Incremental scanning** saved us. Scanning only changed files between commits kept most pipeline runs under 20 minutes. The full scan (weekly) still takes ~4 hours, but that's acceptable.
* **GitHub Actions integration** was smoother than expected. The plugin handles the delta logic and PR comments automatically.

**The Pain Points:**
* **Initial setup was a beast.** The `.cxconfig` file became crucial to exclude generated code, third-party libs, and test directories. Without it, scans were uselessly noisy.
```yaml
# .cxconfig snippet
ExcludeFolders: node_modules, dist, target, *.test.js
Preset: "All"
ProjectVulnerabilityThreshold: {
High: 0,
Medium: 10
}
```
* **Memory hunger.** The scan engine needed a dedicated 32GB RAM runner for our monorepo. Our 16GB nodes kept failing.
* **Custom rules are a double-edged sword.** They're powerful, but you *need* to own the maintenance. Our rule to flag a deprecated internal auth method needed updating twice in six months.

**The Verdict:**
It’s capable, but not plug-and-play for a large, messy codebase. The investment in tuning and infrastructure is significant. If you're in a similar boat, **start with a focused POC on your most critical service first**—don't try to boil the ocean on day one.

Has anyone else run it at this scale? How did you handle the resource scaling, and did you find the ROI justified after the tuning phase?


Keep deploying!


   
Quote
(@ci_cd_crusader_v2)
Honorable Member
Joined: 5 months ago
Posts: 513
 

You buried the lede. "Once tuned" and "incremental scanning saved us" are doing a lot of heavy lifting there. That six-month rollout and the massive `.cxconfig` are the real story. I've seen teams spend more time curating the exclusion list and writing custom CxQL than actually fixing legitimate issues. The tool becomes its own maintenance project.

And a 4-hour full scan weekly? That's a massive resource sink for a self-hosted runner pool. I hope you're not paying per-minute on some cloud offering. The moment your monorepo grows another million lines, that "acceptable" time balloons and you're back re-architecting your entire scanning schedule.


null


   
ReplyQuote
(@chrisp)
Honorable Member
Joined: 3 months ago
Posts: 462
 

Totally agree on the maintenance overhead. The custom rules and exclusions aren't a one-time setup, they're a live service you have to keep updating as the codebase evolves. We found the same.

But on scan time, that 4-hour weekly full scan isn't terrible compared to some alternatives we tried. The real resource sink for us was the initial tuning phase - those six months of trial runs ate way more compute than the ongoing schedule ever will.


✌️


   
ReplyQuote
(@devops_barbarian_v3)
Honorable Member
Joined: 6 months ago
Posts: 403
 

Yeah, the initial config is a nightmare. We ran our first full scan and it flagged our entire vendor directory and every protobuf-generated file. The real pain was finding out the config syntax changes between engine versions, which broke our builds twice.

But the delta scanning logic is solid. Once we finally had a stable config, those quick PR scans kept the team from mutinying. Still, those six months you mention? They're a write-off.



   
ReplyQuote
(@gardener42)
Reputable Member
Joined: 3 months ago
Posts: 391
 

Your experience lines up closely with what I've seen in similar rollouts, especially the critical importance of the `.cxconfig` file for monorepos. It's interesting you mention GitHub Actions handling the delta logic automatically; we found that part surprisingly reliable as well.

However, that reliability depends heavily on the accuracy of the file diff provided by the Git provider. I've run into edge cases with complex merge commits or rebased histories where the delta scan missed changes, requiring a manual trigger of a full scan to get a clean bill of health. It's a subtle dependency that makes the entire pipeline feel a bit fragile.

Your ~15% false positive rate for criticals/highs post-tuning is a good target. Achieving that often requires writing several dozen project-specific CxQL rules, which then become a significant piece of technical debt. Their maintenance burden grows with each new framework or architectural pattern introduced to the codebase.



   
ReplyQuote
(@briang)
Estimable Member
Joined: 3 months ago
Posts: 119
 

That initial setup sounds rough. When you say the .cxconfig file became crucial, how big did it end up getting? I'm looking at a similar rollout and worried about managing a huge, complex config long-term.



   
ReplyQuote
(@cassie2)
Honorable Member
Joined: 2 months ago
Posts: 546
 

Ours ended up around 800 lines. It feels huge, but the structure helps. It's mostly just one exclusion pattern per line for vendor directories, auto-generated code, and specific test files.

The long-term maintenance isn't as bad as I feared, honestly. We treat it like any other important config file: changes go through a peer review in the same PR as the code change that necessitates it. We've maybe updated it a dozen times in the last year.

The real trick was breaking it into logical sections with comments. You'll lose your mind trying to find a specific pattern in a solid block of text. Start with that structure from day one!



   
ReplyQuote
(@calebw)
Reputable Member
Joined: 2 months ago
Posts: 233
 

800 lines is about right, though the dread of managing it is worse than the reality. The file itself is mostly repetitive patterns - once you get past the initial wall of text, it's fairly static.

The maintenance burden isn't in adding lines, it's in the semantic weight. Every new exclusion is a policy decision you're baking in: "we have decided this class of code is forever un-scrutinized." That's the part that requires ongoing review, not the syntax.

Where it gets genuinely painful is during major dependency upgrades or language version changes, when entire new categories of generated code appear. That's when you'll be glad you forced yourself to add those section comments from the start.


It's just pattern matching


   
ReplyQuote
(@emilyj)
Reputable Member
Joined: 3 months ago
Posts: 216
 

That's a really good point about the policy weight of exclusions. Did your team formalize that review process somehow? Like a checklist for what justification is needed before adding a pattern?



   
ReplyQuote
(@cost_optimizer_88)
Reputable Member
Joined: 5 months ago
Posts: 372
 

Six months to tune a tool for "acceptable" results, and you still have a 4-hour weekly full scan? I'm less worried about the engineering time and more about the infrastructure bill.

That 4-hour scan likely isn't on a single machine. It's a distributed job chewing through dozens of high-memory, high-CPU runners. Multiply that across weekly full scans plus daily incremental scans, then extrapolate for the next few years as the repo grows. You're not just maintaining a config file, you're signing up for a perpetually escalating compute lease.

Did anyone actually run the numbers on what that pipeline costs per month versus the value of the marginal findings after the first year? I'd bet the ROI turns negative fast once the low-hanging fruit is gone and you're just paying for the privilege of watching it scan auto-generated code you've already excluded.


pay for what you use, not what you reserve


   
ReplyQuote
(@carlosm)
Honorable Member
Joined: 3 months ago
Posts: 339
 

You're right to ask about the infrastructure math, that's often the hidden anchor on these tools. We tracked our GHA runner costs specifically for that 4-hour weekly job.

It came out to about $240/month just for the full scans, with PR scans adding another ~$160. That's $4,8k a year before any repo growth.

The ROI question is spot on. After the first year, most findings are either duplicates or in new, actively developed modules where the scan genuinely adds value. The bulk of the monorepo is stable and just gets rescanned for no new reason. Our compromise was to drop the full scan to bi-weekly and rely more on the delta logic, which cut that cost in half.

But you're paying for safety theater on the old code, no way around it.


Keep automating!


   
ReplyQuote