The GIL requires that you use multiple processes to make use of multiple CPUs or cores. And that means you cannot keep much data in memory as it would be duplicated in each process. Some applications benefit a lot from keeping much of the data in memory most of the time, and if you have complex data structures (like graphs) memcached (or similar solutions) is no replacement as you have to rebuild those data structures on each access. Any solution that invalidates process relative adresses incurs a huge overhead in order to access that data.
I know the debate around threads and how problematic they are and how much better a multi process model scales. That's all very well, but threads are the only way to use multiple cores and access in memory data structures fast.
So using Python, for me, means having to write much of my application in C++ (or Java or C#) and access that backend process from the Python web frontend. This approach comes with a lot of complexity and it's a lot more work than using Java or C# in the first place.
On the other hand, keeping a lot of data in memory isn't necessary for most applications as the data structures and the parallelism lives in the DBMS, which is written in C/C++ anyway.
It's also questionable whether Java is a good solution for my scenario. Java and C# need about twice as much memory as C++ for the exact same data structures, and the garbage collector gets slower the more memory a process allocates.
I know there are more options but this post is getting lengthy :-)