Skip to content
Time to Signal

All notes  /  Foundations

The Loops, Ranked

A developer runs several feedback loops a day, at different frequencies. Which ones to optimise first, and the one almost nobody measures.

Reference

Not all waiting is equal. A loop that runs two hundred times a day matters more than one that runs twice, even if the second is longer.

The loops

Editor feedback. Syntax, types, lint, as you type. Runs continuously.

Local build or compile. Tens to hundreds of times a day.

Local test run. Some subset, many times a day.

Full local verification. Before pushing, a few times a day.

Continuous integration. Per push, several times a day.

Deployment to a shared environment. A few times a day to a few times a week.

Production. Varies enormously.

The ranking rule

Frequency times duration, weighted by whether attention is held.

A one-second editor delay occurring two hundred times a day is two hundred seconds, and it never breaks attention. A fifteen-minute pipeline occurring five times a day is seventy-five minutes and breaks attention every time.

Both matter. The second matters more per occurrence; the first is easier to fix.

Start where the product of frequency and cost is highest, which is usually the local build or the inner test loop, not the pipeline everyone complains about.

The loop nobody measures

Local iteration.

Continuous integration is instrumented by default: every run produces a record, and dashboards exist. So that is what gets discussed and optimised.

Local builds produce no telemetry unless someone deliberately collects it. Which means the loop developers spend most of their day inside is the one nobody has numbers for.

Collect it. Build tools can emit local timings. The distribution is usually worse than the CI numbers and always more surprising.

Expect resistance, and handle it properly: this is telemetry about builds, not about people, and it should be aggregated and stated as such before collection starts. That boundary has its own note.

Where the loops interact

A slow local loop pushes work into CI. If verifying locally is slower than pushing, developers push to test, which loads the pipeline with work that should never have reached it.

A slow CI loop pushes work into local. If the pipeline is unbearable, people over-verify locally and lose time to setup.

An unreliable loop at any level poisons the ones downstream, because nobody trusts a signal that is wrong a fifth of the time.

Fixing one loop moves load to another, which is why the measurement has to cover all of them rather than the one currently being optimised.

What good looks like, roughly

Targets vary by codebase size and language, and these are the orders of magnitude worth aiming at.

Editor feedback: subsecond.

Incremental local build: seconds.

Focused local test run: seconds to tens of seconds.

Full local verification: minutes, and it should be possible to run only what is affected.

CI on a change: under ten minutes to a useful signal, with the slow parts running after.

If any of these is an order of magnitude off, that is the finding, and it is worth measuring before assuming which one it is.

Instrumenting the local loop

The loop developers spend most of their day in and the only one with no telemetry by default.

Most build tools can emit timings natively or through a plugin.

Collect duration, task, cache result, and platform.

Discard user and machine identifiers at source, which is the boundary and which has its own note.

Aggregate before transmission, so events never leave the machine.

Say what is collected before collecting it. Local instrumentation depends entirely on developers not believing it is aimed at them, and that trust is spent once.

Where load moves when you fix one

Improving a loop rarely reduces total demand; it usually relocates it.

Faster local verification pulls work out of CI, reducing queue pressure.

Faster CI pulls work out of local, because pushing becomes cheaper than verifying.

Faster builds mean more builds, so capacity that felt adequate becomes short.

Measure all the loops, not the one being worked on, or an improvement in one will show up as an unexplained regression in another and be misdiagnosed.