MySQL String Types: VARCHAR vs TEXT vs CHAR
Also Known As
VARCHAR vs TEXT MySQL
CHAR VARCHAR TEXT
MySQL string column types
TL;DR
CHAR is fixed-length, VARCHAR is variable-length up to 65,535 bytes, TEXT variants store large content — each with different indexing and storage behaviour.
Explanation
CHAR(n) pads shorter values with spaces — slightly faster for fixed-length data. VARCHAR(n) stores actual length + 1-2 bytes overhead. TEXT (64KB), MEDIUMTEXT (16MB), LONGTEXT (4GB) store large content off the main row page — cannot be fully indexed without a prefix length and cannot have DEFAULT values. VARCHAR up to 767 bytes (InnoDB row format default) supports full-column indexing. For utf8mb4, the index limit is 191 characters on older InnoDB row formats.
Common Misconception
✗ TEXT and VARCHAR are interchangeable. TEXT cannot have a DEFAULT value, cannot be fully indexed, and stores data off the main row page — impacting row fetch performance.
Why It Matters
Using TEXT for short columns like email prevents full-column indexes and default values. Using CHAR(255) for variable names pads every row to 255 bytes — wasting storage on every row.
Common Mistakes
- Using TEXT for email, name, or slug columns — no DEFAULT, no full-column index.
- Using CHAR(255) for variable-length data — pads every row regardless of actual content length.
- Forgetting that utf8mb4 VARCHAR(255) requires 255×4=1020 bytes — exceeds the 767-byte InnoDB index limit on older row formats.
Avoid When
- Avoid TEXT for columns that need DEFAULT values or full-column unique indexes.
- Avoid CHAR for variable-length content — every row is padded to the declared length.
When To Use
- Use VARCHAR(255) as the default for most string columns — fully indexable and flexible.
- Use TEXT/MEDIUMTEXT/LONGTEXT for article bodies, descriptions, or any content over 1KB.
- Use CHAR for truly fixed-length values: country codes (CHAR(2)), currency codes (CHAR(3)), UUIDs (CHAR(36)).
Code Examples
✗ Vulnerable
-- TEXT for short fields: no DEFAULT, no full index
email TEXT NOT NULL,
-- CHAR(100) wastes 100 bytes even for 'Bob'
name CHAR(100) NOT NULL
✓ Fixed
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
country_code CHAR(2) NOT NULL DEFAULT 'GB',
bio TEXT,
slug VARCHAR(100) NOT NULL UNIQUE
) ENGINE=InnoDB CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
31 Mar 2026
Views
16
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Google 5
Perplexity 4
Unknown AI 2
ChatGPT 1
Ahrefs 1
Also referenced
How they use it
crawler 11
crawler_json 2
Related categories
⚡
DEV INTEL
Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Use VARCHAR(255) for most string columns, TEXT for large content, CHAR only for truly fixed-length values like country codes
📦 Applies To
web
cli
🔗 Prerequisites
🔍 Detection Hints
TEXT column with UNIQUE or DEFAULT, or CHAR on variable-length fields
Auto-detectable:
✓ Yes
semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Low
✓ Auto-fixable
Fix: Low
Context: Line