Postgres Table Size Estimator
How big will this table actually get? Enter your columns and an expected row count and this calculator works out the on-disk size the way PostgreSQL does: a 23-byte tuple header, a null bitmap when any column is NULLable, alignment padding between values, MAXALIGN rounding, the 4-byte item pointer each row costs in its page, and how many rows then fit in an 8 KB page at your fillfactor. It also estimates B-tree index sizes and shows how much space you would save by reordering columns. Everything is computed in your browser — no schema or data leaves your machine.
Do more than postgres table size estimator — meet Chat2DB
Chat2DB is an AI-powered SQL client for Windows, macOS and Linux. Write SQL in natural language, format and optimize queries automatically, and manage MySQL, PostgreSQL, Oracle and 20+ other databases in one workspace.
How to use
- List your columns one per line as `name type`, adding `null` for NULLable columns and `avg=N` to set the average byte length of text or jsonb values.
- Enter the expected row count and the table's fillfactor (100 for append-only tables, 70–90 for heavily updated ones).
- List one index per line as a comma-separated key column list, then read the estimated heap size, index size and the column-order savings.
Frequently asked questions
How do I calculate the row size of a PostgreSQL table?
Start with the 23-byte HeapTupleHeaderData, add a null bitmap of ceil(columns/8) bytes if any column is NULLable, and round that up to a multiple of 8 (MAXALIGN) to get t_hoff. Then lay out each column in order, padding to its type alignment: bigint, double precision and timestamptz align to 8, integer and date to 4, smallint to 2, boolean and uuid to 1. Round the whole row up to a multiple of 8 and add 4 bytes for the item pointer in the page. That is the number this tool computes per row.
Why is my table bigger than the sum of its column sizes?
Three reasons: the per-row header and item pointer add ~27 bytes to every row no matter how narrow it is, alignment padding inserts dead bytes between columns of different widths, and dead tuples from UPDATE and DELETE stay in the table until VACUUM reclaims the space. Indexes are counted separately — pg_relation_size shows only the heap, while pg_total_relation_size includes indexes and the TOAST table.
Does column order really affect table size in PostgreSQL?
Yes. Because each value must start on its alignment boundary, a layout like (boolean, bigint, boolean, bigint) wastes 7 bytes of padding after each boolean, while (bigint, bigint, boolean, boolean) wastes none — 14 bytes per row, which is 140 MB across 10 million rows. Ordering columns from widest alignment down to narrowest, with variable-length text last, is free to do at CREATE TABLE time. To inspect real tables, row widths and index sizes across PostgreSQL, MySQL and 20+ other databases, use Chat2DB — download it at https://chat2db.ai/download or open the web version at https://app.chat2db.ai.
