Slow Requests on Local Flask Server

Just starting to play around with Flask on a local server and I'm noticing the request/response times are way slower than I feel they should be.

Just a simple server like the following takes close to 5 seconds to respond.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "index"

if __name__ == "__main__":
    app.run()

Any ideas? Or is this just how the local server is?


Solution 1:

Ok I figured it out. It appears to be an issue with Werkzeug and os's that support ipv6.

From the Werkzeug site http://werkzeug.pocoo.org/docs/serving/:

On operating systems that support ipv6 and have it configured such as modern Linux systems, OS X 10.4 or higher as well as Windows Vista some browsers can be painfully slow if accessing your local server. The reason for this is that sometimes “localhost” is configured to be available on both ipv4 and ipv6 socktes and some browsers will try to access ipv6 first and then ivp4.

So the fix is to disable ipv6 from the localhost by commenting out the following line from my hosts file:

::1             localhost 

Once I do this the latency problems go away.

I'm really digging Flask and I'm glad that it's not a problem with the framework. I knew it couldn't be.

Solution 2:

Add "threaded=True" as an argument to app.run(), as suggested here: http://arusahni.net/blog/2013/10/flask-multithreading.html

For example: app.run(host="0.0.0.0", port=8080, threaded=True)

The ipv6-disabling solution did not work for me, but this did.

Solution 3:

The solution from @sajid-siddiqi is technically correct, but keep in mind that the built-in WSGI server in Werkzeug (which is packaged into Flask and what it uses for app.run()) is only single-threaded.

Install a WSGI server to be able to handle multi-threaded behavior. I did a bunch of research on various WSGI server performances. Your needs may vary, but if all you're using is Flask, then I would recommend one of the following webservers.

Update (2020-07-25): It looks like gevent started supporting python3 5 years ago, shortly after I commented that it didn't, so you can use gevent now.

gevent

You can install gevent through pip with the command pip install gevent or pip3 with the command pip3 install gevent. Instructions on how to modify your code accordingly are here: https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent

meinheld

gevent is better, but from all the benchmarks I've looked at that involve real-world testing, meinheld seems to be the most straightforward, simplistic WSGI server. (You could also take a look at uWSGI if you don't mind some more configuration.)

You can also install meinheld through pip3 with the command pip3 install meinheld. From there, look at the sample provided in the meinheld source to integrate Flask: https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py

*NOTE: From my use of PyCharm, the line from meinheld import server highlights as an error, but the server will run, so you can ignore the error.