# Quantum is a Bloomberg C++ coroutine framework built on Boost coroutine2

> Quantum is a header-only C++ framework that dispatches tasks as Boost coroutines and runs them concurrently on a reactor, with futures and promises in the STL style, task chaining, prioritisation and a sequencer for strict FIFO ordering. Its last release was v2.2 in 2021 and the last push was on 2026-04-08, so treat it as a stable snapshot rather than a moving dependency.

**bloomberg/quantum** — Powerful multi-threaded coroutine dispatcher and parallel execution engine

- Repository: https://github.com/bloomberg/quantum
- Stars: 642 · Forks: 108
- Language: C++
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/bloomberg-quantum

## What problem Quantum solves inside a Bloomberg C++ stack

Quantum is described as a full-featured and powerful C++ framework built on top of the Boost coroutine library, and the model it uses is the reactor pattern. Users dispatch units of work, called tasks, as coroutines, and the framework executes them concurrently.

The audience is implied by the repository's owner. Bloomberg is a financial data and trading infrastructure provider, and the topics list names boost, coroutines, cpp, multi-threading and parallel. This is infrastructure code for a low-latency environment, which shapes everything about the design.

The problem it addresses is the one every C++ system faces when work is both CPU bound and needs to be scheduled: a thread pool gives you parallelism but no structured control over what runs when, and raw threads give you neither. Quantum gives you a dispatcher that accepts work items and runs them as coroutines, and a future and promise interface in the style of the standard library, so the code that consumes results looks like ordinary asynchronous code.

The README is explicit that the library is designed for two kinds of workload: highly parallelized coroutine frameworks for CPU-bound workloads, and support for long-running or blocking IO tasks. The second point matters more than it first appears, because a coroutine that blocks a thread is a coroutine framework used incorrectly, and a framework that knows about IO tasks is telling you it has thought about where the blocking happens.

The interface-based, header-only design is the other structural fact. There is nothing to build and nothing to link beyond Boost's own libraries, which makes Quantum easy to drop into an existing build system, and easy to vendor if you already vendor Boost.

## The reactor model in fifteen lines of code

The sample code in the README is short, and reading it tells you the whole model.

```c++
using namespace Bloomberg::quantum;

// Define a coroutine
int getDummyValue(CoroContextPtr<int> ctx)
{
    int value;
    ...           //do some work
    ctx->yield(); //be nice and let other coroutines run (optional cooperation)
    ...           //do more work and calculate 'value'
    return ctx->set(value);
}

// Create a dispatcher
Dispatcher dispatcher;

// Dispatch a work item to do some work and return a value
int result = dispatcher.post(getDummyValue)->get();
```

A coroutine is a function that takes a context pointer and returns a value. The context is the handle through which the coroutine cooperates with the scheduler: ctx->yield() hands control back so other coroutines can run, and ctx->set(value) publishes the result. The dispatcher is the reactor that owns the worker threads and the queues, and post() submits the work and hands back a future.

The get() call at the end is where the reactor pattern becomes visible. A future that has not been satisfied blocks its caller, and the dispatcher's threads keep other coroutines moving while it waits. That is the difference from std::async, where a blocked future typically ties up a thread.

Two API generations appear in the README, and the difference is worth understanding before you write code. The original API uses CoroContextPtr<T> and an explicit ctx->set(value) at the end of every stage. The newer V2 API, which the README flags as new support for a simpler coroutine API that returns computed values directly, uses VoidContextPtr and returns the value from the lambda itself, so a stage reads as a plain function that happens to be a coroutine.

If you are starting fresh, the V2 form is the one to reach for.

## Chaining turns four coroutines into a pipeline

Task continuations and coroutine chaining are the features that make Quantum a framework rather than a scheduler, and the README's chaining example is the clearest statement of the model.

```c++
auto ctx = dispatcher.postFirst([](CoroContextPtr<int> ctx)->int {
    return ctx->set(55); //Set the 1st value
})->then([](CoroContextPtr<double> ctx)->int {
    // Get the first value and add something to it
    return ctx->set(ctx->getPrev<int>() + 22.33); //Set the 2nd value
})->then([](CoroContextPtr<std::string> ctx)->int {
    return ctx->set("Hello world!"); //Set the 3rd value
})->finally([](CoroContextPtr<std::list<int>> ctx)->int {
    return ctx->set(std::list<int>{1,2,3}); //Set 4th value
})->end();
```

Four stages, three of them then and one finally, and each stage runs after the previous one has produced its value. The context carries the value forward, and ctx->getPrev<int>() reads the previous stage's output, so a chain is a data flow rather than a set of independent tasks.

The retrieval semantics are where the sharp edges are, and the README annotates them. A chain future is a sequence of values, and reading a value twice is an error: the comment on getAt<int>(0) says it will throw FutureAlreadyRetrievedException since the future was already read in the second coroutine. The getAt overloads index into the chain by stage, getRefAt returns a reference to a value, and get() returns the last value, with the note that the At overload is optional for the last chain future.

The same chain in the V2 API drops the set calls and returns the values directly, which removes the possibility of forgetting to set one. That difference is the whole reason the newer API exists.

## Sequencing, prioritisation and the lock-free path

Three features in the list are about control rather than about throughput, and they are the ones that distinguish a reactor from a thread pool.

The Sequencer class allows strict FIFO ordering of tasks based on sequence ids. In a data pipeline where stage two must consume stage one's output in order, a scheduler that runs tasks as they arrive will produce the wrong answer, and the usual fixes are locks or a single-threaded queue. Quantum offers ordering as a first-class mechanism instead.

Task prioritisation lets a dispatcher run important work ahead of background work, which matters when a low latency request shares a thread pool with a batch job. And the feature list mentions the ability to write lock-free code by synchronizing coroutines on dedicated queues, so that instead of contending on a mutex, coroutines hand off to each other through a queue.

There is also a set of coroutine-friendly synchronisation primitives. The README lists coroutine-friendly mutexes and condition variables for locking critical code paths or synchronizing access to external objects, and a set of past futures, cascading execution output during task continuations, streaming futures for faster processing of large data sets, and support for future references.

Streaming futures deserve a note, because they address a real problem with futures in data processing. A conventional future hands you one value once. A streaming future lets a consumer receive values as they are produced, which is what you want when the producer is generating a large series and the consumer wants to start working before the series ends.

## Building, installing and the CMake options that matter

Quantum is a header-only library, and the README says as such, which means no targets need to be built. Installing is a configure and a make install:

```shell
> cmake -Bbuild <options> .
> cd build
> make install
```

The options are where the real decisions live, and the README lists them all with their defaults. QUANTUM_BUILD_DOC builds Doxygen documentation and is off by default. QUANTUM_ENABLE_TESTS builds the tests target and is also off by default. QUANTUM_ENABLE_DOT generates DOT viewer files, off by default. QUANTUM_VERBOSE_MAKEFILE is on by default.

The Boost-related options control how coroutines get their stacks, and this is where platform problems come from. QUANTUM_BOOST_USE_SEGMENTED_STACKS, QUANTUM_BOOST_USE_PROTECTED_STACKS and QUANTUM_BOOST_USE_FIXEDSIZE_STACKS are all off by default, and the protected stack option is annotated as slow. QUANTUM_BOOST_STATIC_LIBS and QUANTUM_BOOST_USE_MULTITHREADED are both on by default, meaning the default build links Boost statically and expects the multi-threaded Boost libraries.

The allocator options are for people with a specific problem. QUANTUM_USE_DEFAULT_ALLOCATOR switches to the system allocator instead of Quantum's, and QUANTUM_ALLOCATE_POOL_FROM_HEAP pre-allocates object pools from the heap rather than the application stack. The README also mentions fast pre-allocated memory pools for internal objects and coroutines in the feature list, so the default configuration assumes you can afford the pools on the stack.

Installation paths are handled by QUANTUM_INSTALL_ROOT, which defaults to /usr/local/include on Linux and c:/Program Files on Windows, with QUANTUM_PKGCONFIG_DIR and QUANTUM_CMAKE_CONFIG_DIR for the pkg-config and CMake config files, and both exports on by default. BOOST_ROOT and GTEST_ROOT let you point at a different Boost or GTest installation. The README notes that options must be preceded with -D when passed as arguments to CMake.

## Running the tests and what the project does not say

The test path is documented the same way as the install path, from the top directory:

```shell
> cmake -Bbuild -DQUANTUM_ENABLE_TESTS=ON <options> .
> cd build
> make quantum_test && ctest
```

To use the library you include quantum/quantum.h in your application, and two libraries must also be linked: boost_context and pthread. That is a short list, and boost_context is the one to check, because it is the library that provides the coroutine machinery Quantum is built on.

The README states that the library is fully compatible with C++11, C++14 and C++17 language features. That is a useful fact and also a dated one, because the standard library futures that Quantum's interface deliberately mirrors have grown considerably since C++11, and a team starting a new project today has better options available for the same shape of problem.

The repository layout is small and conventional: a quantum directory for the headers, a tests directory, a cmake directory, a docs directory, a Doxyfile.in, a CONTRIBUTING file and a DCO file, which tells you the project expects contributions to be signed off under a developer certificate of origin.

On maintenance, the facts are thin and worth stating plainly. The repository is not archived, but the most recent tagged releases are v2.2 from 2021-04-14, v2.1 from 2019-11-04 and v2.0.1 from 2019-05-14, and the last push was on 2026-04-08. The build status badge in the README still points at Travis CI while the repository also carries a .github directory, and the .travis.yml file is still at the top level, so the continuous integration setup has been left in a transitional state.

The licence is Apache-2.0, which is permissive and carries the usual patent grant and notice requirements, which is a reasonable choice for infrastructure code that a company may want to embed in a larger product.

## Conclusion

Adopt Quantum if you are working in C++ on a Bloomberg codebase, or on any codebase already committed to Boost coroutine2, and you want task dispatch with futures, chaining and deterministic ordering rather than a raw thread pool. Do not adopt it for a new project that needs C++20 coroutines, since Quantum is built on Boost's asymmetric coroutine library and the newer V2 API in the README still follows that model, and do not expect an active upstream roadmap, because the last tagged release is v2.2 from 2021-04-14 and the last push was on 2026-04-08. Verify first that the Boost version you have provides the coroutine facilities Quantum expects, that your toolchain can build the Boost context library, since boost_context and pthread must be linked, and that the Boost stack options you enable match what your platform supports, since the segmented, protected and fixed size stack choices are all off by default.

## FAQ

### What is the Bloomberg Quantum library used for?

Quantum is a header-only C++ framework built on the Boost coroutine library that dispatches units of work as coroutines and executes them concurrently using the reactor pattern. It targets both CPU-bound parallel workloads and long-running or blocking IO tasks, with futures and promises similar to the STL.

### How do I build and install Quantum?

Quantum is header-only, so nothing needs compiling ahead of use. Run cmake -Bbuild with any options, then cd build and make install. The install root defaults to /usr/local/include on Linux and c:/Program Files on Windows, and options must be passed with the -D prefix.

### Which libraries do I need to link when using Quantum?

The README says to include <quantum/quantum.h> in your application and to link boost_context and pthread. Quantum is built on the Boost asymmetric coroutine library, so boost_context is the dependency to check when you are resolving a toolchain or Boost version.

### What is the difference between the Quantum V1 and V2 coroutine APIs?

The original API uses CoroContextPtr<T> and requires an explicit ctx->set(value) at the end of each stage, while the newer V2 API uses VoidContextPtr and returns the computed value directly from the coroutine. The README lists the simpler V2 API that returns computed values directly as a new feature.

### How does Quantum guarantee task ordering?

The Sequencer class allows strict FIFO ordering of tasks based on sequence ids, and the feature list also mentions task prioritisation and the ability to write lock-free code by synchronizing coroutines on dedicated queues, with coroutine-friendly mutexes and condition variables for critical code paths.

## Sources

- [bloomberg/quantum on GitHub](https://github.com/bloomberg/quantum)
- [Issues](https://github.com/bloomberg/quantum/issues)
- [License: Apache-2.0](https://github.com/bloomberg/quantum/blob/master/LICENSE)
- [README](https://github.com/bloomberg/quantum/blob/master/README.md)
- [Releases](https://github.com/bloomberg/quantum/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bloomberg-quantum
