GeezerVison is showing github.com — Releases · uNetworking/uWebSockets.js
Releases · uNetworking/uWebSockets.js
v20.71.0
9ec36de
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Microcaching JavaScript invocations for 13x performance
This release adds the concept of Microcaching.
Any idempotent HTTP handler dealing with dynamic-but-public content can benefit from significant (3x) performance improvements and reduced business logic complexity by enabling some degree of microcaching (see benchmark below).
The feature is experimental and subject to change.
Let's build a financial app
uWS.App().get('/prices/gold', async (res, req) => {
/* Before going async we need to listen to socket abortions */
res.onAborted(() => {
res.aborted = true;
});
/* This would be some async DB action or fetch quest that you want to essentially rate-limit */
const goldPrice = await getGoldPriceJSON();
if (!res.aborted) {
res.cork(() => {
res.end(goldPrice);
});
}
}, {
/* This object specifies the caching options */
lowerExpiry: 1,
upperExpiry: 5
})
Caching is enabled per-route, by passing the following object as final route handler argument:
{
/* This object specifies the caching options */
lowerExpiry: 1,
upperExpiry: 5
}
lowerExpiry is essentially the rate-limiter, it decides how rapidly the cache will try to update. A value of 0 is allowed and will update the cache as fast as the request handler supports (it will still act as protection against thundering herd since only 1 update can be pending at any given time, in other words, the updating is coalesced)
upperExpiry is the deadline cutoff. It decides the absolute upper limit for the cache. If your service has ample traffic and your request handler is reliable, you should never hit upperExpiry.
See the complete HttpCache example
Benchmarking the service
Fastify, more like Crawlify, am I right?
For context, a baseline Fastify "Hello World" server tops out at around 15k req/sec at 100% CPU-core utilization on the test computer.
Benchmarking our Gold price endpoint—which serves dynamic payloads like this:
{
"status": "success",
"asset": "Gold Futures",
"symbol": "GC=F",
"price": 4408.9,
"currency": "USD",
"timestamp": 1789160399,
"isoDate": "2026-09-11T20:59:59.000Z"
}
...results in 200k req/sec using the same CPU-time budget.
(Actually I decided to hit the Bitcoin endpoint here, but they are identical performance wise)
What the heck is going on?
Without any caching, uWS.js is 5x faster than Fastify. By adding caching, we are 13x faster. With a cache, we dilute the JavaScript overhead by allowing native ("core") uWS to respond from its native cache for the most part of a second, and only call into JavaScript to update the cache about once every second. This drastically reduces the density of JavaScript in the hot path, which causes the app to approach native performance even though the business logic remains the same JavaScript.
In fact, the business logic becomes simpler by using a cache, as we can rely on the inherent rate-limiting property of the cache when designing our JavaScript data fetcher. Knowing that we have a cache, we can afford high level async/await without worrying about DOS.

Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
Theofilos-Chamalis, L3P3, VikramAditya33, and Flora90001 reacted with heart emoji
cesco69, uasan, dvergeylen, aleksraiden, jimmyolo, Rolands-Laucis, SchahinRohani, MarcJo, adworacz, and royalswe reacted with rocket emoji
arsa0x, webcarrot, and ChenYingChou reacted with eyes emoji
All reactions
-
❤️
4 reactions
-
🚀
10 reactions
-
👀
3 reactions
17 people reacted
v20.69.0
dddd8ff
This commit was created on GitHub.com and signed with GitHub’s verified signature.
- Bumps uWS to v20.79.0
- Adds beginWrite() call
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
MeredithRodneyMcKay, cesco69, aPoCoMiLogin, and jaaymes reacted with rocket emoji
4 people reacted
v20.68.0
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
v20.67.0
Node.js 26
This release removes Node.js 25 & Node.js 20 support and adds Node.js 26 support.
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
MarcJo, louneskmt, siamakabi, cesco69, MeredithRodneyMcKay, Rolands-Laucis, pasha-vuiko, and VikramAditya33 reacted with thumbs up emoji
8 people reacted
v20.66.0
a63031f
This commit was created on GitHub.com and signed with GitHub’s verified signature.
User space cache for getRemoteAddress(), getRemoteAddressAsText() is now re-enabled after being extended to also support WorkerThreads. These calls are now zero-cost.
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
nigrosimone reacted with rocket emoji
1 person reacted
v20.65.0
The optimization introduced in v20.63.0 is not valid for Latin-1 strings; V8 does not store ASCII or UTF-8, it stores Latin-1 or UTF-16 or some rope combination of them. In v20.63.0, a Latin-1 stored V8 string will pop out as Latin-1 bytes, not the expected (implied) standard UTF-8, and there is no way to tell what uWS will give you.
This release removes the optimization for a conservative, always-UTF-8 output like before. It means uWS will always put UTF-8 bytes on the wire if the input was a JavaScript String.
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
webcarrot reacted with heart emoji
1 person reacted
v20.64.0
09c62a4
This commit was created on GitHub.com and signed with GitHub’s verified signature.
- Bumps uWS to v20.77.0 with important backpressure fix (see main repo for explanation)
- Reduces newly introduced (v20.63.0) 8MB thread-local pool size to 128kb
- Adds VideoStreamerChunked.js example with proper use of chunked transfer-encoding streaming
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
GetThatCookie, dragonbane0, and cesco69 reacted with rocket emoji
3 people reacted
v20.63.0
Faster String arguments
With research & benchmarks done by @BV-WebDev, this release introduces optimizations for methods taking JavaScript Strings. The following demo runs with 17% higher req/sec overall, entirely due to this faster String argument passing:
get('/', (res, req) => {
res.writeHeader("Hello", "There");
res.writeHeader("Hi", "On you");
res.end('Hello World!');
})
This optimization applies to Node.js 24 or later and relies on the new v8::String::ValueView.
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
Guthib-of-Dan, cesco69, Mupli, SchahinRohani, MeredithRodneyMcKay, VikramAditya33, and matiushev reacted with hooray emoji
VentyCZ and VikramAditya33 reacted with eyes emoji
All reactions
-
🎉
7 reactions
-
👀
2 reactions
8 people reacted
v20.62.0
e06b4f2
This commit was created on GitHub.com and signed with GitHub’s verified signature.
- Disables WebSocket.send V8 fastcall variant, suspected of causing issues for existing apps.
- Disables the UWS_REMOTE_ADDRESS_USERSPACE enabled in v20.61.0. There are cases where this feature is not fully implemented (such as use together with worker threads).
Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
v20.61.0
10 years of uWS
If you are interested, there is a more detailed retrospect release post in the main repo. For Node.js we have the following changes:
- getRemoteAddress(), getRemoteAddressAsText() calls are now zero cost. This is a major performance boost for apps using these in hot paths.
- onDataV2 is a superior alternative to onData, explained in the linked retrospect release.
- collectBody is a helper function making optimal use of the new onDataV2. It allows efficient and easy collection of smallish HTTP posts into RAM, returned as one whole buffer.
- We now build AddressSanitizer binaries, available in branch
binaries-asan. These can be very useful for debugging or filing bug reports related to crashes and segfaults. To run the ASAN binaries, your Node.js invocation needs to be prefixed with LD_PRELOAD like so: LD_PRELOAD=$(gcc -print-file-name=libasan.so) node server.js
- DeclarativeResponse can now do writeStatus as well as end with binary, not just text.
- Many documentation fixes.
- Support for symbol-keyed properties in WebSocket UserData.
- getRemotePort, getProxiedRemotePort.

Assets
2
Loading
Uh oh!
There was an error while loading. Please reload this page.
joelwhuff, Necrelox, and chalukyaj reacted with thumbs up emoji
FlorianBELLAZOUZ, Necrelox, Mupli, danmasta, and chalukyaj reacted with heart emoji
Mohmn, Guthib-of-Dan, ValoChet, cesco69, sshrshnv, MeredithRodneyMcKay, endel, FlorianBELLAZOUZ, Necrelox, and chalukyaj reacted with rocket emoji
All reactions
-
👍
3 reactions
-
❤️
5 reactions
-
🚀
10 reactions
13 people reacted
|