Understanding INSERT ... RETURNING
The select count(*) from foo inside the returning clause is evaluated before the insert, and then treated as a constant in the returning clause, as explain clearly shows:
&gt; explain insert into foo (a) values (1) returning (select count(*) from foo);
┌───────────────────────────────────────────────────────────────────────────┐
│                                QUERY PLAN                                 │
├───────────────────────────────────────────────────────────────────────────┤
│ Insert on foo  (cost=41.88..41.89 rows=1 width=4)                         │
│   InitPlan 1 (returns $0)                                                 │
│     -&gt;  Aggregate  (cost=41.88..41.88 rows=1 width=8)                     │
│           -&gt;  Seq Scan on foo foo_1  (cost=0.00..35.50 rows=2550 width=0) │
│   -&gt;  Result  (cost=0.00..0.01 rows=1 width=4)                            │
└───────────────────────────────────────────────────────────────────────────┘
(5 rows)

This is confirmed by the documentation where it says that the returning clause may contain column names or value expressions (using those columns) to be returned (saving a query after the insert):
&gt; select count(*) from foo;
┌───────┐
│ count │
├───────┤
│     1 │
└───────┘
(1 row)

&gt; insert into foo (a) values (1) returning 'a', a, (select count(*) from foo);
┌──────────┬───┬───────┐
│ ?column? │ a │ count │
├──────────┼───┼───────┤
│ a        │ 1 │     1 │
└──────────┴───┴───────┘
(1 row)

INSERT 0 1