A ring buffer is a linear data structure of a fixed, finite size. Ring buffers consist of two pointers:
- Read pointers point to where the “consumer” finds the next item in the buffer. It’s advanced forward when an item is removed.
- Write pointers point to where the “producer” inserts items into the buffer. It’s advanced forward when an item is inserted.
When both pointers are equal, the buffer is empty. It is full when the write pointer is one less than the read pointer. The read pointer should never advance past the write pointer.
Ring buffers are not circular (obviously) in practice: each pointer is wrapped to 0 when they reach the end of the buffer, so an infinite amount of data can flow through the buffer. Software implementations will use a modulo operator to bound the pointers to a valid range.

Ring buffers see wide use in performance-sensitive code (like in KMDs). This is because elements aren’t shuffled around when an element is consumed, and because they use a fixed amount of contiguous memory.
Resources
- What is a circular buffer?, in the Linux Kernel