The Self-Cultivation of Programmers: How to Use GDB Well

    | 42 minute read
    The title may sound a bit arrogant, but it is mainly a tribute to the book The Self-Cultivation of Programmers: Linking, Loading, and Libraries. In the AI era, we may increasingly let agents write and run GDB scripts or analyze core dumps for us. Still, this post discusses how to use GDB better: more specifically, how much of GDB's underlying principles we need to understand to know its capability boundaries and avoid being led around by AI on complex problems.
    Read more ⟶

    Two Months of Heavy AI Code Agent Usage: Thoughts from an Ordinary Engineer

    | 30 minute read
    After two months of heavy AI Code Agent usage, I started to rethink the relationship between programmers and tools. From the perspective of an ordinary engineer outside the AI field, mainstream development may increasingly shift toward AI-generated code, while programmers take on more of a technical architect role. That does not lower the bar for programmers. It raises it.
    Read more ⟶

    Learning eBPF the Hard Way: Starting from nginx eBPF

    | 48 minute read
    This post explains why I want to start this new series and why I like eBPF, then uses Reuseport eBPF as an entry point to analyze how it solves UDP hot upgrade problems. It also looks into nginx's eBPF implementation and its limitations, revisits the pitfalls I hit when I did not understand how eBPF loaders work, and finally digs into Cloudflare's udpgrm project.
    Read more ⟶

    Linux Server-Side UDP Network Programming: Zero-Loss Hot Upgrade

    | 33 minute read
    Starting from a difficult urgent requirement years ago, this post introduces the Established-over-unconnected technique. It discusses UDP network programming on Linux servers, how to implement a truly zero-loss hot upgrade, the pitfalls across different kernel versions, and how TCP and UDP packets are matched to sockets inside the kernel.
    Read more ⟶

    Implementing QUIC from Scratch with Rust: Connection Migration

    | 28 minute read
    Before discussing connection migration, this post explains how QUIC implements connection-oriented behavior, then analyzes the design details of QUIC connection migration and compares similar ideas in other protocols, such as WebRTC Mobility. It also covers implementation scenarios in feather-quic and ends with thoughts on AI-generated code.
    Read more ⟶

    Implementing QUIC from Scratch with Rust: MTU Discovery

    | 33 minute read
    Starting from why transport protocols need MTU discovery, this post analyzes why IP fragmentation can reduce performance and even hurt availability, then discusses common MTU discovery strategies, QUIC's approach, related Linux optimizations such as GSO, TSO, and GRO, and finally gives a few practical MTU configuration suggestions.
    Read more ⟶

    Implementing QUIC from Scratch with Rust: Connection Close and Error Handling

    | 18 minute read
    First, as usual, I take a few swings at TCP and explain why QUIC's connection-close design is much better. Then I implement the cases where a QUIC connection needs to close because of errors. Finally, the first phase of this project is roughly complete, so I write down a few thoughts from the journey so far.
    Read more ⟶

    Incident Response: Lessons from 4+ Years On Call

    | 28 minute read
    A recent customer incident made me notice a small but important mistake in my own response process, so I revisited what incident response really means. In my first job, I spent more than four years in a high-intensity on-call rotation while also working on large-scale infrastructure projects. It felt like replacing an engine while the plane was still flying: the system was running, changes kept shipping, and incidents could happen at any moment. This post summarizes the lessons I learned from those years.
    Read more ⟶

    Implementing QUIC from Scratch with Rust: Streams and Flow Control

    | 17 minute read
    Implement QUIC's core multiplexed stream transport and flow control, adjust the project structure, and add integration tests to keep the stack aligned with the QUIC specification.
    Read more ⟶