Nodes/ComfyUI_KSamplerTimer/KSampler (timer)
ComfyUI Node

KSampler (timer)

Measure Your KSampler Time Where You Actually Render

By my-opencode·Created 2 years ago·Updated 2 years ago· 2
KSampler (timer)
  • model
  • positive
  • negative
  • latent_image
  • LATENT
  • GENERATION_TIME_STRING
  • GENERATION_TIME
seed0
steps20
cfg8.0
sampler_name
scheduler
denoise1.00

ComfyUI's sidebar timer tells you how long the whole graph took. That's fine until you actually want to benchmark - is euler_ancestral really faster than dpmpp_2m on your card? Is that higher CFG costing you real seconds? The built-in timer can't answer that because it blends in VAE decode, model load, everything.

KSampler (timer) can. It's the native KSampler with a stopwatch bolted on, and it hands you the sampling time as a number you can actually use. From my-opencode/ComfyUI_KSamplerTimer (originally by Ludovic Anterieur, a.k.a. IndustrialVectors, on GitLab and mirrored to GitHub - MIT licensed), it does exactly one thing and does it honestly.

How it works

The mechanism is boring in the best way. The node calls the same common_ksampler() function the stock KSampler calls - it is a true wrapper, not a reimplementation - and wraps that call in time.perf_counter() before and after. perf_counter is a monotonic wall clock, so what you get is the elapsed time of the sampling itself: every forward pass, every image in the batch. No CLIP encode, no VAE decode, no model load in the number.

The name is the spec. Inputs are identical to native KSampler: model, seed, steps, cfg, sampler_name (all 34 samplers), scheduler (all 9), positive, negative, latent_image, denoise. Nothing new to learn - you swap it in for your existing KSampler and get the same rendering plus two extra outputs.

The outputs that matter

  • LATENT - the same latent the native node produces. Wires straight into VAE Decode as usual.
  • GENERATION_TIME_STRING - the time in seconds, pre-formatted to two decimals as a string. Handy because ComfyUI's text/display nodes want strings, and you don't want to format a float yourself.
  • GENERATION_TIME - the same value as a float, for math: feed it into a math node, compare runs, or write it to a file.

The pack's example workflows show both patterns: one displays the time, the other logs batch size and times to a file. The node is flagged as an output node, which doesn't stop the LATENT from flowing onward - it just means ComfyUI treats it as a valid terminal point.

Installing it

No dependencies, no model downloads, no requirements.txt - it only imports ComfyUI's own sampling module. This is one of the rare custom nodes you can install blind:

cd ComfyUI/custom_nodes
git clone https://github.com/my-opencode/ComfyUI_KSamplerTimer

Then restart ComfyUI. Or skip the terminal: ComfyUI Manager → Custom Nodes Manager → search "KSamplerTimer" → install. You'll find it under add node → sampling → KSampler (timer), and it even carries a little ⏱ nickname.

Gotchas

  • The time is for the whole batch. A batch of 4 images gives you one number for all four. Divide by the batch size for the per-image average - the author's own workflows do exactly this.
  • First run is a lie. GPU warm-up pollutes the first execution; queue the same thing twice and trust the second number.
  • It's sampling-only. Don't compare it against the "s/it" figures from A1111 or the sidebar, which time more of the pipeline. That's a feature for benchmarking, not a bug.
  • Denoise changes the work. Comparing img2img runs at different denoise values is comparing different amounts of sampling. Keep denoise and the latent fixed, and only vary what you're actually testing.

That last point is where this node earns its keep. Sampler × scheduler sweeps are a genuinely useful habit - the KB's sampler notes even recommend sweeping samplers and steps per model - and this gives you the numbers in-graph instead of staring at a stopwatch. It's a tiny utility, but it's the right one for the job.

Categorysampling

Inputs (10)

NameTypeDefaultDescription
modelMODEL
seedINT00–18446744073709550000
stepsINT201–10000
cfgFLOAT8.00–100
sampler_nameCOMBO34 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +28
schedulerCOMBO9 options: normal, karras, exponential, sgm_uniform, simple, ddim_uniform, +3
positiveCONDITIONING
negativeCONDITIONING
latent_imageLATENT
denoiseFLOAT1.000–1

Outputs (3)

NameTypeDescription
LATENTLATENT
GENERATION_TIME_STRINGSTRING
GENERATION_TIMEFLOAT