By sayantankhan


2015-09-28 03:52:36 8 Comments

In my app the state of a common object is changed by making requests, and the response depends on the state.

class SomeObj():
    def __init__(self, param):
        self.param = param
    def query(self):
        self.param += 1
        return self.param

global_obj = SomeObj(0)

@app.route('/')
def home():
    flash(global_obj.query())
    render_template('index.html')

If I run this on my development server, I expect to get 1, 2, 3 and so on. If requests are made from 100 different clients simultaneously, can something go wrong? The expected result would be that the 100 different clients each see a unique number from 1 to 100. Or will something like this happen:

  1. Client 1 queries. self.param is incremented by 1.
  2. Before the return statement can be executed, the thread switches over to client 2. self.param is incremented again.
  3. The thread switches back to client 1, and the client is returned the number 2, say.
  4. Now the thread moves to client 2 and returns him/her the number 3.

Since there were only two clients, the expected results were 1 and 2, not 2 and 3. A number was skipped.

Will this actually happen as I scale up my application? What alternatives to a global variable should I look at?

2 comments

@lhk 2018-11-05 10:21:02

This is not really an answer to thread safety of globals.

But I think it is important to mention sessions here. You are looking for a way to store client-specific data. Every connection should have access to its own pool of data, in a threadsafe way.

This is possible with server-side sessions, and they are available in a very neat flask plugin: https://pythonhosted.org/Flask-Session/

If you set up sessions, a session variable is available in all your routes and it behaves like a dictionary. The data stored in this dictionary is individual for each connecting client.

Here is a short demo:

from flask import Flask, session
from flask_session import Session

app = Flask(__name__)
# Check Configuration section for more details
SESSION_TYPE = 'filesystem'
app.config.from_object(__name__)
Session(app)

@app.route('/')
def reset():
    session["counter"]=0

    return "counter was reset"

@app.route('/inc')
def routeA():
    if not "counter" in session:
        session["counter"]=0

    session["counter"]+=1

    return "counter is {}".format(session["counter"])

@app.route('/dec')
def routeB():
    if not "counter" in session:
        session["counter"] = 0

    session["counter"] -= 1

    return "counter is {}".format(session["counter"])


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

After pip install Flask-Session, you should be able to run this. Try accessing it from different browsers, you'll see that the counter is not shared between them.

@jtlz2 2019-04-01 14:35:51

This is very cool! Why don't you set it up as its own Q&A?

@lhk 2019-06-22 17:39:38

@jtlz2, thanks, I'm glad I could help you :D But setting this up as its own QA would feel like fishing for reputation. The docs for flask-session are awesome. I mean, if I create a separate question for this it would be called something like "is there something like server-side sessions in flask". And then, any google search that finds the new SO question, probably also shows you the official docs. So my contribution wouldn't really be useful and only compete for attention :P

@Sibish 2019-08-15 22:06:32

this is not working.

@lhk 2019-08-17 18:16:34

@Sibish, if you give me some details, I might be able to help you. It worked fine for me.

@davidism 2015-09-28 14:26:28

You can't use global variables to hold this sort of data. Not only is it not thread safe, it's not process safe, and WSGI servers in production spawn multiple processes. Not only would your counts be wrong if you were using threads to handle requests, they would also vary depending on which process handled the request.

Use a data source outside of Flask to hold global data. A database, memcached, or redis are all appropriate separate storage areas, depending on your needs. If you need to load and access Python data, consider multiprocessing.Manager. You could also use the session for simple data that is per-user.


The development server may run in single thread and process. You won't see the behavior you describe since each request will be handled synchronously. Enable threads or processes and you will see it. app.run(threaded=True) or app.run(processes=10). (In 1.0 the server is threaded by default.)


Some WSGI servers may support gevent or another async worker. Global variables are still not thread safe because there's still no protection against most race conditions. You can still have a scenario where one worker gets a value, yields, another modifies it, yields, then the first worker also modifies it.


If you need to store some global data during a request, you may use Flask's g object. Another common case is some top-level object that manages database connections. The distinction for this type of "global" is that it's unique to each request, not used between requests, and there's something managing the set up and teardown of the resource.

Related Questions

Sponsored Content

15 Answered Questions

[SOLVED] Get the data received in a Flask request

2 Answered Questions

[SOLVED] Handle Flask requests concurrently with threaded=True

  • 2016-08-10 14:47:22
  • Harrison
  • 40675 View
  • 47 Score
  • 2 Answer
  • Tags:   python flask

0 Answered Questions

can't share variables between flask and threads

6 Answered Questions

[SOLVED] How to share the global app object in flask?

  • 2012-11-08 08:02:10
  • murtaza52
  • 38907 View
  • 26 Score
  • 6 Answer
  • Tags:   python flask

8 Answered Questions

[SOLVED] Why are local variables thread safe in Java

2 Answered Questions

[SOLVED] Flask POSTs with Trailing Slash

0 Answered Questions

2 Answered Questions

[SOLVED] Is local static variable initialization thread-safe in C++11?

0 Answered Questions

How to have server call another server in Python with threading?

Sponsored Content