A single core running Python will easily handle more load than most successful SaaS companies ever reach, especially in web dev where most of the real work happens in a database of some flavor.
There absolutely are performance pitfalls, and Python is less power efficient than other alternatives running some kinds of workloads at scale, but in a ton of environments the perf difference doesn't matter.
But while I too had in my head "for web dev most of the real work happens in a database of some flavor", I recently realized that was not true for my app, probably hadn't been true for some time, and probably isn't true of most Rails apps (possibly not the same for non-Rails web apps?). If you've properly eliminated n+1 queries and other inefficient querying, I find that my apps are spending only 20 or 30ms waiting on DB results, and a couple hundred on CPU tasks to render HTML.
I know people are going to reply with "That's because Rails is slow," but I'm not sure that's true for what we're talking about compared to similar Python platforms, I'd be interested in seeing numbers for other real apps. In the Rails community too, people still repeat the assumption "most of your response time is spent waiting on the DB" -- but I dont' think it's actually true anymore (it may have been once).
The "most of your response time is spent waiting on the DB" assumption might not hold for your app. Even if you actively push work to the DB to reduce network bandwidth or something, your workload might fundamentally be comprised of small, easy-to-optimize units of work that the DB handles without any issues.
That said, hundreds of milliseconds sounds slow by an order of magnitude or more for html rendering, even if all the work is done in a batteries-included framework for a dynamic language, and it doesn't jive with my Python experience at all. Do you mind me asking what kinds of tasks are taking that much time?
In this app, mostly lots and lots of thumbnails. It may be some unoptimized code.
But rather than get into the details of my app, and parts that need optimization (whether in my local code or in Rails or in ruby), I'm more curious about the overall concept.
Are you sure that most of your web app's time is spent waiting on the DB? My suspicion has become that this is conventional wisdom that is not actually true of most apps anymore. But I could be wrong. Or I could be right only for Rails and not python because Rails is slower than typical python, or something. I am curious to find out.
> Are you sure that most of your web app's time is spent waiting on the DB?
Positive. It's my first tech job though, and we use C# at work to the extent that matters.
The kind of Python I write off the clock probably isn't a good example of waiting on the DB though. It's usually a thin wrapper around C or assembly (or calling into such a library via numpy, networkx, etc) to do something horrendously expensive that I absolutely would not want to run in vanilla cpython. That said, when I do ordinaryish web-related stuff in Python I'm looking at well under 20ms total elapsed time per call, which is why your ~200ms html rendering time stuck out to me.
time "spent" in the database depends on the speed of DB drivers too, which depends on the language. Our stuff is Java and average query is ~2ms round trip.
Python, Ruby and friends are bad for page speed metrics. REST response time of ~200ms vs ~10ms for our java backends
Yes, it does, as long as performance-bottlenecked code is not in Python (and it usually isn't). In the real world, you may have to extract some hot regions to C++ or Rust or Java, but 99% of your code will scale infinitely.
My team migrated a service handling >1.6k req/s at peak time, from Scala (Finatra), to Python (Django). Same number of servers (3x c5.large), just higher CPU utilization (from ~15% to 70%).
Scala was great, but unfortunately it made it difficult to onboard new team members into the project, so development suffered. Also the rest of our stack is mostly Python, so we couldn't use a lot of the common tooling, and libraries we had built for other projects.
We migrated it within a month, and it's been running for almost a year without issues.
At some point the service even recorded 3k+ req/s at ~200ms 99p latency. Yeah, maybe not Google scale, but more than enough for 99% of the businesses out there.
This service handles about 2.5 billion requests per month from one AWS region. We're a small team, and that's only one of the services we support. Which is great because we don't need to spend all of our time optimizing it.
Notwithstanding this (that Python will scale), Python will force you to scale horizontally a lot earlier than something like Rust. In mid-2013, NewsBlur was using 48 servers to run its Python/Django stack. The workload was reasonably precisely declared (and I could grudgingly see why it used so many servers for its stack), so I was able to run the numbers and confidently concluded that something reasonably efficient (which for me would now mean Rust) could have handled the same workload on one equivalent server, though not with a great deal of headroom, and further vertical scaling might have started running into I/O limitations. But for a one-man thing, I know I would prefer to use a single server as long as convenient, and a 98% reduction in hosting bill is very significant (though that’s a moderately extreme case, and I imagine smaller parts of the code could have been rewritten in a language like Rust to get a meaningful fraction of that resource usage reduction).
There absolutely are performance pitfalls, and Python is less power efficient than other alternatives running some kinds of workloads at scale, but in a ton of environments the perf difference doesn't matter.