99

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?

Meroon
  • 3,458
  • 4
  • 25
  • 29
  • Its not the local server but it might have to do with other applications running in the background what OS are you running this on? – gabeio Jun 22 '12 at 04:51
  • I'm running on OS X 10.7 on a i7 iMac – Meroon Jun 22 '12 at 04:55
  • 1
    It should not be taking this long for your responses but I have actually messed around with flask before to no success I would advise [Bottlepy](http://bottlepy.org/). Though still check your background processes you might have an older version of your server running in the background taking over your python and causing your slow responses. Also it could be your browser does this happen in chrome & safari? – gabeio Jun 22 '12 at 04:58
  • 2
    @Meroon's answer was correct for me. Rather than changing the host settings, however: Might I recommend simply using 127.0.0.1 instead of localhost? That solved the problem without changing the system configuration. – David Bernat Feb 10 '19 at 20:39

10 Answers10

104

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.

Meroon
  • 3,458
  • 4
  • 25
  • 29
  • 3
    I found these useful: Windows http://www.techunboxed.com/2012/08/how-to-disable-ipv6-in-windows-8.html Ubuntu http://www.noobslab.com/2012/05/disable-ipv6-if-your-internet-is.html – Larry Eitel Jan 21 '13 at 14:18
  • thanks a lot! suddenly dev testing is snappy and responsive! my only question: as the Mac hosts file indicates that removing localhost could affect my Mac's operations, I wonder whether it is referring to this line (or the one that simply locates localhost to 127.0.0.1 – David B. Oct 07 '16 at 21:47
  • on my windows 10 system in the hosts file both entries (ip4 and ip6) are commented out; they are resolved by the DNS system. I got a huge speed increase when i ran the server on "127.0.0.1" instead of "localhost" (from 2.0 to 0.003 secs for simple calls) – Lars Nov 15 '19 at 08:18
  • Thank you for this answer! Although my situation was a bit different (running nose2 against aiosmtpd), your answer gave me a hint: When I _disable IPv6_ on my Windows 10 laptop speeds up things like 10x or 100x !! – pepoluan Oct 09 '20 at 18:12
100

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.

Sajid Siddiqi
  • 1,109
  • 1
  • 7
  • 2
  • 5
    Passing `--threaded` to my `manage.py` using `Flask-Script` worked too. – Snorfalorpagus Aug 05 '15 at 22:09
  • 8
    For those who get it "fixed" by enabling threads, be warned! In this case the delay was caused by the previous request not being closed properly, so now it is actually [just stacking a lot of threads](http://i.stack.imgur.com/lRUpS.png). – cvsguimaraes Oct 23 '15 at 11:38
  • 1
    Thank you sir for making my localhost run blazingly fast. – benjaminz May 25 '16 at 23:58
  • @snolflake: Is there a way to know whether the requests aren't being closed properly? – Kylotan May 11 '17 at 19:37
  • @Kylotan There's probably a way to do that. However it's been a while since I worked with python so I can't be of much help right now. Sorry. – cvsguimaraes May 12 '17 at 16:27
  • 1
    From the command line I used `flask run --with-threads` which solved my problem. – arno_v Apr 13 '18 at 11:33
25

Instead of calling http://localhost:port/endpoint call http://127.0.0.1:port/endpoint. This removed the initial 500ms delay for me.

LangeTreeDorpie
  • 328
  • 5
  • 11
  • 2
    for me it removed something like 3seconds (I moved form 0.0.0.0 to 127.0.0.1). Can somebody explain why and how it works? – Rotkiv Apr 24 '20 at 01:04
  • 6
    Why in gods name does this work? Went from 2.06 seconds to 0.002 seconds. Browser is able to use localhost without problem, but requests.get on localhost takes 2 seconds to resolve. – Xevion Jun 20 '20 at 15:57
  • https://stackoverflow.com/questions/71919526/flask-post-request-optimization/71919719#71919719 – MetaStack Apr 19 '22 at 04:35
15

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.

mikeho
  • 6,790
  • 3
  • 34
  • 46
  • I had major performance problems with Flask, even simplest requests were taking about 0.5s to finish. Just switched to gevent and everything works flawlessly, thank you! – gronostaj Jun 07 '15 at 22:55
10

My problem was solved by "threaded=True", but I want to give some background to distinguish my problem from others for which this may not do it.

  1. My issue only arose when running Flask with python3. Switching to python2, I no longer had this issue.
  2. My problem manifested only when accessing the api with Chrome, at which point, Chrome displayed the expected screen, but everything else hung (curl, ffx, etc) until I either reloaded or closed the Chrome tab, at which point everything else that was waiting around returned a result.

My best guess is that Chrome was trying to keep the session open and Flask was blocking the subsequent requests. As soon as the connection from Chrome was stopped or reset, everything else was processed.

In my case, threading fixed it. Of course, I'm now going through some of the links others have provided to make sure that it's not going to cause any other issues.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
ChePazzo
  • 181
  • 2
  • 3
6

threaded=True works for me, but finally I figured out that the issue is due to foxyproxy on firefox. Since when the flask app is running on localhost, slow response happens if

  • foxyproxy is enabled on firefox

slow response won't happen if

  • foxyproxy is disabled on firefox

  • access the website using other browsers

The only solution I found is to disable foxyproxy, tried to add localhost to proxy blacklist and tweak settings but none of them worked.

edward
  • 101
  • 2
  • 3
6

I used Miheko's response to solve my issue.

::1 localhost was already commented out on my hosts file, and setting Threaded=true didn't work for me. Every REST request was taking 1 second to process instead of being instant.

I'm using python 3.6, and I got flask to be fast and responsive to REST requests by making flask use gevent as its WSGI.

To use gevent, install it with pip install gevent

Afterwards, I used the https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 to set flask to use gevent.

Incase the link goes down, here's the important parts of the script:

from flask import Flask, Response
from gevent.pywsgi import WSGIServer
from gevent import monkey

# need to patch sockets to make requests async
# you may also need to call this before importing other packages that setup ssl
monkey.patch_all()

app = Flask(__name__) 


# define some REST endpoints... 

def main():

    # use gevent WSGI server instead of the Flask
    # instead of 5000, you can define whatever port you want.
    http = WSGIServer(('', 5000), app.wsgi_app) 

    # Serve your application
    http.serve_forever()


if __name__ == '__main__':
    main()
SomeGuy
  • 1,702
  • 1
  • 20
  • 19
  • threaded=True is not working for (using python 3.6.7 and postman), I am getting VersionConflict: (greenlet 0.4.13 (c:\anaconda3\lib\site-packages), Requirement.parse('greenlet>=0.4.14; platform_python_implementation == "CPython"')), may I know how to resolve this, Thanks – hanzgs Jun 06 '19 at 02:05
  • 1
    cut times in half. thank u good sir. – Corie LeClair Jul 19 '23 at 22:05
1

I got this error when running on hosts other than localhost as well, so for some, different underlying problems may exhibit the same symptoms.

I switched most of the things I've been using to Tornado, and anecdotally it's helped an amount. I've had a few slow page loads, but things seem generally more responsive. Also, very anecdotal, but I seem to notice that Flask alone will slow down over time, but Flask + Tornado less so. I imagine using Apache and mod_wsgi would make things even better, but Tornado's really simple to set up (see http://flask.pocoo.org/docs/deploying/others/).

(Also, a related question: Flask app occasionally hanging)

Community
  • 1
  • 1
gatoatigrado
  • 16,580
  • 18
  • 81
  • 143
1

I had a different solution here. I just deleted all .pyc from the server's directory and started it again. By the way, localhost was already commented out in my hosts file (Windows 8).

The server was freezing the whole time and now it works fine again.

erickrf
  • 2,069
  • 5
  • 21
  • 44
1

I run Python 3.8.10 which works fine, but as soon as I switch to Python 3.10.6 responses will be awful slow.

I could get around this problem with changing the precedence to IPv4 in /etc/gai.conf