Blog

Fresh, but not freshest

Martins Sipenko, founder

There are two ways a dependency bites: the version you never updated, and the version you adopted the hour it shipped. Most teams drift to one side. The teams that get through incidents unbothered refuse both.

Too fresh

The freshest version is the riskiest version. When a release turns malicious, by account takeover or by its own maintainer, it ships as an update and rides automatic adoption: event-stream in 2018, ua-parser-js in 2021, the colors sabotage and node-ipc in 2022, the xz backdoor in 2024. Most were caught within days, and the teams that updated first took the hit. A soak window is no guarantee, event-stream hid for two months, but it prices the common case: a release’s first days are its trial period, and someone else should serve as the jury.

Too stale

The stale side fails slower and hurts more. Skip a year of updates and nothing happens, which is the trap. Upgrade distance compounds in silence: minors stack into majors, majors stack into rewrites, and the migration you owe grows while nobody is looking. Then a CVE drops in something you run, the fix exists three majors ahead of you, and the work you postponed for a year is due in a day. Under the Cyber Resilience Act, that day now has a legal clock on it.

What Shopify does with Ruby

Shopify wrote the cleanest description of the middle ground. Their Ruby team refuses to run Ruby’s development head in production: no stable API, no precompiled native gems, a compatibility tax on the whole codebase. They also refuse to wait for Ruby’s annual release day. They run the current stable release with fixes backported on top, test against head every night, and, in their words, “can switch Ruby builds and deploy these improvements to production in a matter of hours.”

Hours. Not because they chase the freshest build, but because they never let the distance grow past a step. Fresh, but not freshest, held in place by habit.

The policy shape

The middle ground is a policy, and you can start it without a platform. Hold every new release for a soak window before it merges: days for patches, longer for majors. Both update bots do this now. Renovate calls it minimumReleaseAge and leaves it off until you ask; Dependabot calls it cooldown and has applied three days by default since July 2026. Both let a security advisory jump the queue, which is the right instinct: an exploited bug outranks the soak. The full comparison is here. Then cap staleness with the same energy, because an EOL date or an abandoned upstream is a louder alarm than most CVEs: no fix is coming, on any schedule.

StackRadar encodes both edges. Soak is policy: a green change waits out the window you set, a failed rerun or a fresh advisory resets the clock, and the merge happens without a human once the window closes. Staleness is a lane: EOL dates and abandoned packages sit in the same ranked backlog as vulnerabilities, with the same owner. A freshness view that puts a number on upgrade distance is in preview. Fresh enough to fix anything in a day, aged enough to let someone else find out: that is the whole policy.

Starts in observe mode. It merges nothing until a walkthrough hands you the dial.