> Some light load testing (with (ab -n 1000 -c 1) shows that right now we can serve about 2-3 requests per second (on a ~$10/month VM).

> After turning on template caching, it seems like the site can now pretty easily handle 12 requests per second or so without using all of the CPU. I have not carefully benchmarked the before and after but it seems like it’s made a pretty big difference.

That seems crazy low, I think there has to be something else going on here.

Wow. With a web service in Go or any similar language that would measure in the thousands, at least.

If Django could run reasonable numbers of requests on early-200s0 servers... what has gone wrong since?

I imagine even a $10 VPS should be a much more powerful machine than a high-end server from 2005 or so.

Those numbers sound... Single-threaded. Like they're using the development runserver instead of uwsgi or gunicorn.

Development runserver has been multithreaded by default for over a decade. I think you need to go back to major version 1 to see it single-threaded by default. Maybe affected by the GIL though.

A $10/month VM might only have a single thread anyway. Some providers like lightsail are really slow too.

You can run multiple OS threads (gunicorn workers) on one VM thread so the workers don’t have to wait for each others request to finish though, right?

And if you pay $10/month for a single threaded machine, you’re overpaying by a lot.

True, but in this case with SQLite, there's unlikely to be much of a difference because there isn't the spare time available when waiting for a separate database server. I don't know what providers are good for a $10/month instance these days.

How are you spending any non-negligible time reading from SQLite at 12 requests per second though? That would mean you’re spending something like 50 ms per request on reading from SQLite.

Most of the time you're hitting SQLite, you're just reading from it, and so it doesn't hold anything up.

For a cheap VM, I'd still be expecting in the range of 500-1000 connections a second. Green threads are cheap, even with a single processor.

For a half-decent VM, I'd be expecting multi-thousand.

Single figures a second, is choked to a single connection at a time.

Also, they may be serving static files through Django. Otherwise, it's really, really low.

That’s a number I would been disappointed with 25 years ago, running Perl CGI on a 700MHz Pentium III.

Yeah... in the place I worked, for a while, they didn't have a package index for Python packages (similar to PyPI), so, I wanted to write one. At the time I had a love-hate relationship with Ada, so, after trying to do something with Python and thinking how much resources I would have to ask for and whether I'll need load balancing etc... I checked what Ada's (somewhat unfortunately named AWS...) would need to be used as that kind of index. Suffices to say that I wouldn't need any of the "reverse proxy" servers, no caching, no load-balancers... It would be fast enough to service a company with thousands of employees on a very modest h/w setup.

Using Django is like trying to walk on a highway, with a crutch. Even though it has some convenience features, it's just so impossibly slow you would have to invest a lot of engineering time and resources to mitigate that slowness.

It's because -c 1 only makes 1 request at a time, which is not representative of a real website load. This was also brought up on lobsters a few days ago https://lobste.rs/c/lctz1y

1000ms / 12 = 83ms per request which sounds normal