Character Types
PostgreSQL offers three ways to store text: CHAR(n) for fixed-length strings, VARCHAR(n) for variable-length strings with a maximum, and TEXT for text of any length. They look like a hierarchy of increasing flexibility, but PostgreSQL's implementation blurs the lines between them more than you might expect coming from other databases.
Type | Behavior |
|---|---|
| Fixed length. Shorter values are right-padded with spaces up to |
| Variable length, up to a maximum of |
| Variable length, unlimited. No maximum enforced. |
CHAR(n): fixed-length and padded
CHAR pads with spaces
CREATE TABLE codes (code CHAR(5));
INSERT INTO codes VALUES ('AB');
SELECT code, length(code), code = 'AB' AS looks_equal
FROM codes;code | length | looks_equal --------+--------+------------- AB | 5 | t
VARCHAR(n): variable length with a cap
VARCHAR enforces a maximum
CREATE TABLE users (
username VARCHAR(30) NOT NULL
);
INSERT INTO users VALUES ('short_name'); -- fine
INSERT INTO users VALUES (repeat('x', 31)); -- error: value too long for type character varying(30)VARCHAR(n) stores exactly what you insert (no padding) but rejects any value longer than n. It's a good fit when you have a genuine business rule to enforce — a username limited to 30 characters, a two-letter state abbreviation.
TEXT: unbounded text
TEXT has no length limit
CREATE TABLE articles (
title VARCHAR(200) NOT NULL,
body TEXT NOT NULL
);CHAR(n)— fixed length, pads with spaces, and rarely the right choice.VARCHAR(n)— variable length capped atn, useful when you want the database to enforce a length rule.TEXT— variable length, unbounded, and the pragmatic default in PostgreSQL.All three have essentially the same performance characteristics internally — choose based on constraints you actually need, not imagined storage cost.