uNetworking / uNetworking/uSockets

Issue with performance and compilation

Open
#246 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
1.5k
Forks
307
PR merge metrics
No merged PRs in 30d

Description

Background

I am evaluating the performance of the http_server example, comparing it to bun, which also leverages uWebSockets->uSockets under the hood (I think).

Observed Behavior:
  • For ~1,000 concurrent requests, the server performs adequately — responses are delivered reliably.
  • For >10,000 concurrent requests, the client frequently experiences disconnections or timeouts, indicating instability or resource exhaustion.
  • In contrast, bun handles up to 100,000 concurrent requests with consistent performance
  • When comparing both at 1,000 concurrent requests bun reports lower latency (67ms bun vs 134ms usockets)
  • I tried compiling with IO_URING to see if changing the event loop would improve performance and got the warning below. Despite the warning during compilation, the http_server executable is generated and I tested that similar findings as above.
Question:

Can the uSockets-based http_server example be optimized to match or surpass bun's performance? Such that while sending a simple short text/html response it:

  1. Handles more than 100,000 concurrent connections reliably.
  2. Matches or exceeds the performance (latency, throughput) of bun — particularly at high concurrency.
URING warning

When I tried to make WITH_IO_URING=1 I get the following warning:

rm -f *.o
cc -flto -DLIBUS_NO_SSL -DLIBUS_USE_IO_URING -std=c11 -Isrc -O3 -c src/*.c src/eventing/*.c src/crypto/*.c src/io_uring/*.c
src/io_uring/io_loop.c: In function ‘us_create_loop’:
src/io_uring/io_loop.c:343:20: warning: passing argument 1 of ‘posix_memalign’ from incompatible pointer type [-Wincompatible-pointer-types]
  343 |     posix_memalign(&reg.ring_addr, 1024 * 4, sizeof(struct io_uring_buf) * 4096);
      |                    ^~~~~~~~~~~~~~
      |                    |
      |                    __u64 * {aka long long unsigned int *}
In file included from src/io_uring/internal.h:5,
                 from src/io_uring/io_loop.c:23:
/usr/include/stdlib.h:718:35: note: expected ‘void **’ but argument is of type ‘__u64 *’ {aka ‘long long unsigned int *’}
  718 | extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size)
      |                            ~~~~~~~^~~~~~~~
src/io_uring/io_loop.c:346:20: warning: assignment to ‘struct io_uring_buf_ring *’ from ‘__u64’ {aka ‘long long unsigned int’} makes pointer from integer without a cast [-Wint-conversion]
  346 |     loop->buf_ring = reg.ring_addr;
      |                    ^
src/io_uring/io_loop.c:343:5: warning: ignoring return value of ‘posix_memalign’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  343 |     posix_memalign(&reg.ring_addr, 1024 * 4, sizeof(struct io_uring_buf) * 4096);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib.exe /out:uSockets.a *.o || ar rvs uSockets.a *.o
/bin/sh: 1: lib.exe: not found
r - bsd.o
r - context.o
r - epoll_kqueue.o
r - gcd.o
r - io_context.o
r - io_loop.o
r - io_socket.o
r - libuv.o
r - loop.o
r - openssl.o
r - quic.o
r - socket.o
r - udp.o
for f in examples/*.c; do cc -O3 -flto -DLIBUS_NO_SSL -DLIBUS_USE_IO_URING -std=c11 -Isrc -o $(basename "$f" ".c") "$f" uSockets.a /usr/lib/liburing.a; done
In function ‘us_socket_timeout’,
    inlined from ‘us_socket_timeout’ at src/io_uring/io_socket.c:52:6,
    inlined from ‘main’ at examples/hammer_test.c:439:5:
src/io_uring/io_socket.c:54:20: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   54 |         s->timeout = ((unsigned int)s->context->timestamp + ((seconds + 3) >> 2)) % 240;
      |                    ^
In function ‘us_socket_context_listen’,
    inlined from ‘main’ at examples/hammer_test.c:434:21:
src/io_uring/io_context.c:138:43: note: at offset 24 into destination object of size 16 allocated by ‘malloc’
  138 |     struct us_listen_socket_t *listen_s = malloc(sizeof(struct us_listen_socket_t));

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the reported http_server load behavior and the WITH_IO_URING=1 build. Inspect src/io_uring/io_loop.c, src/io_uring/io_socket.c, and src/io_uring/io_context.c, along with the reported compiler diagnostics. Done should include a defined benchmark showing reliable high-concurrency behavior and a warning-free build.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux
Domain
networking, operating-systems, performance
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.