The Queue That Outgrew the Engines
CxSAST 9.x on Windows: one CxManager, one SQL Server, four CxEngines, results on an SMB share. 2,800 projects; nightly schedule starts at 02:00 with 900 scans. Average scan time rose from 18 to 47 minutes after the platform team switched most projects from Checkmarx Default to the All preset to improve coverage. At 08:00 the queue holds ~220 scans; engine CPU averages 35% and each engine has two concurrent scans configured. The SQL data file is 1.4 TB, the results share is 6 TB (92% full), and the nightly backup now runs until 09:30. Users complain that portal pages time out and that some scans sit in Queued for hours while engines show idle gaps. A proposal to buy four more engines is on the table.
1. What is the most likely bottleneck, and what data would you collect before approving more engines?
Read the worked answer
The queue with idle engines points away from CPU and toward I/O and orchestration. Four engines at two concurrent scans should run eight scans; if engines show idle gaps while 220 scans wait, check what the engines are waiting on: SMB writes to a 92%-full results share, SQL Server I/O during a backup that runs until 09:30, or Manager dispatch and database contention (the portal timeouts support this). The switch from Default to All increases the number of queries and the volume of results written per scan, which multiplies share and database load; that fits the jump from 18 to 47 minutes.
Before buying engines, collect scan phase timings from engine logs, per-engine CPU and disk latency, SMB latency and free space, SQL wait statistics and backup duration, and queue wait time per project. Check whether All is even required: many queries in it are low-value for these applications. Adding engines would add concurrent writers to the same saturated share and database, likely making the queue worse rather than better. The decision should be based on measured headroom, not queue length.
2. Propose a remediation sequence with expected impact.
Read the worked answer
Sequence:
- Restore headroom on the results share: archive or purge scans older than the retention policy and expand the volume. At 92% full, write latency and failed scans are expected.
- Move the backup window so it does not overlap the 02:00-09:30 scan window, or use a storage snapshot.
- Replace All with a tuned preset: Checkmarx Default plus specific queries the business needs, and use query tuning per project to disable slow, noisy queries with documented approval. Re-measure on ten representative projects.
- Stagger the 900 nightly scans into waves by team or criticality instead of one 02:00 start, and consider reducing per-engine concurrency to one until share latency is healthy.
- Add engines only after CPU utilization and database wait times show headroom.
Expected impact: share expansion and backup separation remove the I/O cliff; preset tuning cuts scan duration and result volume; staggering smooths the queue. This ordering is cheaper than four engines and addresses the actual bottleneck first.
3. How would you validate that the changes worked without silently losing detection coverage?
Read the worked answer
Use a controlled benchmark. Pick ten projects representing sizes and languages, freeze the same commit, and scan before and after each change; record duration, queue wait, result counts by severity, and failures. Track p50 and p95, not averages, because the queue is tail-heavy. Monitor engine CPU, disk latency, SMB throughput, SQL waits, share free space, and portal response time for two weeks.
Confirm coverage did not silently drop: run the old and new presets on the benchmark set and diff findings, and keep a known-vulnerable sample project that must still produce its expected results. Compare query-level timing to identify which queries in All were expensive relative to their value.
Define success before starting, for example: p95 queue wait under 30 minutes, scan duration back under 25 minutes, no increase in failed scans, and no loss of High or Critical findings on the benchmark. If those hold, the engine purchase can be deferred or sized from measured CPU headroom.