I haven't had much time to work on blog posts recently, but I do have one quick post to make.

One of our current application prototype's stores a bunch of data. Data continuously arrives, but I only want to store so much of it. You could do this with something list a List<T> and just remove items when the collection is too big, but I wanted something a bit more efficient which didn't have to do any sort of resizing or allocation when adding and removing items. Enter the circular buffer.

What is a circular buffer?

To quote Wikipedia, a circular buffer, cyclic buffer or ring buffer is a data structure that uses a single, fixed-size buffer as if it were connected end-to-end. This structure lends itself easily to buffering data streams.

Indeed. Originally I didn't want to invent the wheel, so when I found Circular Buffer for .NET1 I thought I would use that. Unfortunately as soon as I started using, I hit some problems, both in the code and with what I was trying to do. So I stopped working on what I was doing and wrote a full set of tests for the class, fixing bugs as I went, and also adding some more features to handle what I wanted.

Eventually I decided I would put the code up on GitHub as Circular Buffer for .NET doesn't seem to be maintained any longer.

A generic CircularBuffer<T> class for .NET

On our GitHub page you can download a modified version of the original class. I'm not going into too many details here as it's very straightforward to use - if you've used Queue<T> or Stack<T> then you'll be right at home.

  • Get - Removes and returns one or more items from the start of the buffer
  • Put - Adds one or more items to the end of the buffer. If the buffer is full, then items at the start will be overwritten
  • Peek - Retrieve one or more items from the start of the buffer, without removing them
  • PeekLast - Retrieve the last item in the buffer without removing it
  • ToArray - Return all items in the buffer
  • CopyTo - An advanced version of ToArray, allows you to copy items from the buffer into another array
  • Clear - Resets the buffer

There are also some properties to control behaviour or provide state information.

  • Capacity - The total number of items the buffer can hold
  • Size - The current number of items in the buffer
  • AllowOverwrite - When true, new items overwrite the oldest items when the buffer is full. Otherwise, an exception is thrown
  • IsEmpty - true if the buffer is empty
  • IsFull - true if the buffer is full and AllowOverwrite is false


This first example creates a CircularBuffer<T>, adds four items, then retrieves the first item.

CircularBuffer<string> target;
string firstItem;

target = new CircularBuffer<string>(10);

firstItem = target.Get(); // Returns Alpha

This second example shows how the buffer will automatically overwrite the oldest items when full.

CircularBuffer<string> target;
string firstItem;

target = new CircularBuffer<string>(3);

firstItem = target.Get(); // Returns beta

For more examples, see the test class CircularBufferTests as this has tests which cover almost all the code paths.


.NET Framework 2.0 or later.



Update History

  • 2014-06-21 - First published
  • 2020-11-21 - Updated formatting
  • 2023-02-05 - Fixed swapped URLs

Like what you're reading? Perhaps you like to buy us a coffee?

Donate via Buy Me a Coffee

Donate via PayPal


# Mercede

Is this threadsafe or we have to make it threadsafe>


# Richard Moss


Thanks for the question. At the moment, it's not thread safe - the initial use I had for the class didn't involve multi-threaded access and I didn't want to burden the base class with having to do processing that wouldn't be used.

Richard Moss