My information is old, but maybe mostly correct. Firebird had multi-generational concurrency control while Postgres
was still recovering from its Ingres roots. That means the implementation is really old and reflects the bit-bumming
that was common in the mid-eighties when memory and disk space would embarrass a modern parking meter.
Part of the reason why the Firebird record header is smaller is that it doesn't contain the transaction id of the
transaction that deleted a record. When a record is deleted, Firebird creates a "deleted stub", an empty record.
When the transaction that deleted the record is committed and every translation contemporary with that transaction
has ended, the next pass of garbage collection - think of it as continuous vacuuming - will remove the stub and
all the back versions. If the transaction that deleted the stub fails, the stub is removed and the previous version
becomes the primary version again.
In Firebird, record versions are linked from newest to oldest. When creating a new version, Firebird checks
to see if there is enough space on the page with the older version - that page I'll call the primary page for the
record. . If so, fine and Firebird just twiddles the page index* on the primary page so all references in user
defined indexes point to the new version. If not, Firebird moves the old record to a different page. Under some
circumstances, the new record may still not fit on the primary page. In that case, Firebird fragments the new
record and marks its header to show that it's fragmented and where to find the rest of it. Fragmented record
headers are bigger than normal record headers.
Another piece of information in the record header is whether the next older version is stored completely or
as a delta from the next newer version. Storing deltas saves a lot of space when most changes to records are
small and it makes finding space on the primary page much easier. If there's a one byte change in a 500 byte
record, it's stored in a few bytes. If we had had one more bit, we would have marked the delta record version
as a delta, which would have made debugging that code much easier. But we didn't.
There's another interesting piece of information in the record header - the format version number. When a table
is defined, Firebird creates a record in the system table RDB$Formats which describes the format of the record
(dunh). When the definition changes, Firebird stores a new record in RDB$Formats describing the new format.
When Firebird reads a record, it knows what format version it wants and converts old formats to new. Almost
all changes to a table can be performed without rewriting the data. And of course, that's why for many decades,
Firebird only allowed 255 changes to the format of a table before it's time to backup and restore the database.