It turned out that this was also happening for all static assets. Oops. And the site is covered in very small images. Double oops.
All told, to load a single page the server was making over 150 sql queries. And because it’s Python, those queries were all issued with blocking code. More than enough to keep the server busy for ages.