An asynchronous CherryPy server based on asyncio

CherryPy is a minimalist web application server written in Python. Hundreds of people have relied on it for more than fourteen years now. Recently, I’ve gained interest in the native asynchronous support Python has gained through the implementation of PEP-3156 and PEP-0492. Basically, Python now supports coroutines natively and in a friendly API interface. In addition, thanks to the built-in asyncio module, you can naturally develop concurrent applications.

CherryPy has always used a multi-threaded engine to support concurrent web applications. This may sound surprising, but this is working very well still in 2016. Yet, I love a puzzle and I was interested in making CherryPy run as a set of coroutines rather than a bunch of threads. So a couple of days ago, I set myself on the task to make it happen.

And so here it is, CherryPy on asyncio!

This a branch on my fork, not an official part of the CherryPy project yet.

Now, you can run code like this:

The only differences are:

  • importing cherrypy.async
  • turning page-handlers into coroutines

That is all.

The idea is that the cherrypy.async patches all the internals of CherryPy for you and turn it into an async-aware server.

Note that the code currently runs only on Python 3.5+ as we use the async/await keywords.

Has it been easy?

Turning a project that was not designed for coroutines is not that complicated thanks to the simple interface provided by async/await. However, anytime an I/O operation is performed, it is necessary to transform a call like:


This mundane line is sometimes is part of a function call, in that case, you have to overwrite and copy/paste the whole function to change that one line. Mind you, this can’t be avoided because you must also re-declare the function as a coroutine anyway by prefixing it with async.

As usual, the difficulty lies in the entanglement of your code. The more you made simple to comprehend, the simpler and faster it will be to change with confidence.

What was changed?

Mostly the HTTP server, the machinery of CherryPy: the internal engine/bus, the dispatcher, the request handling.

If we can find a way to re-organise the existing code, actually few lines would eventually be changed.

Note, I made the decision not to make this server WSGI aware because I find that rather counter-intuitive with an async-based server somehow.

Is it production ready?

Not at all. It hasn’t been really tested (this will require to re-write many tests so that they play along with coroutines).

It is also, for some unknown reason yet, much slower than the multithreaded version. Profiling will need to be performed.

Still, if you are feeling like testing it:

I don’t know if this code will go further than this but, maybe this will interest the community enough so that it moves forward. This would make CherryPy more suitable for HTTP2 and websockets.

8 thoughts on “An asynchronous CherryPy server based on asyncio”

  1. Hi Sylvain,

    very nice work. But also interesting to see that you found such a big performance gap btw the threaded vs the asyncio approach. In case you keep investigating about that it would be nice to learn from you what it was.

    Apart from that I still think cherrypy is a great project, we are still using it for a large lab information management system in a biotech company for many years and I’m still really happy about it!

    1. Hi Ralph,

      Thanks for the feedback.

      I’m indeed surprised about the drop in performances. I can only assume the code would need a little tuning. If I get the chance, I will profile the code.


      1. Hi could it be because any cpu bound operation blocks the entire system? In nodejs this is what happens because it’s totally async but single threaded.

  2. Hi Sylvain,

    I learned CherryPy from your book. Now it is amazing that I can study more latest skills (such as asyncio) at your

    What’s more, I highly recommend developers to study Although it looks 5 years old, the modular design of Twiseless is enterprise level, like classic songs of Édith Piaf: timeless and priceless.
    Now I know how to reuse plugins and tools.

    Thank you for your contributions.


  3. Hi i think the proper way to do this is keep the theads but release them while waiting for async operation to complete. It’s not a good idea to remove threads. You will loose a lot doing So: any cpu bound task will block the entire system.
    See how they do it in Very interesting Read:

    If cherrypy could do it like this it will be way ahead other frameworks and servers.

Leave a Reply to Benj Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.