GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Releases · uNetworking/uWebSockets.js

Releases · uNetworking/uWebSockets.js

v20.71.0

v20.71.0 Latest
Latest
@uNetworkingAB uNetworkingAB released this 16 Sep 09:06
v20.71.0
9ec36de
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.

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.

fastify_slow

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.

ayo-what

(Actually I decided to hit the Bitcoin endpoint here, but they are identical performance wise)

dynamic_cache_200

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.

uWS js price feed service is 13x as fast as Fastify's _Hello World_
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

v20.69.0
@uNetworkingAB uNetworkingAB released this 11 Jul 07:19
v20.69.0
dddd8ff
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.
  • 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
All reactions
  • 🚀 4 reactions
4 people reacted

v20.68.0

v20.68.0
@uNetworkingAB uNetworkingAB released this 31 May 14:57
v20.68.0
6249877
  • Bumps uWS to v20.78.0
Assets 2
Loading

Uh oh!

There was an error while loading. Please reload this page.

All reactions

v20.67.0

v20.67.0
@uNetworkingAB uNetworkingAB released this 07 May 04:54
v20.67.0
e0f56eb

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
All reactions
  • 👍 8 reactions
8 people reacted

v20.66.0

v20.66.0
@uNetworkingAB uNetworkingAB released this 24 Apr 22:07
v20.66.0
a63031f
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.

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
All reactions
  • 🚀 1 reaction
1 person reacted

v20.65.0

v20.65.0
@uNetworkingAB uNetworkingAB released this 22 Apr 12:54
v20.65.0
93baa7b

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
All reactions
  • ❤️ 1 reaction
1 person reacted

v20.64.0

v20.64.0
@uNetworkingAB uNetworkingAB released this 15 Apr 21:25
v20.64.0
09c62a4
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.
  • 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
All reactions
  • 🚀 3 reactions
3 people reacted

v20.63.0

v20.63.0
@uNetworkingAB uNetworkingAB released this 09 Apr 07:38
v20.63.0
d584e62

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.

Contributors

  • @ValoChet
ValoChet
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

v20.62.0
@uNetworkingAB uNetworkingAB released this 07 Apr 14:28
v20.62.0
e06b4f2
This commit was created on GitHub.com and signed with GitHub’s verified signature.
GPG key ID: B5690EEEBB952194
Verified
Learn about vigilant mode.
  • 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.

All reactions

v20.61.0

v20.61.0
@uNetworkingAB uNetworkingAB released this 23 Mar 22:25
v20.61.0
cf2e4a8

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.

giphy (4)

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
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.