Last updated:

VARCHAR Max Length by Database - and How to Choose the Right Length

12 min read

The maximum VARCHAR length depends on the database system: MySQL allows up to 65,535 bytes (shared by all columns in a row), PostgreSQL about 1 GB, SQL Server 8,000 bytes, and Oracle 4,000 bytes in standard mode (32,767 in extended mode), while SQLite imposes no limit at all. The quick-reference table below gives the direct answer; the rest of this article explains what those numbers mean in practice.

RDBMSVARCHAR Max LengthNotes
MySQL 8.0 (InnoDB)65,535 bytes (per row)Shared across all columns; utf8mb4 uses up to 4 bytes per character
PostgreSQL~1 GBVARCHAR and TEXT share the same storage; declared length is a check constraint
SQL Server8,000 bytesVARCHAR(MAX) switches to LOB storage
Oracle4,000 bytes (standard) / 32,767 bytes (extended)Byte or character semantics controlled by NLS_LENGTH_SEMANTICS
SQLiteNo limitDynamic typing; VARCHAR declarations are ignored

Choosing the right VARCHAR length for database columns is a fundamental design decision that affects storage efficiency, query performance, and data integrity, much like API response length design impacts the overall system quality. This article covers practical guidelines for common field types across major database systems.

Why VARCHAR(255)? - The Myth Behind the Default

The ubiquitous VARCHAR(255) default traces back to an old MySQL limitation. Before MySQL 5.0, the VARCHAR length prefix was stored in a single byte, capping the maximum at 255. MySQL 5.0 switched to a 2-byte length prefix, allowing up to 65,535 bytes - but the "255" convention persisted as a habit long after the technical constraint disappeared.

There is another reason this convention stuck. In MySQL, a column whose stored values can never exceed 255 bytes uses a 1-byte length prefix, while a column that can exceed that spends 2 bytes. The detail almost everyone misses is that this boundary is measured in bytes, not characters. With a single-byte character set, VARCHAR(255) and VARCHAR(256) really do differ by one byte of overhead per row. With utf8mb4, a single character can take up to 4 bytes, so VARCHAR(64) already reaches 256 bytes at its maximum and already pays the 2-byte prefix. For a schema that stores Japanese text or emoji, the premise that "255 keeps you on the 1-byte side" simply does not hold. The belief that "255 is efficient" is a leftover from the days when character sets were single-byte.

VARCHAR Internal Implementation Across RDBMS

Even with the same VARCHAR(100) declaration, the internal storage format and memory allocation behavior differ significantly across database systems. Failing to understand these differences can lead to unexpected performance and storage issues.

RDBMSMax LengthUnitInternal StorageMemory Allocation
MySQL 8.0 (InnoDB)65,535 bytes (per row)CharactersActual data + a 1- or 2-byte length prefix (2 bytes once values can exceed 255 bytes). Values too long for the row move to off-page storageThe TempTable engine, the default since 8.0, keeps VARCHAR variable-length even in internal temporary tables (no padding). The older MEMORY engine padded to the declared length
PostgreSQL~1 GBCharactersvarlena struct. VARCHAR and TEXT use identical storage. TOAST compresses long values automatically and moves whatever still does not fit into a side tableActual data length only. Declared length acts as a check constraint
SQL Server8,000 bytesBytes (official docs: "n never defines numbers of characters")In-row storage. VARCHAR(MAX) uses LOB storageQuery execution uses the declared length to estimate and reserve memory (Memory Grant)
Oracle4,000 bytes (standard) / 32,767 bytes (extended)Bytes or Chars (controlled by NLS_LENGTH_SEMANTICS)In-row storage. Extended mode uses SecureFile LOBPGA allocates declared length
SQLiteNo limit-Dynamic typing. VARCHAR declarations are ignored; only actual data length is storedActual data length only

What matters here is whether the declared length turns into a runtime cost. SQL Server plans a query around the declared length, so a VARCHAR(255) column that only ever holds 10 characters can still produce an oversized memory grant for a sort or a hash join, and the query runs less efficiently than the data warrants. MySQL behaved the same way through the 5.x era, when internal temporary tables were built on the MEMORY engine and padded to a fixed width. Since 8.0 the default TempTable engine keeps VARCHAR variable-length, so that specific penalty is largely gone. From 8.0 onward, the reason to keep declared lengths tight is less about saving memory and more about refusing data that should never have been stored in the first place.

UTF-8 Variable-Length Encoding Impact on VARCHAR(255)

Even in RDBMS that specify VARCHAR length in characters, internal byte limits still apply. Understanding the difference between characters and bytes is essential for proper schema design. UTF-8 is a variable-length encoding where different character types consume different numbers of bytes.

Character TypeUTF-8 BytesExamplesMax Chars in VARCHAR(255) (byte equivalent)
ASCII alphanumeric1 bytea, Z, 0, @255 chars (255 bytes)
Latin extended / Cyrillic2 bytesé, ñ, Д255 chars (510 bytes)
CJK characters3 bytes漢, あ, 한255 chars (765 bytes)
Emoji / special symbols4 bytes😀, 🎉, 𠮷255 chars (1,020 bytes)

With MySQL's utf8mb4, a VARCHAR(255) column can consume up to 1,020 bytes in the worst case. InnoDB's row size limit is roughly 8,000 bytes on the default 16 KB page (a little under half the page), and that limit applies to the in-row portion, excluding variable-length columns that have been pushed off-page. So eight VARCHAR(255) columns side by side still give you a table you can create; what happens instead is that as values grow they are moved to overflow pages, and each row whose values no longer fit in-row costs an extra page access on every read. The practical question is not "will it fit" but "will it fit in-row". Use Character Counter to check the byte count of real data during schema design and prevent unexpected truncation.

How Many Japanese Characters Fit in VARCHAR(255)?

For CJK text the character-vs-byte question stops being theoretical. The same VARCHAR(255) declaration stores anywhere from 85 to 255 Japanese characters depending on the RDBMS and its length semantics:

RDBMS / SettingWhat 255 MeansJapanese Characters Stored
MySQL (utf8mb4)255 characters255 (stored as up to 765 bytes)
PostgreSQL255 characters255
Oracle, NLS_LENGTH_SEMANTICS=BYTE (default)255 bytesAbout 85 (3 bytes each in AL32UTF8)
Oracle, VARCHAR2(255 CHAR)255 characters255
SQL Server, Japanese collation (code page 932)255 bytesAbout 127 (2 bytes each)
SQL Server, UTF-8 collation (SQL Server 2019 and later)255 bytesAbout 85 (3 bytes each)
SQL Server, NVARCHAR(255)255 byte-pairs (UTF-16)255 (BMP characters)

SQL Server is the system that most often surprises teams migrating Japanese applications: per Microsoft's official documentation, the n in varchar(n) defines the string size in bytes, and "never defines numbers of characters." A Japanese product-name column planned as "255 characters" but declared VARCHAR(255) under a Japanese collation truncates at roughly half that. The conventional fix is NVARCHAR; since SQL Server 2019, UTF-8 enabled collations (code page 65001) are an alternative that lets VARCHAR hold the full Unicode range at UTF-8 byte costs. Oracle's BYTE default has the same failure mode, which is why explicit CHAR semantics are the standard recommendation for CJK deployments.

DDL Examples: Declaring Columns for Japanese Text

The following CREATE TABLE statements show the safe declaration for a 100-character Japanese product name in each system, followed by the queries that verify how your data is actually being counted.

-- MySQL 8.0: utf8mb4 gives character semantics + full emoji support
CREATE TABLE products (
  id BIGINT PRIMARY KEY,
  name VARCHAR(100)
) CHARACTER SET utf8mb4;

-- PostgreSQL: VARCHAR(n) is always n characters
CREATE TABLE products (
  id BIGINT PRIMARY KEY,
  name VARCHAR(100)
);

-- SQL Server: NVARCHAR for Unicode (or VARCHAR + a UTF-8 collation on 2019+)
CREATE TABLE products (
  id BIGINT PRIMARY KEY,
  name NVARCHAR(100)
);

-- Oracle: explicit CHAR semantics so 100 means 100 characters
CREATE TABLE products (
  id NUMBER PRIMARY KEY,
  name VARCHAR2(100 CHAR)
);

To confirm whether an existing column is counting characters or bytes, compare the character-length and byte-length functions on real data:

-- MySQL: characters vs. bytes ("こんにちは世界" → 7 vs. 21)
SELECT CHAR_LENGTH(name), LENGTH(name) FROM products;

-- PostgreSQL
SELECT char_length(name), octet_length(name) FROM products;

-- SQL Server (LEN ignores trailing spaces; DATALENGTH returns bytes)
SELECT LEN(name), DATALENGTH(name) FROM products;

-- Oracle
SELECT LENGTH(name), LENGTHB(name) FROM products;

If the two numbers match on Japanese test data, the column is byte-limited with single-byte data only so far - a latent truncation bug waiting for the first real Japanese input. Testing with actual CJK strings (and emoji) before launch catches this class of problem cheaply.

VARCHAR vs TEXT - Performance and Indexing Reality

The common advice "use TEXT for long strings" oversimplifies the situation. The trade-offs between VARCHAR and TEXT vary significantly by RDBMS.

AspectMySQL (InnoDB)PostgreSQLSQL Server
Storage differenceVARCHAR and TEXT are handled the same way. Under DYNAMIC, the default row format in 8.0, a value too long for the row is moved to an overflow page and only a pointer remains in-row. The older COMPACT and REDUNDANT formats keep the first 768 bytes in-rowNo difference. VARCHAR(n) and TEXT use the same varlena structVARCHAR is in-row. TEXT (VARCHAR(MAX)) uses LOB storage
IndexingVARCHAR: full index (index keys up to 3,072 bytes with the DYNAMIC row format, the default in 8.0; 767 bytes with the older COMPACT and REDUNDANT). TEXT: an index requires a prefix lengthBoth are equally indexableVARCHAR: full index. TEXT: full-text index only
Sorting / GROUP BYVARCHAR: in-memory. TEXT: may use disk temp tablesNo differenceVARCHAR: in-memory. TEXT: uses tempdb
Default valuesVARCHAR: supported. TEXT: a literal default is not allowed (8.0.13 and later accept an expression default)Both supportedBoth supported

The PostgreSQL documentation is explicit that there is no performance difference among character varying, text and character(n), and that character(n) is in fact the slowest of the three because its blank padding costs extra storage; for most situations it advises using text or character varying. Read that carefully: a length limit is not a performance device, it is a constraint that asserts what a valid value looks like. In MySQL, by contrast, a TEXT column cannot be indexed without a prefix length, so VARCHAR is the right choice for columns you intend to search or sort on.

Emoji (4-Byte UTF-8) Pitfalls with VARCHAR

Modern applications must be designed with the assumption that user input will contain emoji. Emoji consume 4 bytes in UTF-8, but the problems go beyond just byte count.

VARCHAR vs. CHAR

Before choosing a string type, understand the fundamental difference between VARCHAR and CHAR.

PropertyCHAR(n)VARCHAR(n)
StorageFixed-length (padded with spaces)Variable-length (actual data only)
Disk usageAlways n bytesActual data + 1–2 bytes overhead
Best forFixed-length data (country codes, postal codes)Variable-length data (names, emails)
Search speedSlightly faster due to fixed lengthMinor overhead from variable length

VARCHAR is the right choice for the vast majority of use cases. Reserve CHAR for truly fixed-length data like ISO country codes (CHAR(2)) or currency codes (CHAR(3)). Note that in MySQL's InnoDB, CHAR columns are also stored as variable-length (trailing spaces are removed), so the storage difference is minimal.

Common VARCHAR Design Mistakes and Correction Costs

VARCHAR Length Changes During Migration - Risks and Safe Procedures

ALTER TABLE operations to change VARCHAR length in production behave very differently across RDBMS. Understanding the internal mechanics is essential for safe execution.

RDBMSLength Increase (e.g., 100→200)Length Decrease (e.g., 200→100)Notes
MySQL (InnoDB)Maximum byte length stays at 255 bytes or below: metadata-only (instant). Crossing from 255 bytes or below to 256 bytes or above: table rebuild requiredTable rebuild required. Errors if existing data exceeds new lengthUse pt-online-schema-change or gh-ost for large tables
PostgreSQLMetadata-only (instant). No table rewrite, though a brief exclusive lock is held while the statement runsRequires data validation. Errors on constraint violationsWidening is lightweight; narrowing scans the existing values, so the two are not equivalent
SQL ServerMetadata-only (instant)Data validation then metadata changeVARCHAR→VARCHAR(MAX) requires table rebuild
OracleMetadata-only (instant)Data validation then metadata changeBYTE→CHAR semantics change possible via ALTER TABLE MODIFY

Safe procedure for changing VARCHAR length in MySQL:

  1. Check existing data maximum length: SELECT MAX(CHAR_LENGTH(column_name)) FROM table_name;
  2. Determine if the change crosses the 255-byte boundary (crossing triggers a table rebuild).
  3. For large tables (1M+ rows), use pt-online-schema-change or gh-ost for zero-downtime changes.
  4. After the change, run ANALYZE TABLE to update optimizer statistics.

Recommended Lengths by Field Type

FieldRecommended VARCHARRationale
Email254The figure widely adopted in practice as the upper bound for an email address
Username50UI display constraints
Display Name100Multilingual support, including emoji
Name (international)100Accommodates cultures with long names and middle names
Phone Number20E.164 allows at most 15 digits including the country code, plus room for a leading + and separators
URL2048A figure widely used as a practical guideline. Browsers and servers handle longer URLs than this, so allow extra room when storing third-party URLs verbatim
Address Line200International address formats
Product Name200Common e-commerce upper limit
Password HashVARCHAR(60) / CHAR(60)bcrypt hash is fixed at 60 chars. CHAR(60) is optimal
UUIDCHAR(36) / BINARY(16)36 chars with hyphens. Binary storage is 16 bytes and more efficient
  1. When a specification or standard (RFC, ISO, etc.) defines a maximum, match it.
  2. When no specification exists, add 20–50% margin to the maximum observed data length.
  3. Plan for future growth while avoiding excessively large values. In MySQL, be mindful of the 255-byte boundary.
  4. Implement the same character limit validation on the application side to prevent DB mismatches.
  5. For internationalized columns, design based on the longest language/culture, not just your primary locale.

Conclusion

VARCHAR length design requires a holistic consideration of data characteristics, encoding, and RDBMS internal implementation. Instead of defaulting to 255, set lengths with clear rationale to improve storage efficiency, query performance, and data quality. In MySQL, pay special attention to the 255-byte prefix boundary, the point at which long values spill to off-page storage, and the impact on index size. Use Character Counter to measure real-world data lengths when designing your schema.

Frequently Asked Questions

What is the maximum VARCHAR length in MySQL?
MySQL allows up to 65,535 bytes, and that budget is shared by all columns in a row. With utf8mb4 (up to 4 bytes per character), a single VARCHAR column can hold at most 16,383 characters, and the practical InnoDB row size limit of about 8,126 bytes constrains multi-column tables further.
How many Japanese characters fit in VARCHAR(255)?
It depends on length semantics: 255 characters in MySQL (utf8mb4) and PostgreSQL, about 85 in Oracle's default BYTE semantics (3 bytes each in AL32UTF8), and about 127 in SQL Server under a Japanese collation, because SQL Server's n counts bytes, not characters. NVARCHAR(255) or Oracle's CHAR semantics restore character-based counting.
Is VARCHAR(255) still a best practice?
No. The 255 convention dates to a pre-MySQL 5.0 length-prefix limitation. Choose lengths from specifications (for example 254 for email per RFC 5321) or from observed data plus a margin, and remember that in MySQL utf8mb4 just 8 VARCHAR(255) columns can exceed the InnoDB row size limit.
Should I use VARCHAR or TEXT?
In PostgreSQL there is effectively no difference, and unconstrained TEXT is idiomatic. In MySQL, VARCHAR supports full indexes and in-memory sorting while TEXT does not, so prefer VARCHAR for searchable columns. In SQL Server, VARCHAR(MAX) replaces the deprecated TEXT type for long strings.

Share this article