Every rate-limit blog post says "use Redis." Most products don't have a Redis. We didn't either, so we asked whether Postgres alone could carry the load — and the answer was, comfortably, yes.
A token-bucket row per user, an update ... returning for atomic decrement, and a sliding window cap to absorb burst skew. The hot-path is one round-trip; the worst-case is one round-trip; we never had to introduce a new datastore for a feature that's cheaper than the data it protects.