VARCHAR(n) in SQL stores a string of up to characters, taking only as much space as the actual string needs plus a small length header. A VARCHAR(255) holding the string "Bob" occupies a few bytes, not 255. This makes VARCHAR the right choice for strings whose length varies — names, emails, addresses, anything where some values are short and others are long.

CREATE TABLE students (
    first_name   VARCHAR(255),
    family_name  VARCHAR(255),
    email        VARCHAR(255) UNIQUE
);

The maximum length is part of the column’s schema definition. The database enforces it: attempts to insert a longer string either fail or are silently truncated (the exact behaviour depends on the database’s strict-mode settings — MySQL truncates in non-strict mode, errors in strict mode; PostgreSQL always errors). Picking involves a tradeoff between flexibility and storage planning, but on modern databases the cost of a generous maximum is small.

Dialect maxima for :

  • MySQL: up to 65,535 bytes per row across all VARCHAR columns combined, so the practical per-column max under UTF-8 is around 21,844 characters and shrinks as more columns are added.
  • PostgreSQL: up to about 10,485,760 characters, with a hard row limit of ~1 GB. VARCHAR without a length parameter accepts strings of any length up to that limit.
  • SQLite: VARCHAR(n) is accepted but treated as TEXT with no length enforcement.
  • SQL Server: up to 8,000 characters for VARCHAR(n); use VARCHAR(MAX) for up to ~2 GB.

Compare:

  • CHAR(n) — exactly characters, padded with spaces if shorter. Efficient for truly fixed-length data.
  • VARCHAR(n) — up to characters, takes only what it needs. The right default for variable-length strings.
  • ENUM — constrained to a fixed list of values. Compact and acts as a constraint.

For strings longer than VARCHAR’s per-row maximum (an issue mainly in MySQL), TEXT, MEDIUMTEXT, LONGTEXT are stored off-row and only the pointer counts against the row limit. For binary content, use BLOB and friends.