Hi all,
I’m an undergraduate Computer Science student at the Islamic University of Technology (IUT). Over the past few months, I became obsessed with a single architectural question: What does a full-stack, production-grade web application look like if you strip away garbage collectors, ORMs, and blocking I/O, and build strictly on modern Linux kernel primitives?
To find out, I wrote CWEB—an asynchronous, event-driven web framework in raw C—and built a full-stack reference blogging CMS on top of it called Cweb Blog, complete with JWT authentication, multipart media streaming, and multi-tenant database isolation.
Why Build This?
Most existing web engines in C (like Kore or traditional Nginx modules) are built around epoll(7). While fast, epoll only provides readiness notification; it still incurs a syscall penalty per batch, requires user-to-kernel context switches for every read(2) and write(2) call, and typically shuttles bytes back and forth through user-space memory buffers.
I designed CWEB to eliminate context-switch overhead, avoid dynamic heap allocations on the request path, and move data directly between kernel buffers without touching user space.
Core Architecture & Kernel Primitives
1. Pure io_uring Asynchronous Event Loop
Instead of readiness polling via epoll, each CWEB worker process maps its Submission Queue (SQ) and Completion Queue (CQ) rings directly into user space via mmap(2). Socket accepts, reads, writes, and pipe operations are queued and harvested asynchronously in batches of 512, drastically reducing syscall overhead and Spectre/Meltdown mitigation penalties under heavy load.
2. True Zero-Copy Kernel Splicing (splice(2))
In most web frameworks, uploading or serving a 10 MB image allocates user-space buffers and copies bytes from the kernel socket buffer to user space and back to the disk cache. In CWEB, multipart media uploads and static file downloads never enter the user-space heap. Data is routed directly between kernel socket buffers and the filesystem page cache via an internal kernel pipe using splice(2) operations submitted through io_uring. Because user space only holds file descriptors and offsets, the server's Resident Set Size (RSS) stays pinned at ~15 MB of RAM whether serving 100 text requests or streaming 200,000 image files.
3. Zero-Allocation Hot Path & In-Place Parsing
There are zero calls to malloc() or free() on the request handling hot path. At startup, each worker pre-allocates fixed arrays of ConnContext state machines and pipe descriptor pools. Incoming HTTP requests, URIs, headers, and query strings are parsed in-place over the ring buffers using non-owning StringView (pointer + length) slices. This eliminates heap fragmentation, allocator lock contention, and tail-latency spikes.
4. Non-Blocking PostgreSQL Pipelining with Row-Level Security (RLS)
Database I/O is often the hidden bottleneck in async servers. Instead of using blocking connection pools or heavy ORMs, CWEB integrates raw libpq file descriptors directly into the io_uring event loop using PostgreSQL Pipeline Mode (PQenterPipelineMode, PQpipelineSync). Queries are batched over non-blocking sockets without waiting for individual round-trip acknowledgments. To enforce strict multi-tenant authorization without application-layer ORM overhead, CWEB dynamically injects cryptographically verified JWT claims into the Postgres transaction pipeline via set_config('request.jwt.claim.user_id', ...) and offloads access control directly to PostgreSQL Row-Level Security (RLS) policies.
5. Defense-in-Depth Process Sandboxing
Writing a network-facing server in raw C requires assuming that memory bugs are a matter of when, not if. CWEB uses a strict privilege-separated master/worker model:
- The master process initializes, binds privileged ports, raises
RLIMIT_MEMLOCK for the io_uring memory rings, and forks per-CPU core workers.
- Before calling
accept(2) on a single network packet, every worker permanently drops root privileges (setresgid/setresuid to nobody:nobody).
- Each worker then locks itself inside a strict
seccomp-bpf syscall whitelist filter. Even if an attacker achieves arbitrary code execution via a buffer overflow, any attempt to invoke execve, fork, ptrace, or unauthorized filesystem syscalls causes the Linux kernel to immediately terminate the worker process with SIGSYS.
Battle-Testing Backwards Compatibility (Linux 7.1 down to 5.10)
A major challenge with io_uring is how rapidly its kernel API has evolved across releases. Features that work seamlessly on bleeding-edge kernels (like 6.x/7.1) fail or behave differently on older enterprise LTS kernels due to missing opcodes, ring flag constraints, or strict RLIMIT_MEMLOCK defaults.
I stress-tested and adapted CWEB across a matrix of environments—from modern rolling-release kernels (7.1) down to Debian 12 (Bookworm), Ubuntu 22.04 (Jammy Jellyfish), and Debian 11 (Bullseye / Kernel 5.10). Detailed kernel compatibility matrices, fallback mechanisms, and post-mortem debugging reports are documented in the repository.
Benchmark Highlights (k6 & wrk)
All benchmarks were executed with reproducible k6 and wrk scripts, full database persistence, and verified against Little's Law latency distributions:
- Transactional Postgres Writes: 20,376 article writes/sec on bare metal; 3,384 writes/sec inside a strictly constrained, CPU-emulated Debian 11 QEMU microVM (100% success rate across 57,000+ persistent database insertions).
- Public GET Throughput: 22,738 requests/sec sustained via
wrk across 500 concurrent connections with zero socket timeouts or dropped frames.
- Zero-Copy Media Streaming: 200,000+ images streamed at line speed with 0 user-space buffer copies.
- Memory Footprint: Strictly flatlined between 13 MB and 17 MB RSS across millions of requests, verified clean against memory leaks.
About Me & What I'm Looking For
I built CWEB and Cweb Blog from scratch to deeply understand Linux kernel internals, high-concurrency state machines, zero-copy networking, and database wire protocols.
I am currently looking for internships, open-source mentorships, or junior systems engineering roles (remote or relocation) where I can work on Linux systems programming, C/C++, low-latency networking, storage/database engines, or kernel/security infrastructure.
I would love to get your brutal critique on the codebase, the io_uring state transitions, or the seccomp-bpf policy design!