Open-source project
bytewax/bytewax avatar
bytewax/bytewax

Bytewax tells you on the first screen that its company stopped being viable

Python Stream Processing

2,054 stars112 forksPythonApache-2.0

At a glance

What is it?
A Python framework over a Rust engine for stateful stream processing, whose readme leads with a notice that the company behind it was no longer commercially viable as of May 2025 and that the core team has stepped back. The code is in good shape and Apache-2.0, which is exactly why the notice is the thing to read first.
Who is it for?
Bytewax fits a team that wants stream processing with Python as the authoring language and is willing to hold a dependency on a community-run project, which is a smaller commitment than it sounds because the code is Apache-2.0 and the engine is small enough to read. Three things to weigh.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 108 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 6, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The first block on the page is a business failure notice

Above the description, in an importance callout, the readme says the project is now community-maintained. The reason is stated plainly: as of May 2025 the company is no longer commercially viable, and the original core team has stepped back from day to day maintenance. What remains is an Apache-2.0 project and a stated intention to rebuild the maintainer pool, with a pointer to a specific tracking issue for anyone depending on it in production and a separate document describing how to get involved. This is unusually direct, and it changes what the rest of the page means. The rest of the page is a good description of a working framework: Python first, stateful stream processing, distributed deployment, connectors, and an operator API. The maintenance state is the context for all of it, and it also lines up with the release history, where the newest published tag is from November 2024 and the last recorded commit on main is dated 2026-06-20. So roughly nineteen months of work sits past the last release.

The operator list ends with a bullet that has nothing after it

The operators section is organised into five bullets, and the first four are populated.

text
- **Stateless Operators:** `map`, `filter`, `inspect`
- **Stateful Operators:** `reduce`, `fold_window`, `stateful_map`
- **Windowing & Aggregations:** Event-time, processing-time windows, tumbling, sliding, and session windows.
- **Joins & Merges:** Combine multiple input streams with `merge`, `join`, or advanced join patterns.
- **Premium Operators:**

The last bullet is a heading with no content, so the list promises a category of paid operators that the page never describes and never says exists. Given the state of the company, the likeliest reading is that a commercial tier was planned and abandoned, leaving the line behind when the rest of the section was rewritten. It is a small thing and a useful one: it is the kind of leftover that tells a reader what the project's direction was before it stopped, and it is the only place on the page where money is mentioned at all.

Two runtime dependencies, with the engine hidden behind a private submodule

The manifest lists exactly two runtime requirements, a typing extensions package and a Prometheus client. Everything else is in the Rust crate. The build is a maturin project with the extension module named as a private submodule inside the Python package, and the Python source directory configured explicitly, so the shape is a hand-written Python surface over a compiled core rather than a generated binding. Two other files explain themselves by existing. A stub generation script sits at the repository root, which is how the hand-written Python surface gets type stubs without the bindings being generated. And there are two configuration files for a tool that checks the minimum Python version a file actually needs, one for the library and one for development, which is what you install when a package claims to support a wide range of interpreter versions and wants to keep the floor honest per file.

The container builds one interpreter, one platform and one architecture

The image definition is three stages and the middle one is where the constraints live.

dockerfile
RUN maturin build --interpreter python3.9
RUN /venv/bin/pip3 install /bytewax/target/wheels/bytewax-$BYTEWAX_VERSION-cp39-cp39-manylinux_2_31_x86_64.whl

The build tool comes from a third-party container image pinned by tag rather than from an official builder, the compiler comes from a slim Debian image on Rust 1.68, the wheel is built against CPython 3.9, and the install step hardcodes the platform tag, the manylinux baseline and the x86_64 architecture into a filename. Only the version is a build argument. So the published container covers one architecture on one platform and one interpreter, while the package manifest claims support from 3.8 through 3.14. The final stage is the debug flavour of a distroless Python image, and that choice is deliberate: the entry point runs a shell script, and the debug flavour is the one that still contains a shell. Two ports are exposed, and a second script for entrypoint recovery is copied alongside the first.

The manifest floor is 3.8 and the development environment is 3.12

The package declares a minimum of 3.8 and lists classifiers for every release from 3.8 to 3.14, plus implementations for both CPython and PyPy. The development tooling pins a single version in the middle of that range: a task runner recipe checks for the fast package manager, recommends installing it through pipx, then checks for Python 3.12 specifically, recommends pyenv to obtain it, creates a virtual environment at that version, and installs the pre-commit hooks. Every recipe then runs through a guard written as a small Python script that inspects the interpreter's prefix path and exits with an error unless you are inside either the development environment or one named plainly. It is a tidy arrangement, and it means the advertised floor of 3.8 is a compatibility claim maintained by tooling rather than the version anyone actually develops against. The engine's own toolchain version in the container is older still than the development interpreter, which is the sort of gap that matters only at build time.

The engine mixes a two year old web framework with current language bindings

The crate's dependency list is where the age of the project shows most clearly. The web server dependency sits on version 0.5 of its line while the language bindings are several major releases ahead and the telemetry stack is two majors further on. Everything else is either current or pinned sensibly: the async runtime with all features, the tracing family wired to the telemetry exporters for both traces and metrics, the Prometheus client, and the SQLite driver with the bundled feature so the database is compiled in rather than expected from the system. One dependency is not from a registry at all: a dataflow library is pulled from its repository at a fixed commit hash, which pins the build but means the build needs network access to fetch it. The observability stack is unusually heavy for a stream processing library, with three telemetry exporters in the list, which tells you the project expected to be operated rather than merely run.

Kafka is an optional extra, and several examples need a broker running

The optional dependency group for Kafka adds a plain HTTP client, an Apache Avro implementation and a confluent-kafka client, and nothing else about the package depends on any of them. Standard input and output are built in, and everything else is either a custom connector or something contributed to the project's module hub. That split shows up in the examples directory, which has two dozen scripts, and the ones that exercise Kafka are written against a Kafka compatible broker rather than a broker you are likely to have installed: two of them are named for that broker, one of those covering anomaly detection and one covering serialisation, plus a plain one for producing and consuming. So the examples that need external infrastructure are also the examples that need a container running first. The local path for everything else is one command, with a worker count flag for more parallelism, and the test story leans on an in-memory source shipped with the testing module.

Editorial conclusion

Bytewax fits a team that wants stream processing with Python as the authoring language and is willing to hold a dependency on a community-run project, which is a smaller commitment than it sounds because the code is Apache-2.0 and the engine is small enough to read. Three things to weigh. The project's own readme says the company behind it stopped being commercially viable and the original team stepped back, so treat the maintainer situation as your first risk rather than the last. The newest release is from November 2024 with the branch nineteen months ahead of it, so pin deliberately. And the container image builds one architecture, one platform and CPython 3.9 only, which means anything on arm64 or a newer interpreter is on the pip path, not the image path.

Frequently asked questions

what is bytewax

A Python framework over a Rust-based distributed engine for stateful event and stream processing. You build a dataflow of operators and connectors in Python, and the engine maintains distributed state, supports fault tolerance and state recovery, and handles event-time windowing.

Is Bytewax still maintained?

The readme states it is community-maintained: as of May 2025 the company was no longer commercially viable and the original core team stepped back from day to day maintenance. The project remains Apache-2.0, the page says the maintainer pool is being rebuilt, and it points at a tracking issue and a maintainers document.

What is the newest Bytewax release?

v0.21.1, published 2024-11-25, which matches the version in the crate manifest. The last recorded commit on the main branch is dated 2026-06-20, so a branch checkout is considerably newer than the newest tag.

How do I run a Bytewax dataflow locally?

Run the module against your flow file, for example python -m bytewax.run my_dataflow.py, and add a worker count flag such as -w 2 for more parallelism. For debugging the page points at the testing source and the inspect operator, both of which ship with the package.

Does Bytewax support Kafka?

Yes, as an optional dependency group that adds a plain HTTP client, an Avro implementation and a confluent-kafka client. Standard input and output are built in, further connectors can be written or taken from the project's module hub, and several of the repository examples are written against a Kafka compatible broker you would need running yourself.

Official sources

  1. bytewax/bytewax on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bytewax-bytewax.svg)](https://hysenlabs.com/projects/bytewax-bytewax)