Language
English English Vietnamese (Tiếng Việt) Vietnamese (Tiếng Việt) Chinese (简体中文) Chinese (简体中文) Portuguese (Brazil) (Português do Brasil) Portuguese (Brazil) (Português do Brasil) Spanish (Español) Spanish (Español) Indonesian (Bahasa Indonesia) Indonesian (Bahasa Indonesia)
Bytes to Gigabytes

Bytes to Gigabytes

Turn the raw byte integers a database returns for tables, indexes and relations into the gigabyte figures a capacity plan or a volume resize is written in.

Turning Row Bytes Into a Table Size You Can Plan Around

Databases answer in bytes. pg_total_relation_size('orders') returns a bare integer; information_schema.tables reports data_length and index_length in bytes; a storage-engine stats page gives you a nine- or twelve-digit number with no unit at all. Capacity planning, on the other hand, happens in gigabytes — the unit of the disk you have to provision, the volume you have to grow and the budget line someone has to approve.

The factor: GB = bytes ÷ 1 000 000 000. So a table reported as 42 500 000 000 bytes is 42 500 000 000 ÷ 1 000 000 000 = 42.5 GB.

The useful skill is not the division itself but knowing which bytes the number contains. A relation size and a table size are different figures, and the gap between them is usually where a capacity forecast goes wrong.

Row width is never just the columns

PostgreSQL adds a 23-byte tuple header plus a 4-byte line pointer to every row, and alignment padding rounds column widths up. A row you calculated at 100 bytes lands nearer 130 on disk.

Indexes are often the bigger half

A heavily indexed table can carry more index bytes than heap bytes. That is why the total-relation figure and the plain table figure diverge, sometimes by a factor of two or more.

Growth is a rate, not a snapshot

Row width times rows per day gives bytes per day. Converted to GB per month it becomes the number that decides whether you resize the volume this quarter or next year.

From a Byte Figure to a Provisioning Number

1

Pull the byte figure from the database

Ask for the raw integer rather than a pretty-printed string — the unformatted value is what you want to convert, and it avoids the server having already rounded to one decimal place for you.

2

Paste it into the bytes field

The gigabyte value appears as you type. Query output is often already grouped with spaces or uses a comma as the decimal mark; both are handled, and spaces are simply ignored.

3

Copy it into the capacity plan

The per-field copy button hands back the bare number, so the figure drops straight into a spreadsheet cell, a Terraform volume size or a ticket without stripping units first.

4

Reverse it to write a threshold

Swap the fields to go from gigabytes back to bytes when a monitoring rule or a quota needs the value in the unit the database exposes. Either dropdown is searchable, so terabytes are one keystroke away when a table outgrows GB.

Row Width × Row Count: What a Table Actually Costs

Multiply the average on-disk row width by the number of rows and you get heap bytes; divide by a billion for gigabytes. The figures below assume the width already includes the per-row header, and exclude indexes — add those separately.

Typical table Row width Rows Heap bytes Size in GB
Event stream, narrow96 B250 000 00024 000 000 00024 GB
Session records128 B10 000 0001 280 000 0001.28 GB
Order lines256 B50 000 00012 800 000 00012.8 GB
User profiles512 B100 000 00051 200 000 00051.2 GB
Audit log with JSON1 024 B5 000 0005 120 000 0005.12 GB
Documents, wide rows2 048 B1 000 0002 048 000 0002.048 GB

Two adjustments almost always apply. Dead tuples awaiting vacuum inflate the heap above the arithmetic figure, and any column whose value exceeds roughly two kilobytes is compressed and pushed out to a TOAST relation, which the plain table size does not include but the total relation size does.

Both fields live while you compare tables

Type in either box and the other follows immediately, so you can run down a list of relation sizes from one query without clearing and re-entering each time.

Twelve-digit values stay readable

Thousands are separated with a space and very large results switch to scientific notation, which makes miscounted digits in a raw byte figure obvious at a glance.

Follows a table past a terabyte

Both unit menus are searchable and list every storage unit, so the same page covers a small lookup table in kilobytes and a partitioned fact table in terabytes.

Production figures stay local

Everything is computed in the browser after the page loads, so sizes copied out of a production database are never sent anywhere.

Database Sizing Questions

Why is my table bigger than the column widths suggest?

Every row carries fixed overhead before your data starts. In PostgreSQL that is a 23-byte tuple header plus a 4-byte item pointer in the page, and column values are padded to their alignment boundary — a bigint after a bool may waste seven bytes. On a narrow table those additions can be a third of the row. Multiply the real width, not the nominal one, before dividing into gigabytes.

Should indexes be counted in the size I provision for?

Yes, and they are frequently underestimated. Each index stores its key columns plus a row pointer and its own page overhead, so a table with six indexes can spend more space on them than on the heap. Size the heap and the indexes separately, convert each to gigabytes, and provision the sum — then leave headroom for the temporary copy a reindex needs.

What exactly does the total relation size include?

It returns bytes for the heap, every index, the free-space and visibility maps, and any TOAST relation attached to the table. The plain table-size function covers the heap and its maps only. When a monitoring dashboard and a manual query disagree about a table, this is almost always why — one of them counted the indexes and the other did not.

How do oversized column values change the arithmetic?

A row must fit inside a page, so once a value grows past roughly two kilobytes the engine compresses it and, if that is not enough, moves it out of line into a side relation, leaving a small pointer in the row. The visible row width collapses while the real storage sits elsewhere. For a table of large text or JSON documents, a width-times-rows estimate can be wildly low unless you measure the side relation too.

How do I project next year's size from rows per day?

Multiply rows per day by the measured on-disk width to get bytes per day, convert that to gigabytes, then multiply by the retention window. At 2 000 000 rows a day and a 256-byte width you are adding 512 000 000 bytes daily — 0.512 GB, about 15.4 GB a month. Apply the index ratio you measured on the existing data on top, and check the result against the actual growth after a month rather than trusting the first estimate.

B
GB

Relation Sizes in Bytes

250 000 000 B=0.25 GB
1 073 741 824 B=1.073741824 GB
5 000 000 000 B=5 GB
42 500 000 000 B=42.5 GB
120 000 000 000 B=120 GB
1 250 000 000 000 B=1 250 GB

Byte (B)

The unit every size function reports in: heap pages, index pages, TOAST relations and the 23-byte row header all arrive as a bare integer count of bytes.

Gigabyte (GB)

One billion bytes, and the unit a capacity plan is argued in — the volume you provision, the growth you forecast per month and the storage line on the invoice.

Convert the raw integer your query returns, not a pretty-printed string that has already been rounded
Size the heap and the indexes separately — a well-indexed table can spend more space on indexes than on rows
Use swap to go back to bytes when a monitoring threshold or a quota has to be written in the unit the database exposes
Both unit menus are searchable, so a partitioned table that outgrows GB can be read in TB on the same page
Want to learn more? Read documentation →
1/5
Start typing to search...
Searching...
No results found
Try searching with different keywords