VARCHAR
- Stores variable-length strings up to a declared maximum (VARCHAR(255), VARCHAR(1000), etc., up to 65,535 bytes shared across the row).
- Can have a DEFAULT value.
- Can be fully indexed (up to index length limits).
- Stored inline with the row, which generally makes reads faster for shorter values.
TEXT
- Stores up to 65,535 bytes (TEXT), with larger variants MEDIUMTEXT (16MB) and LONGTEXT (4GB).
- Cannot have a DEFAULT value.
- Can only be indexed with a prefix length (e.g. the first 191 characters).
- May be stored off-page, which can add I/O for reads but keeps the main row compact.
Which should you choose?
Use VARCHAR when:- The value has a sensible, known maximum length (usernames, emails, titles, slugs).
- You want to index or sort by the full column.
- You need a DEFAULT value.
- The content is long-form or unbounded (article bodies, descriptions, serialized data, logs).
- You rarely filter or sort on the column directly.
Practical tips
- Don’t declare VARCHAR(255) by habit — pick a realistic limit. Length limits act as a basic data-quality guard.
- In utf8mb4, indexes on VARCHAR columns are limited to 191 characters with the older index format — relevant when adding unique indexes.
- Avoid SELECT * on tables with large TEXT columns when you don’t need them; fetching large off-page values adds overhead.
- For repeated fixed sets of values, consider ENUM or a lookup table rather than free-text columns.