What’s the Real Maximum Length of MySQL VARCHAR? Understanding Limits and Storage
This article explores the true maximum length of MySQL VARCHAR columns, showing how charset, NULLability, column count, and row format affect the limit, and explains the underlying storage mechanics, row overflow, and alternatives for data larger than 64 KB.
What is the maximum length of VARCHAR?
Many believe the maximum length of a VARCHAR column is 65,535 characters, but this is a misconception. An experiment creating a column with length 65,535 under utf8mb4 fails with an error indicating the maximum is 16,383. Reducing the length to 16,383 succeeds.
Impact of character set
The actual limit depends on the charset because each character may occupy multiple bytes. Using show charset; you can see the maximum bytes per character (Maxlen). For example:
utf8mb4: Maxlen=4 → max VARCHAR length ≈ 16,383 (4 × 16,383 = 65,332 bytes)
utf8mb3: Maxlen=3 → max VARCHAR length ≈ 21,844 (3 × 21,844 = 65,532 bytes)
latin1: Maxlen=1 → max VARCHAR length ≈ 65,533 (1 × 65,533 = 65,533 bytes)
Thus the length specified after VARCHAR represents the maximum number of characters, while the row‑size limit (65,535 bytes) is based on bytes.
Effect of NULLability
If a column is declared NULL, MySQL needs an extra byte to record the null flag. Changing a column from NOT NULL to NULL reduces the usable length by one byte (e.g., from 65,333 to 65,332).
Influence of column count
The 65,535‑byte row limit applies to the sum of all columns in a row (excluding hidden columns and row header). Adding more columns reduces the space available for a single VARCHAR column, and multiple VARCHAR columns can cause the limit to be reached earlier.
Row storage format
MySQL tables typically use the Dynamic row format, which separates extra row information from the actual data. Extra information includes a variable‑length field list, a NULL‑value list, and a 5‑byte record header. The actual data section stores the column values and hidden columns (e.g., Row_ID, trx_id, roll_pointer).
For a single VARCHAR column that is NOT NULL, the variable‑length field list uses two bytes to store the column’s length, leaving the remaining bytes for the data itself.
Row overflow
If a VARCHAR value exceeds the 16 KB page size, MySQL stores a 20‑byte pointer in the row and places the actual data in off‑page overflow pages. This increases I/O when reading such rows.
Handling data larger than 64 KB
When data exceeds the VARCHAR limit, you should use TEXT or BLOB types, which also have TINY, MEDIUM, and LONG variants supporting up to several gigabytes.
Differences between BLOB and TEXT
TEXTcolumns have an associated charset and collation, allowing proper sorting and comparison, while BLOB columns store raw binary data without charset considerations. BLOB can also hold binary files such as images or videos, though object storage services are generally preferred for large binary objects.
Summary
MySQL tables usually use the Dynamic row format, which separates extra row information from actual data.
The maximum size of a row (excluding hidden columns and header) is 65,535 bytes.
For a single NOT NULL VARCHAR column, the effective maximum length is approximately 65,535 divided by the charset’s Maxlen.
To store strings larger than ~64 KB, use LONGTEXT, LONGBLOB, or other large object types.
Dynamic rows store only a 20‑byte pointer for oversized VARCHAR / TEXT / BLOB values, causing additional disk I/O when reading them. BLOB lacks charset support, while TEXT respects charset and collation rules.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
