Skip to main content

Command Palette

Search for a command to run...

Postgres OID VS Relfilenode

Updated
2 min read
Postgres OID VS Relfilenode

When you create a table, PostgreSQL assigns it an OID (Object Identifier). This is just a logical identifier for the table. it is stored in the system catalog pg_class and remains constant for the lifetime of the table.

But under the hood in physical file on disk is identified by the relfilenode, which is also stored in system catalog pg_class. But the good news is that most of the time OID and Relfilenode are same. But they can diverge, and understanding when and why is probably the most crucial.

Try This Experiment

CREATE TABLE demo(
    id INT,
    data TEXT
);

SELECT oid, relfilenode FROM pg_class WHERE relname = 'demo';

Again

TRUNCATE demo;
SELECT oid, relfilenode FROM pg_class WHERE relname = 'demo';

Now you might see the different oid and relfilenode from those commands. The OID stayed the same but why relfilenode changed ?

When you truncate a table, PostgreSQL doesn't actually delete all the rows from the existing file. Instead, it creates a brand new file with a new relfilenode and updates the catalog to point to it. The old file is deleted. This is much faster than scanning through the file and marking every tuple as deleted, and it's safer from a crash-recovery perspective—the old file exists until the transaction commits.

The same thing happens with VACUUM FULL, CLUSTER, and REINDEX (for indexes). These operations rewrite the entire table or index, giving it a new physical file. But the OID never changes. This separation between logical identity (OID) and physical storage (relfilenode) allows PostgreSQL to reorganize data without breaking foreign key constraints, views, or permissions, all of which reference the OID.

10 views

Demystifying Postgres

Part 4 of 5

Explore PostgreSQL internals in this series—learn how data is stored, queries run, and transactions work. Hands-on experiments and system-level insights help you master PostgreSQL like a backend engineer.

Up next

Understanding Heap File Storage

When you execute INSERT INTO users VALUES (1, 'Alice') in PostgreSQL, what actually happens on disk? Where does that data go? How is it organized? Why does a simple SELECTsometimes cause disk writes? These aren't just academic questions—they're the f...