Skip to content

Troubleshooting

This page maps symptoms you may see in benchmark output to their likely causes and the specific NBenchmark configuration that addresses them.

Measurement variability

SymptomLikely causeConfiguration fix
Large Error (wide CI)Too few iterationsIncrease with .WithIterations(500) or --iterations 500 - see Configuration
Large Error (wide CI)OS scheduling / context-switch noiseSwitch outlier mode to .WithOutlierMode(OutlierMode.IqrFence) - see Configuration
Large Error (wide CI)Thermal throttling on laptopsIncrease warmup with .WithWarmup(50) to let the CPU stabilise, or reduce iterations to shorten the run. Run plugged in. - see Configuration
High StdDevGC pressure or allocation noiseEnable allocation tracking with .WithAllocations() to diagnose - see Configuration. If your benchmark intentionally exercises GC, you can disable ForceGcBeforeEachIteration - see Configuration

Quick reference: Outlier modes

ModeWhen to use
RemoveTop5Percent (default)General-purpose. Removes the slowest 5% of iterations.
RemoveTopAndBottom5PercentWhen very fast outliers (e.g. cache hits after warmup) also skew results.
IqrFenceWhen you see sporadic large spikes from OS scheduling interrupts - the IQR-based fence adapts to your data's spread rather than a fixed percentage.
NoneWhen every sample matters (latency-tail analysis).

Zero or unexpected results

SymptomLikely causeConfiguration fix
Result shows 0 nsDead code elimination - the compiler removed your benchmark body because it has no observable side effectsUse the Func<T> overload that returns a value, or add a side effect. See FAQ: 0 ns
All results zeroedDry-run mode active (--dry-run, Iterations=0, WarmupIterations=0)Remove --dry-run flag or set Iterations > 0
MarginOfError is ±0 nsOnly one sample (n < 2) or all measurements identical (timer resolution coarser than the benchmark duration)Increase iterations. If the timer is too coarse, run on a machine with a higher-resolution timer
Sig column shows ~Too few samples for the Mann-Whitney U test (requires ≥5 per group)Increase iterations or combine more runs - see FAQ: significance

Discovery and setup errors

SymptomLikely causeConfiguration fix
[Benchmark] method not discoveredMethod is static, class is abstract, or assembly not registeredUse --list to verify what the host finds - see Host mode: listing. Check the class is public, not abstract, and the method is an instance method
"Could not instantiate MyClass"No public parameterless constructorAdd one, use [BenchmarkSetup], or add NBenchmark.DependencyInjection - see FAQ: instantiation
Benchmarks run in different order each timeRandom order is the default (prevents systematic bias)Use --order declaration or .WithRunOrder(RunOrder.Declaration) for source order - see Configuration

Still stuck?

Released under the MIT License.