Library / SDK
eventlet/eventlet avatar
eventlet/eventlet

eventlet: a greenlet networking library now in maintenance only

Concurrent networking library for Python

1,274 stars340 forksPythonNOASSERTION

At a glance

What is it?
eventlet runs blocking style networking code on greenlets with epoll or libevent underneath, and its own README now discourages new usage, limits changes to stability fixes and migration work, and states a goal of planning the library's retirement in favour of the standard library's asyncio. It suits teams with an existing eventlet service, and it is the wrong choice for a new project.
Who is it for?
Adopt eventlet only if you already have a service running on it and want to keep it running, because the library is still maintained for stability and bug fixes and the migration notes are there when you decide to move. Do not adopt it for anything new, since the project itself states that usages in new projects are discouraged and that no new features will be accepted except those related to the asyncio migration.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 6 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 November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • eventlet/eventlet1,274 ★ · -1
Star history
Repository2026-10-192026-11-07
eventlet/eventlet1.3k1.3k

-1 Stars in the last 19 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The warning at the top of the README is the news

The first thing in the eventlet README is a warning, and it is not a routine note about version support. It says that new usages of eventlet are now heavily discouraged, and then explains why.

Eventlet was created almost 18 years ago, at a time where async features were absent from the CPython standard library. With time eventlet evolved and CPython too, but for several years the maintenance activity of eventlet decreased, which led to a growing gap between eventlet and the CPython implementation. The README says this gap is now too high and can lead to unexpected side effects and bugs in your applications.

The new maintenance policy follows from that diagnosis. Only maintenance for stability and bug fixing will be provided. No new features will be accepted, except those related to the asyncio migration. Usages in new projects are discouraged. And the goal is stated in the plainest possible terms, to plan the retirement of eventlet and to give people ways to move away from it.

That last sentence is the part to hold on to. This is not a library in maintenance mode that will be there for a decade. It is a library in maintenance mode with an end date, and the maintainers are explicit that the end is on the way.

The README is careful about who it is talking to. If you are looking for a library to manage async network programming and you do not yet use eventlet, you are encouraged to use asyncio, the official async library of the CPython standard library. If you already use eventlet, the hope is that the migration path helps some use cases, and only migration related features will be accepted.

What eventlet does: change how you run the code, not how you write it

The description of the library itself is a sentence worth reading closely, because it explains the design and the reason it lost ground.

Eventlet is a concurrent networking library for Python that allows you to change how you run your code, not how you write it.

The mechanism underneath is greenlets. The runtime dependencies are dnspython at 1.15.0 or later and greenlet at 1.0 or later, and greenlet is the primitive that makes the whole approach possible: it is a lightweight, cooperatively scheduled coroutine that a program can suspend and resume without a thread switch.

The network layer uses epoll or libevent for highly scalable non-blocking I/O. Coroutines ensure that the developer uses a blocking style of programming similar to threading, while providing the benefits of non-blocking I/O. And the event dispatch is implicit, which the README says means you can easily use eventlet from the Python interpreter, or as a small part of a larger application.

That last property is the historical reason eventlet spread. It is the difference between a library you adopt by rewriting your call sites and one you adopt by changing how your program starts. For an application written in a blocking style, the port was close to free, which is why you still find it inside older WSGI services and chat servers.

The dependency floor is worth noting, and so is the shape of the package metadata. The project is built with hatchling and hatch-vcs, which means the version is derived from the repository tags rather than written in the manifest.

The migration path, and what counts as an acceptable change

The migration story is the reason the project still accepts patches at all, and it is structured rather than aspirational.

The README links a section called Migrating off of Eventlet in the documentation, under the asyncio section of the guides, and the policy sentence is precise: only new features related to the migration solution will be accepted.

So the project is not frozen and not open. It is open in one direction, towards making it easier to leave. That is a specific and unusual position for a library to take, and it means the useful contributions to eventlet today are the ones that reduce the amount of application code that has to change.

The scale of that work depends on how the application is written, and this is where the difference between running and writing comes back. An eventlet program is a blocking program, with a hub dispatching greenthreads and a monkey-patched socket layer underneath. Porting it to asyncio means replacing the patched blocking calls with awaits, which is a change to how you write. The easy cases are the ones that were already written in an explicit coroutine style. The hard cases are the ones with blocking third party libraries in the middle, because those libraries will block the event loop and have to be isolated.

The README says the maintainers are happy to answer questions about the maintenance goals or about the migration, through the issue tracker, which is unusual for a project that is trying to shrink.

The version floor, and the contradictions in the metadata

The support statements disagree with each other, which is worth knowing before you pin a version.

The README says Python 3.8 to 3.13 are supported, while the repository metadata specifies requires-python >=3.10 and lists classifiers for Python 3.10 through 3.14. The requires-python field restricts installation eligibility for a distribution built from that source; classifiers communicate declared support and do not set an installer upper bound.

The repository metadata may differ from a published release. Check the selected release's PyPI metadata and test it on your Python version before upgrading.

The licence has a similar mismatch. The project metadata says MIT, and the classifier list includes the MIT licence, while the licence recorded for the repository is one that GitHub could not classify, pointing at the LICENSE file. The LICENSE file is in the repository root, and the metadata is the more likely to be current, but the two are not obviously in sync.

The development status is 4, Beta, which is a classification that has probably not been revisited in a while, and it sits awkwardly next to a README that says the project plans its own retirement.

The release process is hatchling with hatch-vcs, and there are no GitHub releases in the project, so the version comes from tags. The last push to the repository was on 2026-10-19.

The examples are the documentation, and they are worth reading

For a library that is winding down, the examples directory is the most useful thing left in the repository, and it is unusually broad.

The list covers the patterns a networking library is judged by. There is an echoserver, a simple producer_consumer example and a forwarder for the basics. There is a wsgi.py, which is the adapter that let eventlet serve WSGI applications, and that file is the one to look at if you are running eventlet behind a web framework.

There is a substantial websocket group, with websocket.py, a websocket.html page, websocket_chat.py with its own HTML, and distributed_websocket_chat.py, which is the hardest of them because it involves several processes. There is a crawler pair, webcrawler.py and recursive_crawler.py, and a feedscraper with a test client. The messaging examples are zmq_simple.py and zmq_chat.py, and the chat ones are chat_server.py and chat_bridge.py.

The README points a new user at exactly three things: the examples, the common design patterns page, and the list of basic API primitives. The presence of a design patterns page is a hint about the style of use, since eventlet's idiom is less about individual coroutine primitives and more about how you structure a hub, a pool of greenthreads and a queue between them.

Building the documentation locally is a single tox invocation, with tox -e docs, and the built HTML ends up in doc/build/html.

Who should still use it, and the difference from asyncio

The decision is not really about eventlet's quality, so it is worth being explicit about the difference in approach between the two options.

asyncio is in the standard library, which means it is installed with Python, it is maintained with Python, and it is where the ecosystem energy goes. The price is that it is a different programming model. You write await, you use async def, and libraries that block have to be dealt with. The eventlet approach is the opposite trade: you keep the blocking style and the library handles the concurrency, which is why it was adopted so widely before asyncio existed.

So the difference in approach is that asyncio changes how you write the code and eventlet changed how you run it, and the migration cost falls on that axis. An eventlet codebase is mostly blocking code, so porting it is a rewrite of the call sites rather than a change of runtime.

Given the maintenance policy, the situations where eventlet is still the right call are narrow. A service in production that works, where the risk of a port exceeds the risk of staying, and where the maintainers will still fix stability bugs. A codebase that has already been ported to asyncio does not need to consider it. A new project has no reason at all to start on it, and the maintainers say so in the first paragraph of their README.

If you are in the second situation, the honest first step is the migration guide rather than a decision, because the size of the port is the thing that determines whether staying is reasonable. The project will still be there while you read it, and the policy is that it will be maintained for stability in the meantime.

Editorial conclusion

Adopt eventlet only if you already have a service running on it and want to keep it running, because the library is still maintained for stability and bug fixes and the migration notes are there when you decide to move. Do not adopt it for anything new, since the project itself states that usages in new projects are discouraged and that no new features will be accepted except those related to the asyncio migration. Before you plan a move, read the migration guide in the documentation, and budget for rewriting blocking calls into awaits, which is the part of the port that touches your application code rather than the library.

Frequently asked questions

Is eventlet still maintained?

Yes, but only for stability and bug fixing. The README states that no new features will be accepted except those related to the asyncio migration, that usages in new projects are discouraged, and that the goal is to plan the retirement of eventlet.

Should I use eventlet or asyncio for a new project?

The project itself points new users to asyncio, the official async library of the CPython standard library. The difference in approach is that asyncio changes how you write the code while eventlet changed how you run it, so the migration from eventlet is a rewrite of the call sites.

How do I install eventlet and which Python versions are supported?

The README gives pip install -U eventlet, and states that Python 3.8 to 3.13 are currently supported, while the package metadata requires Python 3.10 or later and lists classifiers up to 3.14. The runtime dependencies are dnspython 1.15.0 or later and greenlet 1.0 or later.

How does eventlet achieve concurrency?

It uses greenlets for coroutines, epoll or libevent for highly scalable non-blocking I/O, and implicit event dispatch, so the developer keeps a blocking style of programming similar to threading while the library handles the non-blocking behaviour.

Official sources

  1. eventlet/eventlet on GitHub
  2. Issues
  3. Project website
  4. README
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/eventlet-eventlet.svg)](https://hysenlabs.com/projects/eventlet-eventlet)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/eventlet-eventlet.svg)](https://hysenlabs.com/projects/eventlet-eventlet)

Was this useful?