That tone is asking for some passionate replies ;-)
This isn't about PostgreSQL at all. There's things where relational databases are a good fit, and things that are a bad fit. As such, this isn't about what PostgreSQL does poorly, but about the cases where a key-value store with some pretty good data structures comes in handy. Would you really store temporary data in your relational database? Would you use it as a caching mechanism? Perhaps as a queue? Not unless you're crazy. So I guess this isn't about what PostgreSQL performs poorly, but about where Redis is a better solution.
I'm not sure how to efficiently implement redis-style sorted sets using SQL, but the fact that I have to think about it at all means it's easier to use redis.
A lot of the other things could probably be done with the right combination of stored procedures and clever SQL but again, redis makes it so much easier as to make things qualitatively different. It's just a bunch of C files with no real external dependencies (I don't even have to run ./configure before building it!).
Operationally, for a generic non-db-expert kind of person like me, redis is much simpler to manage than PostgreSQL. With redis I don't need to worry about vacuuming, write ahead logs, archiving, query tuning & statistics, lock management, etc (to name a few things from the config file).
You have items that you want to retrieve (LRANGE) in the same order, or in reverse order you push inside (LPUSH / RPUSH). Usually you need the latest items (think to timelines), and all this should be FAST and efficient.
In Redis this is trival to model. SQL is so far from modeling this in the right way that you need an "ORDER BY" statement for all your LRANGE-alike query even if there is nothing to order, you want to retrieve things in their natural insertion order.
Sorted sets can model a zillion of use cases in the same way. They are ordered per score on insertion. You can ask for ranges, for the RANK of an element, and things like this, in a matter of microseconds per queries. Completely impossible to model with SQL in a natural and fast way.
Just to cite another one (but there are tens of cases like this), bloom filters anyone? With Redis 2.2 you can manipulate a unique bitfield at the lower level, and even accessing to the sub bytes if you wish, with very efficient operations.
I use sorted sets quite heavily for timelines. And it's awesome.
One usecase I can't figure out, is storing/querying IP address ranges. Is there a natural way with Redis to check if a number is within a given range? (without storing every value and without multiple calls)
What about the other way around though? Storing the range, say, 159.18.0.0 - 159.18.255.255, and then querying to check if an address is in that range.
The only way I can think to do this is to store the range as two integers, as you suggest, and query twice. The first to find the nearest lower bound for an IP and then a second time for the upper bound.