Skip to main content
April 10, 2026
Solved

Systems Diagnostics - Database Sizes math?

  • April 10, 2026
  • 1 reply
  • 3 views

Does anyone know how Used (GB) and Unused is derived? Maybe I'm wrong, going to assume it's looking at total_size, total_used, reserved_pages, ect.. Trying to figure out the math, and questioning if it's correct. This is what I have so far, any feedback is appreciated!

Dim sql As String =
        "SELECT " &
        "    DB_NAME()                                                                   AS DatabaseName, " &
        "    CAST(f.total_size      * 8.0 / 1048576 AS DECIMAL(10,2))                    AS TotalSizeGB, " &
        "    CAST(f.total_used      * 8.0 / 1048576 AS DECIMAL(10,2))                    AS UsedByFilesGB, " &
        "    CAST((f.total_size - f.total_used) " &
        "                           * 8.0 / 1048576 AS DECIMAL(10,2))                    AS UnallocatedGB, " &
        "    CAST(s.reserved_pages  * 8.0 / 1048576 AS DECIMAL(10,2))                    AS ReservedGB, " &
        "    CAST(s.data_pages      * 8.0 / 1048576 AS DECIMAL(10,2))                    AS DataGB, " &
        "    CAST(s.index_pages     * 8.0 / 1048576 AS DECIMAL(10,2))                    AS IndexSizeGB, " &
        "    CAST((s.reserved_pages - s.data_pages - s.index_pages) " &
        "                           * 8.0 / 1048576 AS DECIMAL(10,2))                    AS UnusedGB " &
        "FROM ( " &
        "    SELECT " &
        "        SUM(size)                               AS total_size, " &
        "        SUM(FILEPROPERTY(name, 'SpaceUsed'))    AS total_used " &
        "    FROM sys.database_files " &
        ") f " &
        "CROSS JOIN ( " &
        "    SELECT " &
        "        SUM(a.total_pages)                                           AS reserved_pages, " &
        "        SUM(CASE WHEN p.index_id IN (0,1) " &
        "                 THEN a.used_pages " &
        "                 ELSE 0 END)                                         AS data_pages, " &
        "        SUM(CASE WHEN p.index_id > 1 " &
        "                 THEN a.used_pages " &
        "                 ELSE 0 END)                                         AS index_pages " &
        "    FROM sys.partitions p " &
        "    JOIN sys.allocation_units a " &
        "      ON p.partition_id = a.container_id " &
        ") s"

Here's the output

--- Level 1 (Total) --- TotalSize: 1394.27 GB

UsedByFiles: 228.51 GB

Unallocated: 1165.75 GB (83.6% of Total)

LogFile: 1.67 GB (0.1% of Total)

--- Level 2 (Reserved) ---

Reserved: 226.85 GB (16.3% of Total)

UsedGB (Data+Index): 221.60 GB (15.9% of Total)

Unused: 5.25 GB (0.4% of Total)

--- Level 3 (Used) ---

Data: 129.73 GB (9.3% of Total)

IndexSize: 91.87 GB (6.6% of Total)

--- Math Checks ---

Total=Reserved+Unalloc+Log: 1394.27 = 1394.27 → True

Reserved=Used+Unused: 226.85 = 226.85 → True

Used=Data+Index: 221.60 = 221.60 → True

Best answer by JJones

OneStream System Diagnostics is pulling the values from the System database or is running a stored procedure depending on if this is Standard SQL Server or SaaS and then divides the values by 1024 to get each value.

It pulls from Sys.ResourceStats for SAAS and runs a stored procedure EXEC sp_spaceused @oneresultset = 1 for Standard SQL which returns the values in KB and then does the math to convert to GB

1 reply

JJonesAnswer
April 13, 2026

OneStream System Diagnostics is pulling the values from the System database or is running a stored procedure depending on if this is Standard SQL Server or SaaS and then divides the values by 1024 to get each value.

It pulls from Sys.ResourceStats for SAAS and runs a stored procedure EXEC sp_spaceused @oneresultset = 1 for Standard SQL which returns the values in KB and then does the math to convert to GB