Thread local storage in Python
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Thread-local storage lets each thread keep its own private state without manually passing that state through every function call. In Python, the standard tool for this is threading.local(), which creates an object whose attributes are isolated per thread even though the object itself is shared.
Create a Thread-Local Object
The core API is small. You create one local object and store attributes on it as if it were a normal instance.
Even though both threads use the same thread_state object, each thread sees its own user value.
Why It Exists
Thread-local storage is useful when:
- you need request-specific or task-specific state in threaded code
- passing a context object through many layers would be noisy
- the state should never be shared across threads
Common examples include request IDs, database-session handles, authentication context, and logging metadata in threaded applications.
The main benefit is convenience. The data feels globally reachable inside the thread, but it is not shared with other threads.
Practical Example: Per-Thread Request Context
A logging or tracing context is a classic use case.
Each thread logs with its own request ID without needing to thread that value through every helper function.
How It Works Conceptually
threading.local() does not clone the object per thread. Instead, it stores a separate attribute dictionary for each thread behind the scenes. That is why setting thread_state.user in one thread does not affect another thread's view of the same attribute.
This behavior is convenient, but it also means you should treat thread-local values as context state, not as a replacement for explicit program structure. Hidden context can become hard to reason about if it spreads everywhere.
Thread-Local Storage Is Not for Async Code
One important limitation is that thread-local storage tracks threads, not asynchronous tasks. In asyncio code, many logical tasks may run on the same thread, so threading.local() is usually the wrong abstraction.
For async task-local state, use contextvars instead.
This distinction matters a lot in modern Python services where concurrency often comes from async code rather than traditional threads.
Thread Pools Need Extra Care
If your application uses a thread pool, remember that worker threads are reused. That means thread-local state can accidentally persist into a later task if you do not reset it explicitly.
Setting a value at task start and clearing it at task end is a good habit when the data is sensitive or task-specific.
Common Pitfalls
One common mistake is assuming thread-local state automatically resets between reused worker threads. In thread pools, it does not. Old values can leak into later work unless you overwrite or clear them.
Another is using thread-local storage for data that should really be passed explicitly. Hidden context can make testing and debugging harder if too much code silently depends on it.
Developers also sometimes try to use threading.local() in async code and get confusing behavior because there is only one thread even though many tasks are active.
Finally, remember that thread-local storage provides isolation, not synchronization. It does not solve shared-state coordination problems between threads because, by design, the values are not shared.
Summary
- '
threading.local()gives each thread its own isolated attribute storage.' - It is useful for per-thread context such as request IDs or session handles.
- The same
localobject can hold different values in different threads. - Thread-local storage is not the right tool for
asyncio; usecontextvarsthere. - Clear or overwrite thread-local state when using reusable thread pools.
Related reading
.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.