FetchMode
Generated page
Model gemma-mtp, commit f508a4b65b3f, 2026-08-15, sources: 6. Edit the code or the hand-written documentation instead.
What this module is responsible for
The FetchMode determines the data transfer strategy used by the broker to move log data from the storage layer to the network socket during a FetchRequest. It is a critical performance knob that dictates whether data passes through the JVM heap or stays within the OS page cache.
Diagram
FetchMode
The available strategies are defined in BooblikServer.kt:37-43:
| Mode | Description |
|---|---|
ZERO_COPY | Uses FileChannel.transferTo to move data from the page cache directly to the socket buffer, bypassing the JVM heap. |
HEAP | Reads data into a heap-allocated staging buffer before writing it to the connection. |
ZERO_COPY mechanics
When FetchMode.ZERO_COPY is selected, the Session utilizes the Connection.transferFrom method to perform a zero-copy transfer Session.kt:221-223. This approach leverages the operating system's ability to move data from the file system cache directly to the network stack, avoiding the overhead of copying bytes into the application's memory space.
HEAP staging and buffer reuse
In HEAP mode, the Session manages a reusable staging buffer to minimize allocation pressure Session.kt:289-294. The lifecycle of this buffer is as follows:
- Allocation: A buffer is allocated with an initial size of 64 KiB
Session.kt:297. - Growth: If a request requires more space, the
stagingfunction allocates a newByteBufferof the required sizeSession.kt:290. - Reuse: The same buffer is cleared and reused for subsequent requests to avoid frequent GC cycles.
Fetch slice lifecycle and retention
To prevent a long-running FetchRequest from blocking log retention, the Session manages data access through a "slice" mechanism Session.kt:206.
- Opening: A slice is opened only after the
maxWaitMillisperiod has passed and thehighWatermarkis checkedSession.kt:188. - Retention: The slice is held open only during the actual I/O operation (the header and the body)
Session.kt:212. - Closing: The slice is automatically closed via a
useblock, ensuring that the log segment is not held open longer than necessary, which would otherwise prevent the retention policy from deleting old segmentsSession.kt:212.
Fetch response integrity and truncation
The server ensures that responses respect the maxBytes constraint and segment boundaries:
- Truncation: If a record is cut off by the
maxByteslimit, theSessionmarks the response as truncatedServerTest.kt:117. - Segment Boundaries: A fetch operation will stop at a segment boundary; if a request spans multiple segments, the client must perform subsequent fetches to retrieve data from the next segment
ServerTest.kt:137. - Integrity: The
maxBytesconstraint is applied to the total bytes returned, and thetruncatedflag is used to signal to the client that the full record was not sentServerTest.kt:117.
Key files
| File | Lines | What is there |
|---|---|---|
…/net/BooblikServer.kt | 37-43 | The FetchMode enum defining ZERO_COPY and HEAP. |
…/net/Session.kt | 219-231 | The implementation of the fetch logic for both ZERO_COPY and HEAP modes. |
…/net/ServerTest.kt | 105-122 | Tests verifying maxBytes truncation and record integrity. |
Behaviour that surprises
- Silent Requests: When
AckPolicy.NONEis used in aProduceRequest, the server does not send any response frame at all, even if the write was successfulSession.kt:169. - High Watermark vs. Log End: A
FetchRequestat the currenthighWatermarkis considered a valid "caught-up" state and returns an empty response rather than an errorSession.kt:197. - Slice Timing: The
availablecheck forminBytesis performed by opening and immediately closing a slice to avoid holding a segment lock during theawaitRecordswait periodSession.kt:276-277.