-
Notifications
You must be signed in to change notification settings - Fork 294
Open
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:
- Handles more than 100,000 concurrent connections reliably.
- 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(®.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(®.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));
Metadata
Metadata
Assignees
Labels
No labels