BUG #19456: # Unit-Labeling Issue: `pg_size_pretty()` Incorrectly Labels Binary Units as Decimal Units - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #19456: # Unit-Labeling Issue: `pg_size_pretty()` Incorrectly Labels Binary Units as Decimal Units
Date
Msg-id 19456-b16ffd2798ae6fd5@postgresql.org
Whole thread
Responses Re: BUG #19456: # Unit-Labeling Issue: `pg_size_pretty()` Incorrectly Labels Binary Units as Decimal Units
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      19456
Logged by:          GAUTAM KUMAR
Email address:      gautamkumar2764@gmail.com
PostgreSQL version: 16.8
Operating system:   LINUX
Description:

Dear PostgreSQL Team,

I would like to report a unit-labelling inconsistency in the
pg_size_pretty() function in Aurora PostgreSQL.
The function appears to calculate sizes using binary (base-2) division—that
is, dividing by 1024 at each unit step—but labels the results using decimal
(SI) unit symbols such as MB, GB, and TB.
Per commonly accepted standards such as IEC 80000-13 and IEEE 1541, values
derived using binary multiples should be labelled with binary prefixes such
as MiB, GiB, and TiB, while MB, GB, and TB should refer to decimal (base-10)
units.


Environment

•       Database Engine: Aurora PostgreSQL
•       Affected Function: pg_size_pretty(bigint), pg_size_pretty(numeric)


Steps to Reproduce

SQl Query:--

SELECT
    datname AS database_name,
    pg_database_size(datname) AS size_bytes,
    pg_size_pretty(pg_database_size(datname)) AS size_pretty,
    ROUND(pg_database_size(datname) / (1000.0^3), 2) AS size_gb_decimal,
    ROUND(pg_database_size(datname) / (1024.0^3), 2) AS size_gib_binary
FROM pg_database
WHERE datistemplate = false
ORDER BY pg_database_size(datname) DESC;


Observed Sample Output

| Database | Size (Bytes)    | pg_size_pretty | Actual GB (÷10⁹) | Actual
GiB (÷2³⁰) |
| --------    | ---------------         | --------------      |
----------------         | -----------------    |
"DB1"   140492455907    "131 GB"                     140.49
130.84
"DB2"   125492355043    "117 GB"                     125.49
116.87


Example Analysis:-

Taking “DB1” (140,492,455,907 bytes) as an example:

•       Decimal (GB): 140,492,455,907 ÷ 1,000,000,000 = 140.49 GB
•       Binary (GiB):    140,492,455,907 ÷ 1,073,741,824 = 130.84 GiB
•       pg_size_pretty()  output: 131 GB

The `pg_size_pretty` value of 131 matches the binary (GiB) calculation
(130.84 rounded), which indicates the function is using base-2 conversion.
However, the label says "GB" (a decimal unit), not "GiB" (the correct binary
unit).

Unit Mislabelling Error

This is a ~7.4% discrepancy per unit step (1 GiB = 1.074 GB), which grows
with database size:

Database        pg_size_pretty  Actual GB (decimal)     Error
(underreported)
DB1     131 GB  140.49 GB       9.49 GB (6.75 %)
DB2     117 GB  125.49 GB       8.49 GB (6.75%)
Total   248 GB  265.98 GB       17.98 GB


When using `pg_size_pretty` output for capacity planning or billing, these
two databases alone are underreported by ~18 GB.
For large production databases in the terabyte range, this mislabelling can
cause hundreds of gigabytes of misinterpretation in capacity planning,
billing analysis, and compliance reporting.


Impact:-

This can create confusion in several practical scenarios:

•       Capacity Planning: Teams relying on `pg_size_pretty` may
underestimate actual storage needs by ~7-10% when interpreting "GB" at face
value.
•       Cost Estimation: AWS storage billing is typically in GB (decimal).
Using `pg_size_pretty` output directly in cost calculations leads to
inaccurate estimates.
•       Compliance & Auditing: Reports using `pg_size_pretty` produce
technically incorrect unit labels, which can cause issues in regulated
environments.
•       Developer Confusion: Engineers comparing `pg_size_pretty` output
against OS-level or AWS Console metrics (which may use either convention)
face inconsistencies.


Expected Behaviour

`pg_size_pretty()` should either:

1. Option A (Preferred): Use correct IEC binary unit labels:
   - Output `129 GiB` instead of `129 GB`
   - Output `107 MiB` instead of `107 MB`

2. Option B: Compute using decimal (base-10) divisions to match the
`GB`/`MB` labels:
   - 138,553,548,771 ÷ 1,000,000,000 = `139 GB`


Suggested Fix

Update the unit suffix strings in the `pg_size_pretty` function
implementation:

Current Label   Corrected Label
kB      KiB
MB      MiB
GB      GiB
TB      TiB
PB      PiB

References

•       IEC 80000-13: Defines GiB (gibibyte) = 2³⁰ bytes, GB (gigabyte) =
10⁹ bytes
•       IEEE 1541-2002: Standard for prefixes for binary multiples



Regards,
Gautam kumar





pgsql-bugs by date:

Previous
From: Julien Tachoires
Date:
Subject: Bug in CREATE TABLE .. LIKE .. INCLUDING STATISTICS?
Next
From: SIEBERT Florent
Date:
Subject: patroni-4.1.1-1PGDG.rhel9.7.noarch.rpm missing in https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-9-x86_64/