Database

Database Row Size Calculator

Turns a CREATE TABLE into a byte-by-byte row cost, then into a table size.

Loading the tool…

Processing happens locally in your browser. What you paste or load is processed by this page and is not uploaded to a server. Nothing is stored unless you use a control that says it stores something, and you can clear anything this site has kept from the privacy page.

How to use this tool

  1. Paste the CREATE TABLE statement, or load a .sql file with the picker.
  2. Pick the engine you are actually running — the row header, the alignment rules and the page size all differ between them.
  3. Set the row count to what you expect the table to hold.
  4. Select Calculate the row size.
  5. Read the ROW TOTAL and ROWS PER PAGE lines together — if very few rows fit on a page, moving a large text column to its own table is usually the cheapest fix.

What row size calculator does

Adding up the declared widths of the columns gives a number that is always wrong, usually by a third. A row carries a header before any of your data — twenty-three bytes on PostgreSQL, five on InnoDB, seven on SQL Server. If any column is nullable there is a null bitmap. On PostgreSQL every column is aligned to its own natural boundary, so a boolean sitting between two timestamps costs eight bytes rather than one. And rows are packed into fixed-size pages, so a row that is one byte too large for two-per-page wastes nearly half the file.

This page reads your CREATE TABLE and shows the whole calculation: every column with its width and the padding in front of it, then the header, the null bitmap, the page pointer, the row total, how many rows fit on a page, and what the table comes to at the row count you give. Change the engine and the numbers change, because the overheads genuinely differ. Variable-length columns are estimated at half their declared length by default — that is an assumption, and it is stated on the row rather than hidden in the total.

Frequently asked questions

Because a row is more than its columns. Every row carries a header — twenty-three bytes on PostgreSQL, five on InnoDB, seven on SQL Server — plus a null bitmap if any column is nullable, plus a pointer in the page slot array. On PostgreSQL each column is also aligned to its natural boundary, so a one-byte boolean between two eight-byte timestamps costs eight. All of those appear as their own rows in the result so you can see where the difference went.

At half their declared length by default, plus the engine length prefix, and the row says so. A varchar(40) at 50% counts as 24 bytes on PostgreSQL. If you know your real average, change the fill percentage — that single assumption usually moves the total more than anything else on the page. Unbounded types like text with no declared length are assumed to be 64 characters.

No. PostgreSQL moves large values out of the row into TOAST storage and compresses them, InnoDB has compressed and dynamic row formats, and SQL Server has page and row compression. Any of those makes the real figure smaller, sometimes dramatically. Read this as the uncompressed upper bound.

On PostgreSQL it genuinely does. Alignment padding is inserted in front of a column whose boundary the current offset does not sit on, so grouping the wide fixed-width columns together and putting the one-byte columns at the end can save real bytes per row. On MySQL and SQL Server there is no such padding and the order makes no difference to size.