How to use gevent and tornado in a single application?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Using gevent and Tornado in the same application is possible, but the straightforward answer is that you usually should not try to make them share one event loop. They are built around different concurrency models, so the practical solutions are either to choose one stack for the whole service or to isolate the gevent and Tornado parts into separate processes that communicate over a clear boundary.
Why combining them is awkward
gevent works by monkey-patching blocking I/O and scheduling greenlets cooperatively. Tornado is built around its own non-blocking event loop and explicit asynchronous programming style. Both want to define how network operations behave, and that is where the trouble starts.
The problem is not that they cannot exist in one deployment. The problem is that forcing them to run as if they were one runtime usually creates subtle bugs around sockets, timeouts, DNS, and third-party libraries.
The safest pattern is process isolation
If you already have a Tornado web application and some gevent-friendly code, the cleanest design is usually to run them as separate services. Let Tornado own the HTTP interface and let the gevent side handle the work it is good at, such as high-volume cooperative network clients.
A minimal example looks like this:
This is still one overall system, but each runtime keeps control over its own event model.
If you must keep one process, minimize overlap
Sometimes a full separation is not realistic right away. If both libraries must exist in one process, keep the boundary narrow. Do not monkey-patch late, do not let both frameworks compete for the same socket layer, and do not assume every third-party library behaves correctly after patching.
In practice, that usually means one of the frameworks is only a small compatibility island, not a peer runtime.
Often the better answer is to replace one of them
A lot of teams asking this question are really trying to preserve legacy code during a migration. In that situation, a better end state is usually:
- Tornado plus
asynciofor the whole service - or
geventplus a WSGI layer for the whole service
Mixing both long-term usually increases operational complexity without adding useful capability.
If you need Tornado's modern async style, port the gevent portion gradually. If you need gevent patching for a legacy dependency, keep it outside the Tornado service boundary.
Watch blocking calls even in the isolated design
Using both frameworks does not magically make blocking code safe. For example, a Tornado handler that calls a blocking HTTP client or a gevent worker using a library that ignores monkey patching can still stall the service.
The main rule stays the same: each side must still respect its own concurrency model.
Use integration boundaries you can test
If you split the runtimes by process, communicate through plain HTTP, a queue, or RPC. That gives you testable interfaces and makes the system easier to reason about. It also makes future migration easier because you can replace one side without rewriting everything at once.
That is a much more maintainable answer than trying to build a fragile hybrid loop.
Common Pitfalls
- Trying to make
geventand Tornado share one event loop as equal peers. - Monkey-patching too late after other networking modules are already imported.
- Assuming all third-party libraries behave correctly under
geventpatching. - Mixing blocking calls into Tornado handlers and blaming the framework integration.
- Treating a migration bridge as a permanent architecture.
Summary
- '
geventand Tornado use different concurrency models and do not combine cleanly in one loop.' - The safest design is to isolate them into separate processes or services.
- If both must live in one codebase temporarily, keep the boundary narrow and explicit.
- Long term, standardizing on one async model is usually the better architecture.
- Test the boundary between the two runtimes rather than relying on fragile in-process magic.
Related reading
- How to use Git and Dropbox together?
- How to use Google API Client Library for JavaScript gapi with async/await?
- How to use HttpWebRequest .NET asynchronously?
- How to use HttpWebRequest .NET asynchronously?
- how to use GridSearchCV with custom estimator in sklearn?
- How to use keras layers in custom keras layer
- How to use Huggingface Trainer with multiple GPUs?
- How to use JUnit to test asynchronous processes
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.