TRT
Sign in
easyFoundationsconcept

How does a ring buffer work, and why do systems use it?

Explain head, size and wrap-around, full versus empty, growth and overflow policies, and where ring buffers appear in real systems.

TRT practice prompt — not a verified question from a named employer.

The Runtime Theory Team2 min read
Learn it firstQueues and ring buffersA queue serves items in the order they arrived. Built on a ring buffer, a fixed array whose start and end wrap around, every operation is O(1) and no item ever moves.

A strong answer

A ring buffer is a fixed-size array used as a queue. It keeps the index of the oldest item, head, and the number of items, size. Enqueue writes at (head + size) % capacity and increments size; dequeue reads buf[head], advances head = (head + 1) % capacity and decrements size. The remainder makes the end of the array wrap around to its start, so slots freed by dequeues are reused. Every operation is O(1), nothing is allocated after creation, and items never move once written.

If the buffer stores head and tail instead, head == tail means either empty or full; implementations either keep a count or leave one slot unused. A power-of-two capacity lets % capacity become & (capacity − 1), one instruction.

When the buffer is full, the policy is a design choice: grow it (allocate double and copy the items in queue order, as Java's ArrayDeque does), block the producer (backpressure), overwrite the oldest item (logs of recent events, audio), or reject the new item.

Systems use ring buffers because they are predictable: fixed memory, no allocation, cache-friendly sequential access, and a natural fit for a producer and a consumer working at different paces. Network cards receive packets into rings shared with the kernel, Linux's io_uring uses submission and completion rings, audio drivers stream samples through them, and the LMAX Disruptor passes messages between threads with one. With exactly one producer and one consumer, each index is written by only one side, so the buffer can be made thread-safe with atomic loads and stores instead of a lock.

What the interviewer is listening for

  • The index arithmetic and why nothing shifts.
  • The full-versus-empty ambiguity and its fixes.
  • Overflow policies and backpressure.
  • Real uses, and why fixed memory matters there.

Common mistakes

  • Shifting items on dequeue, which defeats the purpose.
  • Copying a wrapped buffer straight into a larger array, which scrambles the order.
  • Forgetting to define what happens when the buffer is full.

This answer walks

Practice follow-ups

  1. 01How do you tell a full ring buffer from an empty one if you store only head and tail?
  2. 02Why do many implementations require the capacity to be a power of two?
  3. 03What should happen when a producer writes to a full buffer?
  4. 04Why can one producer and one consumer share a ring buffer without a lock?

Not started

Sign in to save your learning progress.

Sign in to save