Mehdi Akiki

Writing archive

Everything published under Writing, newest first. Each entry is labelled as part of an investigation, an article or reference. Short engineering notes have their own archive.

  • Published on

    Investigation · Part 5 of 10 · Following a TCP connection

    What a Full Socket Buffer Does to the Sender

    My sender wrote 2.6 MB to a peer that never read anything, and every send() said success. I looked where these bytes waited, what setsockopt really does to the buffer sizes, how a blocking sender is slowed down for free, and how an unbounded queue breaks this.
  • Published on

    Investigation · Part 5 of 10 · Inside a database index

    A Covering Index Never Touches the Table

    When an index has every column a query needs, SQLite never opens the table. For one row this saves almost nothing. For 67,245 rows it was 98 ms against 21 ms with a warm cache, and 875 ms against 24 ms with a cold one.
  • Published on

    Investigation · Part 4 of 10 · Following a TCP connection

    Why recv() Returns Less Than You Asked: TCP Is a Byte Stream

    Three send() calls arrived in one recv(), and one send() of 1 MiB arrived in seventeen. TCP keeps the bytes and their order, not the boundaries between your writes. I broke a small JSON reader with two inputs and fixed it with a length prefix and with lines.
  • Published on

    Investigation · Part 4 of 10 · Inside a database index

    Why Column Order Matters in a Composite Index

    Two indexes with the same two columns in a different order. For the same query, one reads 1,885 entries and the other 27,243. I measured why on a SQLite table of one million rows, and found that the leftmost-column rule has an exception called skip-scan.
  • Published on

    Investigation · Part 3 of 10 · Following a TCP connection

    Why a Small Write Can Wait 40 Milliseconds: Nagle and Delayed ACK

    My client wrote each request in two small pieces, and almost every request took 43 ms or more on loopback, where a round trip costs microseconds. I followed it with strace, ss and the kernel counters to see how Nagle's algorithm and delayed ACK wait for each other.