PostgreSQL LENGTH(): Length of a String, char_length and octet_length

To get the PostgreSQL length of a string, call length(): it counts characters, not bytes. Here’s the shortest version, with the byte count next to it:

SELECT length('José')       AS characters,
       octet_length('José') AS bytes;
 characters | bytes 
------------+-------
          4 |     5
(1 row)

That returns 4 characters but 5 bytes, because é takes two bytes in UTF-8.

In this tutorial, I’ll show you every PostgreSQL length function on one small customers table: char_length, octet_length, char(n) padding, trimming, CHECK limits, arrays and NULLs.

PostgreSQL length functions at a glance

FunctionReturns‘José’ gives
length(text)Number of characters4
char_length(text) / character_length(text)Number of characters (SQL standard name)4
octet_length(text)Number of bytes5
bit_length(text)Number of bits (8 x bytes)40

The string functions accept char, varchar and text; see my PostgreSQL data types guide.

The sample customers table for the length examples

Every query runs on PostgreSQL 18 against six US customers, two with accented names:

CREATE TABLE customers (
  customer_id int PRIMARY KEY,
  full_name   text NOT NULL,   -- 'José Ramírez', 'Zoë Thompson'
  username    varchar(20),     -- '  avance ', one NULL
  state       char(2) NOT NULL,
  promo_code  char(8),         -- 'SAVE10'
  tags        text[]           -- {vip,newsletter}, {}, NULL
);

To follow along, create a table in PostgreSQL like this one.

length vs char_length vs octet_length vs bit_length

Same customers table, three names, all four functions side by side:

SELECT full_name,
       length(full_name)       AS length,
       char_length(full_name)  AS char_length,
       octet_length(full_name) AS octet_length,
       bit_length(full_name)   AS bit_length
FROM customers
WHERE customer_id IN (1, 2, 4);

Output:

  full_name   | length | char_length | octet_length | bit_length 
--------------+--------+-------------+--------------+------------
 Megan Bowen  |     11 |          11 |           11 |         88
 José Ramírez |     12 |          12 |           14 |        112
 Zoë Thompson |     12 |          12 |           13 |        104
(3 rows)
PostgreSQL length, char_length, octet_length and bit_length on accented names, run in psql from VS Code
José Ramírez is 12 characters but 14 bytes; Megan Bowen is 11 of each.

length and char_length always agree. Bytes differ only where é, í or ë take two bytes each in UTF-8.

Note: on Windows, if é looks garbled in psql, run chcp 65001 first so the console reads UTF-8, as in my screenshots.

Emoji make the gap bigger, since one emoji is four bytes:

SELECT length('Thanks 👍')       AS characters,
       octet_length('Thanks 👍') AS bytes;

Output:

 characters | bytes 
------------+-------
          8 |    11
(1 row)

So if an API or a fixed-width file limits bytes, check octet_length, not length.

How do you find the length of a string column and filter with WHERE?

Pass the column to length(), and use the same expression in the WHERE clause. This finds names longer than 11 characters:

SELECT customer_id, full_name,
       length(full_name) AS name_length
FROM customers
WHERE length(full_name) > 11
ORDER BY name_length DESC;

Output:

 customer_id |       full_name        | name_length 
-------------+------------------------+-------------
           6 | Christopher Montgomery |          22
           2 | José Ramírez           |          12
           4 | Zoë Thompson           |          12
(3 rows)
PostgreSQL length of string column filtered with WHERE length(full_name) > 11 and sorted by length
Three names are longer than 11 characters; the longest has 22.

Christopher Montgomery comes first with 22. Sorting by length is just ORDER BY on the alias, or on length(full_name) itself.

Length of char(n) vs varchar vs text: where trailing spaces go

The promo_code column is char(8), so ‘SAVE10’ is stored padded to eight characters:

SELECT promo_code,
       length(promo_code)             AS length,
       octet_length(promo_code)       AS bytes,
       length('SAVE10  '::varchar(8)) AS varchar_len,
       length('SAVE10  '::text)       AS text_len
FROM customers
WHERE customer_id = 1;

Output:

 promo_code | length | bytes | varchar_len | text_len 
------------+--------+-------+-------------+----------
 SAVE10     |      6 |     8 |           8 |        8
(1 row)
PostgreSQL length of a char(8) value ignores trailing spaces while octet_length counts them
length() says 6 for the padded char(8) value; octet_length() still counts all 8 bytes.

Important: length converts char(n) to text first, which strips the padding. octet_length takes char(n) directly, so it keeps it, while varchar and text keep every space.

That’s one reason I use varchar or text for new columns; here’s how text and varchar compare.

Trim spaces before measuring: length(trim(…))

Imported data often has stray spaces. Same table: find usernames where trimming changes the length:

SELECT customer_id,
       '[' || username || ']'  AS username,
       length(username)        AS raw_length,
       length(trim(username))  AS trimmed_length
FROM customers
WHERE length(username) <> length(trim(username));

Output:

 customer_id |  username   | raw_length | trimmed_length 
-------------+-------------+------------+----------------
           3 | [  avance ] |          9 |              6
(1 row)
PostgreSQL length(trim(username)) finds values with leading and trailing spaces
The brackets show two leading spaces and one trailing space: 9 characters raw, 6 after trim.

trim() only removes spaces at both ends. To drop spaces inside a value too, use PostgreSQL REPLACE before you measure.

PostgreSQL length of NULL and empty strings

NULL isn’t an empty string, and the results show it (I set psql to print (null)):

\pset null '(null)'
SELECT length(NULL::text) AS null_value,
       length('')         AS empty_string,
       length(' ')        AS one_space;

SELECT full_name,
       coalesce(length(username), 0) AS username_length
FROM customers
WHERE username IS NULL;

Output:

Null display is "(null)".
 null_value | empty_string | one_space 
------------+--------------+-----------
     (null) |            0 |         1
(1 row)

  full_name  | username_length 
-------------+-----------------
 Alex Wilber |               0
(1 row)

length(NULL) is NULL, '' is 0 and a single space is 1. Wrap it in coalesce(..., 0) when a report needs a number, as with Alex Wilber’s missing username.

Enforce a maximum length with varchar(n) or a CHECK constraint

A CHECK constraint can use char_length for both a minimum and a maximum. You add it with ALTER TABLE:

ALTER TABLE customers
  ADD CONSTRAINT username_length_chk
  CHECK (char_length(trim(username)) BETWEEN 3 AND 15);

INSERT INTO customers (customer_id, full_name, username, state)
VALUES (7, 'Lee Gu', 'lg', 'IL');

Error:

ALTER TABLE
psql:length-check-constraint.sql:6: ERROR:  new row for relation "customers" violates check constraint "username_length_chk"
DETAIL:  Failing row contains (7, Lee Gu, lg, IL, null, null).
PostgreSQL CHECK constraint with char_length rejecting a username shorter than 3 characters
ALTER TABLE succeeds, then the 2-character username ‘lg’ breaks username_length_chk.

Trimming inside the check counts ‘ avance ‘ as 6. NULL usernames pass, since a CHECK only fails on false.

A varchar(20) column gives you a hard maximum without any constraint:

INSERT INTO customers (customer_id, full_name, username, state)
VALUES (8, 'Isaiah Langer', 'isaiah.langer.chicago', 'IL');

Error:

psql:length-varchar-too-long.sql:2: ERROR:  value too long for type character varying(20)

Fix it by shortening the value or widening the column; here’s how to change a column’s data type.

PostgreSQL array length: array_length vs cardinality

For arrays, length() doesn’t apply. Same customers, now the tags column:

\pset null '(null)'
SELECT full_name, tags,
       array_length(tags, 1) AS array_length,
       cardinality(tags)     AS cardinality
FROM customers
WHERE customer_id IN (2, 3, 6);

Output:

Null display is "(null)".
       full_name        |         tags          | array_length | cardinality 
------------------------+-----------------------+--------------+-------------
 José Ramírez           | {newsletter}          |            1 |           1
 Adele Vance            | {}                    |       (null) |           0
 Christopher Montgomery | {vip,beta,newsletter} |            3 |           3
(3 rows)
PostgreSQL array_length returns NULL for an empty array while cardinality returns 0
Adele Vance’s empty array: array_length gives NULL, cardinality gives 0.

array_length needs the dimension and returns NULL for an empty array; cardinality returns 0. For JSON arrays, use jsonb_array_length:

SELECT jsonb_array_length('["vip", "beta"]') AS json_items;

Output:

 json_items 
------------
          2
(1 row)

That’s 2 items. Here’s how JSON and JSONB differ.

How do you get the length of a number in PostgreSQL?

length() only takes text, so cast numbers and dates first:

SELECT length(90210::text)              AS zip_digits,
       length(DATE '2026-10-27'::text)  AS date_chars;

SELECT length(90210);

Output:

 zip_digits | date_chars 
------------+------------
          5 |         10
(1 row)

psql:length-of-number.sql:4: ERROR:  function length(integer) does not exist
LINE 1: SELECT length(90210);
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

The cast gives 5 digits for the ZIP code and 10 characters for the date. Without it, you get function length(integer) does not exist. More on casting in PostgreSQL.

Common mistakes with PostgreSQL length

  • Checking length when the limit is in bytes: use octet_length for UTF-8 data.
  • Forgetting that char(n) padding disappears in length but not in octet_length.
  • Measuring before trim(), so stray spaces pass a minimum-length check.
  • Filtering a big table on length(col) without an expression index on that same expression.

Once you can measure strings, try these next:

Frequently Asked Questions

What is the difference between length and char_length in PostgreSQL?

For text there’s none: both return the number of characters. char_length (and character_length) is the SQL-standard name, as the PostgreSQL 18 string functions docs list.

Does PostgreSQL length count spaces?

Yes. Leading, trailing and inner spaces all count, except the trailing padding of a char(n) value, which length() strips.

How do I get the length of a string in bytes in PostgreSQL?

Use octet_length(). In a UTF-8 database, accented letters take two bytes and most emoji take four.

What is the maximum length of a varchar or text value in PostgreSQL?

Any string can be about 1 GB. In varchar(n), n can’t exceed 10,485,760 (character types).