Limit number of threads in numpy
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
When NumPy appears to use many CPU threads, the threads usually come from the native math library underneath it rather than from NumPy itself. Operations such as matrix multiplication, singular value decomposition, and other linear algebra routines often run through OpenBLAS, MKL, or another backend that decides how many worker threads to create.
Core Sections
Know which layer controls the thread count
NumPy delegates many heavy numerical operations to lower-level libraries. That means there is no single universal numpy.set_num_threads() call that works for every installation. Instead, you typically control the backend through environment variables such as OPENBLAS_NUM_THREADS, MKL_NUM_THREADS, or OMP_NUM_THREADS.
This distinction matters because developers often try to optimize NumPy itself when the real behavior is controlled by the linked BLAS or OpenMP runtime.
Set environment variables before importing NumPy
The safest approach is to define the thread limit before Python loads NumPy and its native dependencies. Many backends read their configuration only once during startup.
You can also export the variables in the shell session:
This approach is reliable for local scripts, CI jobs, data pipelines, and container entry points.
Setting limits from Python
If you control the main entry point, you can set the environment variables before importing NumPy. The timing matters. If NumPy or a dependent library is already imported elsewhere, changing the variable may have no effect.
For larger applications, shell-level configuration is usually safer because it avoids import-order surprises.
Use threadpoolctl when you need scoped control
Sometimes you do not want a global thread limit for the entire process. In that case, threadpoolctl lets you temporarily cap the number of threads around a specific block of work.
This is useful when one stage of a service should avoid saturating the machine, while a different stage can use the backend default.
Verify which backend you are actually using
If a thread variable seems ineffective, inspect the active native libraries instead of guessing.
This tells you whether the process is using OpenBLAS, MKL, or something else. Once you know the backend, you can choose the correct knob and test again.
Why limiting threads can improve performance
More threads do not automatically mean faster code. Oversubscription is common in data-processing systems that already use multiprocessing, task queues, or parallel test runners. For example, if four Python processes each open eight BLAS threads on an eight-core machine, the operating system must schedule thirty-two active workers on eight cores.
In that setup, one BLAS thread per worker process is often faster and more predictable than letting every process fan out aggressively.
Common Pitfalls
- Setting
OPENBLAS_NUM_THREADSor similar variables after NumPy is already imported often has no effect. - Changing only one environment variable without confirming the active backend can lead to false conclusions about thread control.
- Assuming that higher thread counts always improve throughput ignores oversubscription and memory-bandwidth limits.
- Blaming NumPy alone for thread behavior can hide the fact that the real tuning point is MKL, OpenBLAS, or OpenMP.
- Benchmarking on an idle laptop and then deploying the same settings to a shared server often produces very different results.
Summary
- NumPy thread counts usually come from the native math backend underneath the library.
- Set backend thread limits before NumPy is imported for the most reliable behavior.
- Use
threadpoolctlwhen you need temporary or inspectable runtime control. - Check which backend is loaded instead of guessing which environment variable matters.
- Lower thread counts are often the right choice when NumPy runs inside multiprocessing or shared compute environments.
Related reading
- Line Chart with Custom Confidence Interval in Altair
- Linear algebra application in Machine Learning
- Linear regression analysis with string/categorical features variables?
- Linear Regression Normalization Vs Standardization
- Limit Tensorflow CPU and Memory usage
- Limit the number of pods per node
- Limiting floats to two decimal points
- Linear Regression and Gradient Descent in Scikit learn?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.