Sometimes in YugabyteDB YSQL, you might want to measure the size of the data in a row… for example, to estimate storage, debug string concatenations, or sanity-check column widths.
At first glance, you might try something like this:
SELECT c1, c2, c3, octet_length(test.*::text) AS len
FROM test;
But here’s the catch: casting a row type to TEXT doesn’t give you a simple concatenation of the column values. Instead, it produces a tuple with parentheses and commas:
yugabyte=# SELECT c1, c2, c3, test.*::text, octet_length(test.*::text) AS len
yugabyte-# FROM test;
c1 | c2 | c3 | test | len
----+----+----+------------+-----
AA | AA | AA | (AA,AA,AA) | 10
A | A | A | (A,A,A) | 7
(2 rows)
Notice how len is larger than expected because it’s counting the formatting characters too.
Concatenating Column Values Directly
The simplest fix is just to concatenate the columns yourself:
SELECT c1, c2, c3,
octet_length(c1 || c2 || c3) AS len
FROM test;
Now the output looks right:
yugabyte=# SELECT c1, c2, c3,
yugabyte-# octet_length(c1 || c2 || c3) AS len
yugabyte-# FROM test;
c1 | c2 | c3 | len
----+----+----+-----
AA | AA | AA | 6
A | A | A | 3
(2 rows)
Making It Generic
Manually listing every column gets tedious, especially if your table has lots of them. Instead, you can define a reusable helper function:
CREATE OR REPLACE FUNCTION row_octet_length(anyelement)
RETURNS INT
LANGUAGE sql
IMMUTABLE
AS $$
SELECT octet_length(
(SELECT string_agg(value, '' ORDER BY key)
FROM json_each_text(row_to_json($1)))
);
$$;
This function:
• Works with any row type (
anyelement)• Converts the row to JSON, extracts values, concatenates them in column order, and measures their byte length
• Ignores the tuple formatting characters
Example Usage
yugabyte=# SELECT c1, c2, c3, row_octet_length(test) AS len
yugabyte-# FROM test;
c1 | c2 | c3 | len
----+----+----+-----
AA | AA | AA | 6
A | A | A | 3
(2 rows)
yugabyte=# \d test2
Table "public.test2"
Column | Type | Collation | Nullable | Default
-----------+-----------------------------+-----------+----------+---------
id | integer | | |
some_ts | timestamp without time zone | | |
some_json | jsonb | | |
yugabyte=# SELECT id, some_ts, some_json, row_octet_length(test2) AS len
yugabyte-# FROM test2;
id | some_ts | some_json | len
----+----------------------------+------------------+-----
1 | 2025-08-28 16:58:30.566115 | {"A": 1} | 35
2 | 2025-08-28 00:00:00 | {"A": 1, "B": 2} | 36
(2 rows)
Wrap-up
When you need to measure the length of all values in a row, concatenating columns directly works fine… but defining a small helper function makes it reusable for any table or row type.
Have Fun!
