I've run two big sites on PostgreSQL now, the first is a content management system for schools across the US with ~3M users with 1K to 3K active at the same time. 300G db on machines with 128G RAM, 34 15kSAS drives, HW RAID controllers and 48 AMD opteron cores. We ran a very aggressive autovacuum schedule, 8 threads with 1ms sleep and max work limit in the 5000 or higher range. We ran several other services on top of pgsql as well, a search engine, stats db, and session servers on it there. Each setup somewhat differently, all 24/7 and quite reliable. The main ~300G cms database was replicated by Slony, since it was setup some time ago when slony was the only real reliable etc replication engine at the time we started. Honestly, it was great performance wise, and reliability wise. Working around Slony for ddl updates is a gigantic pain in the ass tho. Things have gotten better.
The second site, in my current job is also 24/7 and on big hardware but is used as a core db for a storage system consisting of literally thousands of TB sized HDs. The actual db is only a fraction of our storage.
Once you teach your developers to be db centric (start with the data model and work upwards) and the little tricks of postgresql they usually are pretty happy with it. But if you don't have a pg specialist on staff the developers often hate using pgsql because it's NOT what they're used to.
An example is when I was teaching a new guy to use it and he was bitching at how poor insert performance was. He had a 10k file to import and it was about 10% imoprted after 10 minutes. I had him truncate the table and wrap the inserts in begin;commit; and the whole thing imported in about 10 seconds. This was back on pg 7.1 and php3.0 days. Pg has gotten much faster but the ratio of 10k transactions / individual inserts versus batching all 10k together is still quite large.
The fact that you can wrap anything except create / drop database / table or setval/nextval in a transaction and roll it back makes it amazing for development work. You can wrap some huge db updates in a transaction and if there's an error anywhere the whole thing rolls back and you can try again without cleaning up a half-updated db.
It's not perfect, but once you get a handle on performance tuning, autovacuum tuning, and replication it's pretty amazing both performance and reliability wise.