AWS Builder Center

Adding a Valkey cache to our class API taught me about invalidation, not speed

I put ElastiCache Serverless for Valkey in front of our course-review API on RDS. The speedup was nice, but the stale-data bug a teammate reported was the real lesson.

Our software engineering course project is an API where students review classes, backed by RDS PostgreSQL. The most common request is "show the average rating and latest reviews for course X," which runs the same aggregation over and over. I wanted an excuse to try a cache, and ElastiCache Serverless for Valkey looked like the easiest way to start without having to pick node sizes.
I went with the cache-aside pattern. The API checks Valkey for course:<id>:summary. On a hit, it returns the cached JSON. On a miss, it queries Postgres, stores the result in Valkey with a 5-minute TTL and returns it. The database load for popular courses dropped a lot, since most requests turned into cache hits.
Two days later a teammate posted a review, didn't see it show up, and opened an issue titled "reviews are broken." They weren't broken. They were cached for five minutes, which was a decision I made without really thinking about what it would feel like for the person who just posted.
I changed the write path so creating a review also deletes that course's cache key. The next read misses, recomputes and caches the fresh summary. The TTL stays as a backup in case a delete ever fails.
Setup things that cost me time:
  • It lives in the VPC. The API has to run in the same VPC, with a security group rule allowing it to reach the cache on ports 6379 and 6380 (serverless caches use 6380 for reads from replicas).
  • TLS is required. ElastiCache Serverless  always encrypts in transit. My first connection attempts timed out because I was connecting without TLS, and the timeout gave me no hint about why.
  • Regular Redis clients work. Valkey is compatible with Redis OSS clients, so I used the normal Python Redis library.
For the traffic our class project gets, Postgres alone was fast enough, if I'm honest. But I finally understand why people joke that cache invalidation is one of the hard problems, and I learned it from a GitHub issue instead of a production incident.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article