GenStage is a specification for producer and consumer demand, not a pipeline library
Producer and consumer actors with back-pressure for Elixir
At a glance
- What is it?
- GenStage is the Elixir library that defines how producers and consumers exchange events, with demand and back-pressure as part of the contract rather than something you configure. It ships two things, the GenStage behaviour and ConsumerSupervisor, and its own README is short enough that the examples and the two libraries built on top of it carry most of the explanation.
- Who is it for?
- Adopt GenStage when you need bounded, demand-driven event flow between Elixir processes and want back-pressure to be part of the interface rather than something you bolt on. Do not adopt it as a general pipeline engine: the README is explicit that Flow and Broadway are the libraries built on top of it for map-reduce flows and for ingestion from SQS or RabbitMQ, and reach for those instead when you need them.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 79 days ago.
- What is it written in?
- Mainly Elixir, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two modules, and the README says so in one line each
The project states its scope plainly: GenStage is a specification for exchanging events between producers and consumers. It currently provides two pieces of functionality.
`GenStage` is a behaviour for implementing producer and consumer stages. `ConsumerSupervisor` is a supervisor designed for consuming events from GenStage and starting a child process per event.
That is the entire feature list. There is no third module, no plugin system, and no configuration file. Everything else people associate with GenStage, including the parts that make it pleasant, lives in the examples or in libraries built on top of it.
The library requires Elixir v1.5 and is added like any other dependency:
def deps do
[{:gen_stage, "~> 1.0"}]
endNote that the repository carries no GitHub releases at all. Releases for Elixir libraries go through Hex, not GitHub, so the absence of tags is normal here and not a maintenance signal by itself. The repository does carry a CHANGELOG.md at the root, which is the place to look for what changed.
What the examples show instead of the README
The README's Examples section names four files in the `examples/` directory, and they cover the shapes you would otherwise have to infer.
`ProducerConsumer` is described as a simple example of setting up a pipeline of `A -> B -> C` stages and having events flowing through it. That is the minimal case: three stages, events moving from one to the next.
`ConsumerSupervisor` shows how to use one or more ConsumerSupervisor as a consumer to a producer that works as a counter. So the producer is a deliberately trivial generator and the interesting part is the supervision arrangement on the receiving side.
`GenEvent` is the one worth reading first for anyone coming from older Elixir code. The README describes it as an example of how to use GenStage to implement an alternative to GenEvent that leverages concurrency and provides more flexibility regarding buffer size and back-pressure. Two capabilities are named there: buffer size and back-pressure. Both are the reasons GenEvent was considered insufficient, and both are the things GenStage makes explicit.
`RateLimiter` performs rate limiting in a GenStage pipeline, which is the clearest demonstration of why back-pressure has to live in the contract. You cannot rate limit from outside a system that never says how fast it is being called.
The repository root is correspondingly small: `.formatter.exs`, `CHANGELOG.md`, `mix.exs`, `mix.lock`, `lib/`, `test/`, `examples/` and the `docs` links in the README. There is no `docs/` directory, because the documentation lives on hexdocs.pm at http://hexdocs.pm/gen_stage, split into a `GenStage` page and a `ConsumerSupervisor` page.
So the practical learning path is: add the dependency, open `examples/producer_consumer.exs`, and read the behaviour's documentation on hexdocs. The README is an index, not a tutorial.
Why the specification is separate from the libraries people use
The README points at two projects built on top of GenStage, and the pairing explains the project's scope better than any feature list would.
Flow is for building computational flows using map-reduce, partitions, windows, and more, that run concurrently. The README links its documentation and also José Valim's ElixirConf 2016 keynote introducing the main concepts behind both GenStage and Flow.
Broadway is for building concurrent and multi-stage data ingestion and data processing pipelines to consume events from Amazon SQS, RabbitMQ, and others. Its introduction talk is linked too.
Read those three sentences together and the division of labour is clear. GenStage defines the protocol between stages: who produces, who consumes, and how much. Flow adds a computation model on top, and Broadway adds a production pipeline shape with broker integration.
That separation is the design decision that has survived the years. A pipeline that owns broker connections, batching, acknowledgements and failure handling is a different kind of thing from the protocol between two processes, and coupling them means the second cannot be used without the first. GenStage stays small enough that you can implement the behaviour yourself for a source that has unusual semantics, which is what ConsumerSupervisor is for when you need one child process per event.
If you are reaching for GenStage specifically, it is usually because you need to be the unusual source, or you want the semantics without the rest.
The README focuses the documented scope on exchanging events between producers and consumers.
Licensed like Elixir itself, which makes it the least surprising dependency
The README states the licence as the same as Elixir under Apache License 2.0, pointing at the NOTICE and LICENSE files in the elixir-lang/elixir repository for details.
That is worth stating precisely rather than paraphrasing, because GitHub's licence information for this repository is unknown, while the README states Apache 2.0 and links to Elixir's own files. If your process requires a licence identifier in the dependency manifest rather than in documentation, that discrepancy is real and worth resolving with the maintainers before a compliance review rather than after. In practice, a library under the elixir-lang organisation distributing under the same terms as the language is an unremarkable arrangement.
Maintenance is visible and current. The repository is not archived and the last push was on 2026-08-05, a little over two months before this article. The CHANGELOG.md is the authoritative record of what changed, since there are no GitHub releases to read.
Editorial conclusion
Adopt GenStage when you need bounded, demand-driven event flow between Elixir processes and want back-pressure to be part of the interface rather than something you bolt on. Do not adopt it as a general pipeline engine: the README is explicit that Flow and Broadway are the libraries built on top of it for map-reduce flows and for ingestion from SQS or RabbitMQ, and reach for those instead when you need them. Verify first which of the two shapes you actually want, read the examples directory rather than the README, and confirm your Elixir version satisfies the stated v1.5 minimum before adding the dependency.
Frequently asked questions
What does GenStage provide?
Two things: the GenStage behaviour for implementing producer and consumer stages, and ConsumerSupervisor, a supervisor for consuming GenStage events that starts a child process per event. It is a specification for exchanging events between producers and consumers.
How do I add GenStage to a mix.exs?
Add it to your deps list as `{:gen_stage, "~> 1.0"}`. The project requires Elixir v1.5 or later.
How does GenStage compare to GenEvent?
The repository includes an example showing how to use GenStage as an alternative to GenEvent that leverages concurrency and provides more flexibility regarding buffer size and back-pressure.
What should I use instead of GenStage for a data pipeline?
For computational flows using map-reduce, partitions and windows, the README points to Flow. For concurrent multi-stage ingestion from Amazon SQS, RabbitMQ and other brokers, it points to Broadway. Both are built on top of GenStage.
What license does GenStage use?
The README states it is the same as Elixir under the Apache License 2.0, pointing at the NOTICE and LICENSE files in the elixir-lang/elixir repository. The repository metadata itself records the licence as unknown.
Where is the GenStage documentation?
On hexdocs.pm at http://hexdocs.pm/gen_stage, with separate pages for the GenStage behaviour and for ConsumerSupervisor. Runnable examples live in the examples directory of the repository.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/elixir-lang-gen-stage)Was this useful?