
The common advice out there on how to scale your framework of choice -- whether Rails, Django or CakePHP -- is caching, caching and more caching. These frameworks come with caching functions that make it dead easy.
But let's not forget that a webserver like Apache can always deliver a static file faster (and more reliably) than any framework, no matter how much the framework caches. As soon as the language interpreter loads, some time has been spent.
I ran into a problem trying to serve dynamically generated images thru Django. With built-in caching, performance was pretty good, averaging a few hundred requests a second, enough for most apps but not an ad server. Instead of trying to wring out more performance from Django, I configured Apache to act as a cache handler, avoiding Django entirely on cache hits.
The technique is to rewrite URIs to reference a static file. If the file doesn't exist, then run your script and have it save its output to a predetermined location. A similar technique is using a 404 handler to generate static files for the next request to a URI.
Here is my Apache config code (inspired by hardcoder.com):
#cache handling
RewriteEngine On
RewriteCond %{QUERY_STRING} !=miss
RewriteRule composite/([0-9]+)/$ /media/comp_cache/$1.jpeg
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule media/comp_cache/([0-9]+).jpeg$ /composite/$1/?miss
These rules will transform the URI
/composite/84/ -> /media/comp_cache/84.jpeg
If /media/comp_cache/84.jpeg does not exist, it will then transform back
/media/comp_cache/84.jpeg -> /composite/84/?miss
so the script at /composite/84/ can run and produce the static file /media/comp_cache/84.jpeg.
By the way, here is a great online service that lets you test your rewrite rules without messing with Apache logs.