Node.js 26.10.0 adds debounce and throttle to the standard library
The release arrived on September 22, 2026 and contains no security fixes. Both new functions return a promise for whatever the wrapped function produced, accept an AbortSignal, and say exactly what happens to a call they decide not to run. Throttle also carries a concurrency limit, a queue depth and a choice between queueing the overflow and rejecting it. Nine further changes are marked semver-minor, among them a synchronous openAsBlob and a way to hand a bound socket to a worker thread.
Delaying a reaction to an event that fires too fast, and capping how often a client calls someone else's service, are two of the most common reasons a Node project pulls in a dependency it does not otherwise need. Node.js 26.10.0 was published on September 22, 2026, and both now live in node:util. Neither is a thin copy of what npm already offers: each returns a promise, accepts an AbortSignal, and states what happens to a call it will not run.
How debounce works
util.debounce(fn, wait[, options]) returns a function that delays fn until the wait in milliseconds has passed since the most recent call. The returned function hands back a promise for whatever fn produced, and if fn throws or returns a rejected promise, that promise rejects with the same reason. When the debounced function is called several times inside one window, fn receives the arguments from the last of them.
The options decide what happens to the calls that lose. By default every superseded call resolves with the result of the invocation that did run. With rejectOnCancel set, those calls reject with an AbortError instead, which is what a caller needs when it must know its work was discarded. The leading option invokes fn at the start of the window, and the returned function carries a cancel method.
Throttle is a rate limiter, not a timer
util.throttle(fn, limit, interval[, options]) caps invocations at limit per interval in milliseconds. Rate capacity is consumed when fn starts, not when a call enters the queue, and concurrency capacity is released when the returned value settles. The documentation puts the rule in one sentence, quoted below.
Calls above the limit are queued in arrival order by default. Setting overflow to drop rejects them immediately with an ERR_THROTTLED error, and maxPending caps the queue when queueing is kept. A rejected call comes back as a promise that is already marked as handled, so ignoring one does not raise an unhandled rejection.
concurrencylimits how many invocations may have an unsettled return value at once, and the default isInfinity.strictholds the limit across any rolling interval rather than across fixed windows.- An aborted
signalcancels pending calls and prevents future ones, on both functions.
The rest of the release
Nine further entries in the notable list are marked semver-minor. util.markPromiseAsHandled(promise) marks a promise so that a rejection is not reported through the unhandled rejection path, which is the same mechanism throttle uses on the calls it rejects itself.
crypto.parsePKCS12()reads a bundle in the PKCS#12 format.fs.openAsBlobSyncis the synchronous counterpart ofopenAsBlob.- The
netmodule can send anet.BoundSocketto worker threads and child processes. perf_hooksgains aSlidingWindowHistogramand qrde analysis insideHistogram.sqlitenow bindsundefinedtoNULL, andffican load libraries from a mounted virtual file system.
What it changes for a project
A dependency that exists only to debounce an event handler can come out of package.json, and so can a hand-rolled limiter sitting in front of someone else's API. On a server that matters less for size than for the supply chain: every package removed is one fewer thing to audit and one fewer thing to update.
The release page marks this one as Current, and the notes list no security fixes, so the upgrade is not urgent. One entry deserves a read before it happens: sqlite now binds undefined to NULL, which changes what a query does with a missing value rather than adding something new.
„An invocation starts only when both rate and concurrency capacity are available.“
Sources
Related
Python 3.15 makes UTF-8 the default encoding and adds explicit lazy imports
Python 3.15.0 came out on October 9, 2026. Files opened without an explicit encoding are now read and written as UTF-8 on every system, and a new lazy import statement defers loading a module until it is used. The release also adds frozendict and a sampling profiler.
Python Software Foundationverified

Deno's team joins Cloudflare, and the Deno runtime gets one more year of updates
Ryan Dahl announced on October 9, 2026 that the whole Deno team is moving to Cloudflare. The Deno runtime will get monthly fixes for one more year before development ends, and Deno Deploy will shut down after six months. JSR keeps running.
Denoverified

Anthropic's OSS Scanner sends open-source maintainers free vulnerability reports that no human has reviewed
Anthropic launched OSS Scanner on October 8, 2026, an opt-in service that scans eligible open-source projects with its strongest models, including Claude Mythos, at no cost. Each report includes a reproducer, an explanation, and a candidate patch when one exists, but no person checks it before it is sent. Anthropic says it expects more than 90% of findings to be real.
Anthropicverified