Model notes
The rule to remember. With N samples at fs, the bin spacing is Δf = fs/N. Doubling N halves that spacing and spreads the same broadband-noise power over twice as many bins, so the average noise power in each bin falls by 3.01 dB. The total noise power is unchanged.
That separates SNDR from SFDR. SNDR adds every non-signal bin, so a longer record should converge to the same SNDR and ENOB; it only makes the estimate steadier. SFDR looks at the single tallest non-signal line. It rises while that line is a random noise bin, then stops when a real harmonic becomes tallest. Record length improves visibility, not converter linearity.
How to choose N. Start with the bin spacing you need: N ≥ fs/Δfrequired. The window still decides how many adjacent bins one tone occupies. Then make the record long enough that repeated captures meet your allowed SNDR spread and the spur you care about stands above the tallest noise bin. Report N, fs and the window with any SFDR number; without them, the number is incomplete.
The experiment. A 10-bit converter runs at 800 MS/s with a coherent tone, a third harmonic at the level you set, and enough white noise to reach the ENOB you set. Each length gets 16 fresh-noise captures. The shaded bands are their full range; the repeatability plot uses their standard deviation.
Checked against ADCToolbox 0.9.1. analyze_spectrum uses its default Hann window and automatic signal side bins. python/adc_record_length.py runs ADCToolbox on the same deterministic captures; the TypeScript model is pinned to those results in the test suite.