The generated buffer is 140MB, not 14MB. At 14 bytes per row, that makes sense.
I have done another test. If I execute `FETCH ALL FROM cursor` I get a 140MB disk buffer file, on the PostgreSQL server, reported in its log. If I execute `FETCH 5000000 FROM cursor` (exactly half the rows), I see a 70MB disk buffer file. This is regardless of how many rows I actually stream from thE connection before closing the cursor.