I haven't used PG in production for some time, but it did have limits. One is how MVCC is handled. Oracle historically kept pre-change copies of the table data in rollback segments and freed them on commit (actually after the final active SELECT finished after commit). PG took the approach of leaving pre-change copies in place, then marking them free after commit (again, after the final SELECT).
The Oracle approach kept only one version of the table data in the table space, but was slower for changes since any change required copying the modified blocks to the rollback segments. SELECTs against data being changed were also horribly slow since the query had to traverse the rollback segments. Finally, rollbacks were slow since the data had to be copied back from the rollback segment.
Since PG kept all versions of table data in then table space, it did not suffer any of the Oracle disadvantages, but it had the effect of every change leaving holes in the table space and causing the table space to grow without bound. To "fix" the holes, an occasional VACUUM command would be run which coalesced the data.
Each approach has advantages and disadvantages.