CHAR, VARCHAR, and TEXT

Understand the differences between PostgreSQL CHAR, VARCHAR, and TEXT character types: storage behavior, length enforcement, and when to use each.

5 min read · Last updated: March 2026 · Back to overview

Quick Answer

PostgreSQL provides three character types: CHAR(n) for fixed-length blank-padded strings, VARCHAR(n) for variable-length strings with a length limit, and TEXT for unlimited variable-length strings. There is no performance difference between them.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

PostgreSQL supports three primary character data types: CHAR(n), VARCHAR(n), and TEXT. Unlike some other database systems, all three are stored identically under the hood — the difference is purely in length enforcement behavior.

Character type comparison

  • CHARACTER(n) / CHAR(n): Fixed-length, blank-padded. Strings shorter than n are padded with spaces. Strings longer than n cause an error (except for excess trailing spaces, which are silently truncated).
  • CHARACTER VARYING(n) / VARCHAR(n): Variable-length with an upper limit of n characters. Inserting a string longer than n raises an error.
  • TEXT / VARCHAR (no length): Variable-length with no upper limit. Both are identical in behavior and performance.

Practical example: length enforcement

CREATE TABLE character_tests (
  id serial PRIMARY KEY,
  x  CHAR(1),
  y  VARCHAR(10),
  z  TEXT
);

Trying to insert a 3-character string into x CHAR(1) raises an error:

INSERT INTO character_tests (x, y, z)
VALUES ('Yes', 'test', 'This is a long text column');
-- ERROR: value too long for type character(1)

Similarly, a string longer than 10 characters in y VARCHAR(10) raises an error:

INSERT INTO character_tests (x, y, z)
VALUES ('Y', 'This is a test for varchar', 'Long text here');
-- ERROR: value too long for type character varying(10)

A valid insert:

INSERT INTO character_tests (x, y, z)
VALUES ('Y', 'varchar(n)', 'This is a very long text for the PostgreSQL text column')
RETURNING *;
id | x |     y      |                            z
----+---+------------+---------------------------------------------------------
 1 | Y | varchar(n) | This is a very long text for the PostgreSQL text column

Choosing the right character type

In most cases, use TEXT or VARCHAR (without a length). Only use VARCHAR(n) when you want PostgreSQL to actively enforce a maximum string length as a data integrity rule — for example, a 2-character ISO country code or a 10-digit phone number field.

Avoid CHAR(n) in new designs — the blank-padding behavior is rarely useful and can cause subtle comparison bugs.

Production tips

  • Prefer TEXT for general-purpose string columns — it avoids unnecessary length restrictions that often become migration pain points later.
  • Use VARCHAR(n) as a constraint, not a performance optimization — PostgreSQL has no storage advantage for shorter types.
  • Add a CHECK constraint for complex validation (e.g., CHECK (char_length(code) = 2)) instead of relying solely on CHAR(2).
  • Casting a string to CHAR(n) or VARCHAR(n) truncates it to n characters — useful for enforcing length at insert without raising an error, but use with care.

Reference: PostgreSQL documentation — Character Types.

Continue in PostgreSQL Data Types: NUMERIC.

Related in this section: Boolean · NUMERIC · DOUBLE PRECISION

Frequently Asked Questions

What is the difference between CHAR, VARCHAR, and TEXT in PostgreSQL?

CHAR(n) stores fixed-length strings padded with spaces to length n. VARCHAR(n) stores variable-length strings and enforces a maximum of n characters, raising an error if exceeded. TEXT stores variable-length strings with no length limit. In PostgreSQL, all three have identical performance.

When should I use VARCHAR(n) versus TEXT?

Use VARCHAR(n) when you want PostgreSQL to enforce a maximum string length as a constraint — for example, a country code column limited to 2 characters. Use TEXT when length is variable and not bounded. Avoid arbitrary length limits like VARCHAR(255) unless you have a real business reason for the limit.

Does CHAR pad strings with spaces in PostgreSQL?

Yes. CHAR(n) pads shorter strings with trailing spaces to reach length n. When comparing CHAR values, trailing spaces are ignored. This blank-padding behavior can cause subtle bugs and is one reason most developers prefer VARCHAR or TEXT.

Is VARCHAR without a length limit the same as TEXT?

Yes. VARCHAR without a length specifier behaves identically to TEXT — both allow strings of unlimited length. The only practical difference is that VARCHAR(n) adds a length enforcement check that TEXT does not.

Is there a performance difference between CHAR, VARCHAR, and TEXT in PostgreSQL?

No. Unlike some other databases, PostgreSQL stores all three types the same way internally. There is no performance advantage to choosing CHAR over TEXT or VARCHAR. The choice should be based on whether you need length enforcement, not performance.