Calculating Row Value Lengths in YugabyteDB

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!

While visiting my old college town, I took my wife to see the "paradise" I once shared with the guys… only to find a run-down duplex with a front-yard garbage display. Maybe it looked like this back then too? 😂🏚️🍕🍺