SystemsApril 21, 20261 min read

What writing an HTTP server taught me about frameworks

A non-blocking HTTP server in C++, no libraries allowed. It’s the project that showed me what every framework quietly does on my behalf.

At 1337 I wrote an HTTP server in C++ from scratch — no HTTP libraries. Just sockets, an event loop, and a parser I had to write myself. Nothing demystifies a framework like reimplementing the floor it stands on.

The event loop is not magic

"Non-blocking" stops being a buzzword the moment you write the epoll_wait loop yourself. One thread, a readiness list, and a strict rule: never call anything that can block.

loop.cppC++
int n = epoll_wait(epfd, events, MAX, -1);
for (int i = 0; i < n; ++i) {
    int fd = events[i].data.fd;
    if (fd == listen_fd)      accept_new_connection();
    else if (events[i].events & EPOLLIN)  read_request(fd);
    else if (events[i].events & EPOLLOUT) flush_response(fd);
}
The thing frameworks hide

Backpressure. A socket’s send buffer fills and write() returns EAGAIN. You must stop, register for EPOLLOUT, and resume later. Every framework is quietly managing this dance for you.

What carried over

I learned the stack from the socket up — and I’ve never since trusted a framework blindly to do it for me.

Now when a framework misbehaves, I don’t guess. I know which syscall it’s standing on.

← All field notes