https://blog.miguelgrinberg.com/post/python-3-14-is-here-how-fast-is-it miguelgrinberg.com * Home * My Courses and Books * Consulting * About Me * + Light Mode + Dark Mode + ------------------------------------------------------------- + System Default * GitHub LinkedIn Bluesky Mastodon Twitter YouTube Patreon RSS Feed Python 3.14 Is Here. How Fast Is It? Posted by [Miguel Grinberg] on 2025-10-08T13:09:36Z under [Python] In November of 2024 I wrote a blog post titled "Is Python Really That Slow?", in which I tested several versions of Python and noted the steady progress the language has been making in terms of performance. Today is the 8th of October 2025, just a day after the official release of Python 3.14. Let's rerun the benchmarks to find out how fast the new version of Python is! Note: If you do not care about tables and charts with results and just want to read my conclusions, click here to go to the end of the article. A Quick Word On How Misleading Benchmarks Can Be Yes, even though I'm going to share the results of my benchmark, I feel I have to warn you again, like I did in the previous article, that generic benchmarks like this one are not really very useful. Running these benchmarks is fun, and that is why I do it, but it is really impossible to build an accurate performance profile of something as complex as the Python interpreter just from running a couple of silly little scripts. I have designed my tests so that they run only pure Python code, avoiding the use of any dependencies, and in particular any functions that are written in C code. Native code (aside from the Python interpreter itself, that is) is less likely to become faster from one release of Python to the next, so I see no point in including that in the benchmark. But real-world applications do often use a mix of pure Python and native code, be it C, C++ or Rust, so while my test scripts are great to evaluate the performance of pure Python code, I do not consider them to be representative of the applications we normally use. In short, have a look at my benchmark, but consider it just one data point and not the last word on Python performance! The Testing Matrix Here is the test matrix that I've worked with, with five dimensions: * 6 Python versions, plus recent versions of Pypy, Node.js and Rust: + CPython 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 + Pypy 3.11 + Node 24 + Rust 1.90 * 3 Python interpreters + Standard + Just-In-Time (JIT): only for CPython 3.13+ + Free-threading (FT): only for CPython 3.13+ * 2 test scripts + fibo.py: calculates Fibonacci numbers, relying heavily on recursion + bubble.py: sorts a list of randomly generated numbers with the bubble sort algorithm, with a lot of iteration, but no recursion * 2 threading modes + Single-threaded + 4 threads running independent calculations * 2 computers + Framework laptop running Ubuntu Linux 24.04 (Intel Core i5 CPU) + Mac laptop running macOS Sequoia (M2 CPU) You may think that including Node.js and Rust in my benchmark is an odd choice. Maybe it is, but just the same, I ported the two Python test applications to JavaScript and Rust, so that I can have some reference numbers from outside of the Python ecosystem, just to put things into perspective. The Test Scripts Below you can see the main logic in fibo.py: def fibo(n): if n <= 1: return n else: return fibo(n-1) + fibo(n-2) After running some experiments, I've determined that calculating the 40th Fibonacci number with this function took a few seconds on my two laptops, so this is what I used for all the test results I'm sharing below. Here is the sort function from bubble.py: def bubble(arr): n = len(arr) for i in range(n): for j in range(0, n-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] return arr For this script I also eyeballed what array size to use so that the script took a few seconds to run. I settled on using a list with 10,000 numbers that are randomly generated. Please do not assume that these are great examples, because they are not. There are more efficient ways to code these functions if the goal was to make them run as fast as possible. But the goal here is not to have fast functions, but to compare how different Python interpreters run the code. I have chosen these functions mainly because one is recursive and the other is not, so that I have two different coding styles in the test set. The framework that I built for running this benchmark executes each test function three times and reports the average time of the three runs. The complete test scripts along with the benchmark scripts are available on the GitHub repository. Benchmark #1: Fibonacci single-threaded Okay, let's have a look at the first test. For this test I measured the time it took to run fibo(40) in seconds. As I mentioned above, for each data point I ran the code three times and averaged the results. Here are the numbers in table form: fibo 1 thread Linux macOS vs. 3.14 3.9 15.21 13.81 0.45x 3.10 16.24 14.97 0.42x 3.11 9.11 9.23 0.71x 3.12 8.01 8.54 0.78x 3.13 8.26 8.24 0.79x 3.14 6.59 6.39 -- Pypy 3.11 1.39 1.24 4.93x Node 24 1.38 1.28 4.88x Rust 1.90 0.08 0.10 69.82x The rightmost column shows the speed ratio against 3.14, so a number smaller than 1 in this column means that the corresponding test was slower than 3.14, and a number above means that it was faster. To calculate these ratios I used the average between the Linux and macOS results. Sometimes it helps to see the data graphically as well, so here is a chart with the above numbers: fibo 1 thread What can be learn from these results? We can see that 3.14 has gotten a nice speed improvement over 3.13. It ran close to 27% faster, which is another way of saying that 3.13 ran at about 79% of the speed of 3.14. These results also show that version 3.11 is the point at which Python versions moved from being "very slow" to "not so slow". One more detail that isn't related to Python 3.14 is that Pypy continues to blow my mind. In this test it was a hair faster that Node.js, and almost 5 times faster than 3.14. Impressive, although still quite far away from Rust, which as expected runs circles around everybody else. Just-In-Time and Free-Threading Variants Starting with Python 3.13, the CPython interpreter comes in three flavors: standard, free-threading (FT) and just-in-time (JIT). The free-threading interpreter disables the global interpreter lock (GIL), a change that promises to unlock great speed gains in multi-threaded applications. The JIT interpreter includes an on-the-fly compiler to native code, which should, in theory, help portions of code that run multiple times get faster by having them compiled to native code only once. The results I shared above for 3.13 and 3.14 used the standard interpreter, but I also wanted I to see specifically how the other two interpreter variants dealt with my test. In the next table and chart you can see a comparison of the same test running on the three interpreters under 3.13 and 3.14: fibo 1 thread Linux macOS vs. 3.14 3.13 8.26 8.24 0.79x 3.13 JIT 8.26 8.28 0.78x 3.13 FT 12.40 12.40 0.52x 3.14 6.59 6.39 -- 3.14 JIT 6.59 6.37 1.00x 3.14 FT 7.05 7.27 0.91x fibo 1 thread - Interpreter variants And this is a bit disappointing. At least for this test, the JIT interpreter did not produce any significant performance gains, so much that I had to double and triple check that I used a correctly built interpreter with this feature enabled. I do not know much about the internals of the new JIT compiler, but I'm wondering if it cannot deal with this heavily recursive function. As far as free-threading, I already discovered last year that the interpreter was slow when running single-threaded code. In 3.14 this interpreter appears to still be slower than the standard interpreter, but the difference is much smaller, with free-threading running at just 91% of the speed of the standard interpreter. Benchmark #2: Bubble sort single-threaded The following results are for the bubble sort benchmark, sorting an array of 10,000 random numbers: bubble 1 thread Linux macOS vs. 3.14 3.9 3.77 3.29 0.60x 3.10 4.01 3.38 0.57x 3.11 2.48 2.15 0.91x 3.12 2.69 2.46 0.82x 3.13 2.82 2.61 0.78x 3.14 2.18 2.05 -- Pypy 3.11 0.10 0.14 18.14x Node 24 0.43 0.21 6.64x Rust 1.90 0.04 0.07 36.15x bubble 1 thread This test shows a larger discrepancy between my Linux and macOS laptops, but the ratios between versions on each machine are more or less the same. The difference just suggests that Python on the Mac is able to run this test slightly faster. The 3.14 interpreter is the faster of the CPythons as in the Fibonacci test, but the difference here is smaller than in the previous benchmark, with Python 3.11 clocking in at just 91% of the speed of 3.14. This test also runs slower in 3.12 and 3.13 than in 3.11, an interesting oddity that I also observed in last year's benchmark. Pypy this time was 18 times faster than 3.14, and even 3 times faster than Node. I really need to spend some time evaluating Pypy, because it looks amazing. Just-In-Time and Free-Threading Variants Let's see how the 3.13 and 3.14 specialized interpreters fared on the bubble sort test. Here is the table and chart with the results: bubble 1 thread Linux macOS vs. 3.14 3.13 2.82 2.61 0.78x 3.13 JIT 2.59 2.44 0.84x 3.13 FT 4.13 3.75 0.54x 3.14 2.18 2.05 -- 3.14 JIT 2.03 2.32 0.97x 3.14 FT 2.66 2.28 0.86x bubble 1 thread - Interpreter variants The JIT interpreter appears to be a little bit faster here, but only on the Linux version of Python. On the Mac it was a bit faster for 3.13, but slower for 3.14. The speed differences are also very small, so overall I'm feeling the JIT interpreter needs some more time to mature. It seems the code that I'm using is somehow not able to benefit much from JIT compilation. The free-threading interpreter also ran slower, but again the difference was much smaller in 3.14 than in 3.13, so this is consistent between the two benchmarks. At this point it does not seem like it would make sense to switch to the free-threading interpreter for regular workloads, but it could be an interesting option when the GIL is really getting in the way, which is only for multi-threaded with big CPU needs. Benchmark #3: Fibonacci multi-threaded This year I decided to introduce multi-threaded versions of the two test programs, mainly as an excuse to give the free-threading interpreter the chance to shine. What I did for the multi-threaded Fibonacci test is to start four threads running the same calculation of the 40th Fibonacci. The four threads ran independently of each other, and the two laptops that I'm using have more than four cores, so they should be able to parallelize this test nicely. The time measurement that I used is from the time I launched the first thread to the time all four threads ended. Here are the results of fibo.py running on 4 threads running on the standard interpreters: fibo 4 threads Linux macOS vs. 3.14 3.9 67.87 57.51 0.46x 3.10 72.42 61.57 0.43x 3.11 45.83 36.98 0.70x 3.12 36.22 34.13 0.82x 3.13 37.20 33.53 0.81x 3.14 32.60 24.96 -- Pypy 3.11 7.49 6.84 4.02x fibo 4 threads Note that I did not run Node and Rust versions of the tests here, since this is a very specific test that only applies to Python's GIL. Of course these results do not tell us much. We can see again that my Mac seems a bit faster than my Linux machine, but aside from that things have more or less scaled linearly. For example, the single-threaded Fibonacci test ran in 7 seconds, and here it took 25 on the Mac and 32 on Linux, which is, give or take a 4x scale. This is expected because the GIL does not permit the Python code to parallelize. Let's see the detailed results on the 3.13 and 3.14 interpreters: fibo 4 threads Linux macOS vs. 3.14 3.13 37.20 33.53 0.81x 3.13 JIT 37.48 33.36 0.81x 3.13 FT 21.14 15.47 1.57x 3.14 32.60 24.96 -- 3.14 JIT 32.58 24.90 1.00x 3.14 FT 10.80 7.81 3.09x fibo 4 threads - Interpreter variants And this is quite nice! Since we were not expecting anything significant for the JIT interpreter on this test, we can ignore those results. But the free-threading interpreter is showing us how removing the GIL can help with running multiple threads that are CPU hungry. In Python 3.13 the free-threading interpreter ran about 2.2x faster than the standard interpreter. In 3.14 the performance improvement is about 3.1x. This is an exciting result! Benchmark #4: Bubble sort multi-threaded To complete this benchmarking exercise, below you can see the results of the bubble sort test running on 4 threads. For this test I had each thread sort 10,000 random numbers. The four threads received copies of the same randomly generated array. First let's look at the standard interpreters: bubble 4 threads Linux macOS vs. 3.14 3.9 16.14 12.58 0.66x 3.10 16.12 12.95 0.65x 3.11 11.43 7.89 0.97x 3.12 11.39 9.01 0.92x 3.13 11.54 9.78 0.88x 3.14 10.55 8.27 -- Pypy 3.11 0.54 0.59 16.65x bubble 4 threads These results show no big surprises either. The single-threaded version of this test executed in about 2 seconds on 3.14, and here we have 10 seconds on Linux and 8 seconds on Mac. It's interesting that on the Linux machine this test took a bit longer than 4x the single-threaded time. Here are the results with the new interpreters in 3.13 and 3.14: bubble 4 threads Linux macOS vs. 3.14 3.13 11.54 9.78 0.88x 3.13 JIT 10.90 9.19 0.94x 3.13 FT 9.83 5.05 1.17x 3.14 10.55 8.27 -- 3.14 JIT 10.03 9.26 0.98x 3.14 FT 6.23 3.02 2.03x bubble 4 threads - Interpreter variants And here once again we see a good use case for the free-threading interpreter. For this test the Mac's free-threading did better than Linux, but on overage 3.14 FT ran about 2x faster than standard 3.14. If you have a multi-threaded application that is CPU heavy, a switch to the free-threading interpreter might be a good idea. The odd results of the JIT interpreter being slower on the 3.14 Mac interpreter that we've seen in the single-threaded bubble sort test have repeated here, so I guess they were not a fluke, but in any case the differences are not big enough to matter, in my opinion. We'll just have to wait for the JIT interpreter to continue evolving in future releases. Conclusions I hope you found my benchmark results interesting. As way of a summary, these are the conclusions that I'm making from these results: * CPython 3.14 appears to be the fastest of all the CPythons. * If you can't upgrade to 3.14 just yet, consider using a release since 3.11, as these are significantly faster than 3.10 and older. * The 3.14 JIT interpreter does not appear to provide any significant gains in speed, at least not with my test scripts. * The 3.14 free-threading interpreter is faster than the standard interpreter for CPU heavy multi-threaded applications, so It is worth a try if your application fits this use case. I wouldn't recommend using this interpreter for other workloads, as it is still slower for code that is not directly slowed down by the GIL. * Pypy is insanely fast! Have you benchmarked Python 3.14? Let me know in the comments if you have results that are different than mine. Buy me a coffee? Thank you for visiting my blog! If you enjoyed this article, please consider supporting my work and keeping me caffeinated with a small one-time donation through Buy me a coffee. Thanks! Buy Me A Coffee Share this post Hacker News Reddit Twitter LinkedIn Facebook E-Mail 31 comments * [a52c9f84bc] #1 Butterfly said 2025-10-09T02:31:53Z Regardless you have your opinion like wise everyone has there's. Ty for the information not everyone shared there thoughts. * [1e79263b70] #2 P Rajagopalan said 2025-10-09T02:43:05Z Your article is superb and that too so soon as the latest version of Python. It is certain that the readers will get motivated and benefited with the comparisons you offered. Hats off to you! * [b866443a09] #3 Liam said 2025-10-09T05:04:09Z Thanks for creating this tests, very interesting. * [6b7d5b2580] #4 PACI said 2025-10-09T08:00:08Z Fine, JIT is beneficial, but Python's JIT hasn't succeeded yet * [fb341c84c5] #5 Darryl Miles said 2025-10-09T12:08:02Z Thanks for the summary. Please consider GraalPy in your rankings. This uses the JVM runtime to execute Pythom code. You get the most advanced byte code VM and JiT in the world with multi threading and interoperability with both ecosystems at the same time. What is there not to like. * [ac7c7507ea] #6 jammymalina said 2025-10-09T14:21:09Z Nice post! Is there any plan to compare asyncio performance between python versions? * [66176a4f03] #7 Trev said 2025-10-09T14:56:34Z Since some tests include Rust and node, and pypy, it would be interesting to see Mojo included. Mostly interesting to me as a comparison to those three moreso than the latest or earlier Python versions, but still could be an interesting data point. * [729e26a2a2] #8 Miguel Grinberg said 2025-10-09T15:55:09Z @Darryl & @Trev: I'm unlikely to add more languages to the benchmark. Neither GraalPy nor Mojo are widely adopted, as far as I know, and I have no familiarity with neither of them. The main reason I included pypy is because it is pretty much a drop-in replacement and requires no complicated setups. And I added Node and Rust because these languages I'm familiar with and it cost me near zero effort to include them. * [729e26a2a2] #9 Miguel Grinberg said 2025-10-09T15:58:24Z @jammymalina: as far as I know there hasn't been any recent optimizations that are specific to asyncio, so this benchmark should apply to those applications as well. You may also want to look for web server benchmarks, since these would better measure performance for I/O bound code. * [66aa330ace] #10 Stephane Raimbault said 2025-10-09T19:59:55Z Each time I run a high CPU or I/O bound task on my old Core i7 (2013) to compare it to my MacBook Pro M1 Max, I'm impressed by the efficiency of Linux. Same thing here your i5 (don't know the ref) against M2. * [a55fb932b8] #11 Val said 2025-10-09T20:36:35Z It would be great if you can test the same code on the same hardware compiled with Nuitka into a native code. * [8c46364c1c] #12 George Stephanis said 2025-10-09T20:50:32Z Wait ... 3.14? More like Pi-thon! * [729e26a2a2] #13 Miguel Grinberg said 2025-10-09T22:03:37Z @Val: there are a ton of Python or Python-related languages out there. Outside of the CPythons I selected pypy as a good representative of all of them. My goal was to evaluate Python 3.14, not every Python-related language out there. * [729e26a2a2] #14 Miguel Grinberg said 2025-10-09T22:08:18Z @Stephane: My CPU is 13th Gen Intel(R) Core(TM) i5-1340P. I'm also super happy with its performance vs. the M2. * [276221c4e1] #15 Fezan Muhammad Ali said 2025-10-10T03:20:02Z From your benchmark, the Rust done super job executing all scripts faster than any other. Why the rust didn't take the hype as of Python? * [4c01abff9d] #16 Anonimus said 2025-10-10T06:22:55Z Can you run performance tests with Golang? Recently, many people have been clashing with the Rust and Go languages. I switched to the go language myself after 4 years of development after Python. * [729e26a2a2] #17 Miguel Grinberg said 2025-10-10T07:01:25Z @Fezan: Rust is a much complex language to learn than Python, and not as flexible. * [729e26a2a2] #18 Miguel Grinberg said 2025-10-10T07:03:29Z @Anonimus: I would if I was interested in performance of Go. I'm interested in the performance of Python, so really no point in running Go, which is going to be the same order of speed as Rust, give or take. * [9ab9a86020] #19 siawash said 2025-10-10T08:37:06Z thanks for sharing. did you consider using subroutines in python 3.14 for cpu bound tasks? * [729e26a2a2] #20 Miguel Grinberg said 2025-10-10T09:00:36Z @siawash: I think you mean subinterpreters, not subroutines. I'm not really sure this applies here. As I explain in the article, the goal is to measure the performance improvements in the Python interpreter. The tests that I used are not optimized for speed, quite the contrary, they are CPU heavy on purpose, because that allows me to compare how different versions of Python deal with the same code. * [8423223f8e] #21 rox said 2025-10-10T10:11:04Z Interesting benchmarks! Since the free-threading interpreter is designed to improve multi-threaded performance, it would be great to see comparisons using actual threaded workloads to highlight its advantages. * [4c3138f2f8] #22 jankes said 2025-10-10T10:25:05Z thanks for a great article. I have one question: when I look at the benchmark #3 fibonacci multi-threaded py3.14 FT vs benchmark #1 fibonacci single-threaded py3.14, the single-threaded case is more than 3 seconds faster. However, your cpu has more than 4 cores, so the threads should run completely in parallel and I would expect the multi-threaded case be very very close to the single-threaded one. Where do the 3 additional seconds come from? * [4c3138f2f8] #23 jankes said 2025-10-10T10:35:11Z regarding the slow performance of python JIT interpreter, here is a nice article from one of the JIT interpreter developers https:/ /fidget-spinner.github.io/posts/jit-reflections.html. In short, they just laid off fundations of JIT and the performance improvements should come later * [729e26a2a2] #24 Miguel Grinberg said 2025-10-10T11:17:40Z @rox: The free-threading interpreter is designed to allow multiple threads to run Python code at the same time, due to the removal of the global interpreter lock. The gain in performance is only there for CPU bound code, which is exactly what my tests in this article are. For I/O bound multithreaded code you are not going to see any improvement. * [729e26a2a2] #25 Miguel Grinberg said 2025-10-10T11:25:18Z @jankes: removing the GIL has a cost. If you look at the FT performance for the single-threaded Fibonacci test it was slower than the standard interpreter. The single-threaded test ran in 7.2 seconds (average between the two laptops). The test with 4 threads took 9.3 seconds (10 secs on intel, 7.8 secs on Mac). Yes, there is a bit of overhead, but it is still quite impressive, considering that the standard interpreter runs the 4 threads in 33 secs (Intel) or 25 secs (Mac). * <<<< * << * >> * >>>> Leave a Comment Name [ ] Email [ ] Comment [ ] Captcha [Submit] SQLAlchemy 2 In Practice [sqlalchemy] If you want to learn the ins and outs of relational database programming with Python and SQLAlchemy, consider my SQLAlchemy 2 In Practice book, available on Amazon. Click here to get this Book! About Miguel [miguel] Welcome to my blog! I'm a software engineer and technical writer, currently living in Drogheda, Ireland. You can also find me on Github, LinkedIn, Bluesky, Mastodon, Twitter, YouTube, and Patreon. Thank you for visiting! Categories AI RSS Feed [AI] 3 Arduino RSS Feed [Arduino] 7 Authentication RSS Feed [Authentication] 10 Blog RSS Feed [Blog] 1 C++ RSS Feed [C++] 5 CSS RSS Feed [CSS] 1 Cloud RSS Feed [Cloud] 11 Database RSS Feed [Database] 23 Docker RSS Feed [Docker] 5 Filmmaking RSS Feed [Filmmaking] 6 Flask RSS Feed [Flask] 129 Games RSS Feed [Games] 1 IoT RSS Feed [IoT] 8 JavaScript RSS Feed [JavaScript] 36 MicroPython RSS Feed [MicroPython] 10 Microdot RSS Feed [Microdot] 1 Microservices RSS Feed [Microservices] 2 Movie Reviews RSS Feed [Movie Reviews] 5 Personal RSS Feed [Personal] 3 Photography RSS Feed [Photography] 7 Product Reviews RSS Feed [Product Reviews] 2 Programming RSS Feed [Programming] 193 Project Management RSS Feed [Project Management] 1 Python RSS Feed [Python] 175 REST RSS Feed [REST] 7 Raspberry Pi RSS Feed [Raspberry Pi] 8 React RSS Feed [React] 19 Reviews RSS Feed [Reviews] 1 Robotics RSS Feed [Robotics] 6 Security RSS Feed [Security] 12 Video RSS Feed [Video] 22 WebSocket RSS Feed [WebSocket] 2 Webcast RSS Feed [Webcast] 3 Windows RSS Feed [Windows] 1 (c) 2012- by Miguel Grinberg. All rights reserved. Questions?