Most of this article tracks quite well with my experiences! It's nice to see stuff like this written down.
> If the application’s code is in our control we can cache data in a memory store like Redis or Memcached to avoid querying the database.
On this point - what I've seen over and over again is caches being used as a band-aid for overall throughput limitations. Then the cache goes down (sometimes partially in the case of a clustered cache), the database gets slammed, and there's an outage soon after.
So caches help as an improvement on latency to some degree, but using them to avoid scaling your capacity can get you in a pickle depending on your usage patterns / hit distribution. You usually need some amount of capacity planning and consideration there.