Database VARCHAR Limits: Characters vs Bytes
Understand how VARCHAR(255) is interpreted differently in PostgreSQL, MySQL, and SQLite, and whether the limit counts characters or bytes.
Detailed Explanation
VARCHAR Limits Across Databases
The meaning of VARCHAR(255) varies significantly between database systems. Some count characters, others count bytes, and the distinction has major implications for international text.
PostgreSQL
PostgreSQL's VARCHAR(n) counts characters (code points):
-- PostgreSQL
CREATE TABLE t (name VARCHAR(5));
INSERT INTO t VALUES ('東京都渋谷'); -- 5 CJK chars: OK
INSERT INTO t VALUES ('東京都渋谷区'); -- 6 CJK chars: ERROR
Even though 5 CJK characters are 15 UTF-8 bytes, PostgreSQL allows them because the character count is within the limit.
MySQL
MySQL's behavior depends on the character set:
With utf8mb4 (recommended):
-- MySQL with utf8mb4
CREATE TABLE t (name VARCHAR(5) CHARACTER SET utf8mb4);
INSERT INTO t VALUES ('東京都渋谷'); -- 5 chars: OK
VARCHAR(n) counts characters. Internally, MySQL reserves up to 4 bytes per character for utf8mb4.
Row size limit:
MySQL has a maximum row size of ~65,535 bytes. With utf8mb4, each VARCHAR character can use up to 4 bytes, so VARCHAR(255) reserves 1020 bytes in the worst case. This limits how many VARCHAR columns you can have per table.
TEXT types count bytes:
TINYTEXT: 255 bytes
TEXT: 65,535 bytes
MEDIUMTEXT: 16,777,215 bytes
LONGTEXT: 4,294,967,295 bytes
SQLite
SQLite's VARCHAR(n) is essentially ignored — SQLite has no length enforcement on TEXT columns. The length in VARCHAR(n) is just a hint:
-- SQLite: no error even if exceeding declared length
CREATE TABLE t (name VARCHAR(5));
INSERT INTO t VALUES ('This is much longer than 5 characters'); -- OK!
Practical Sizing Guide
| Content Type | Recommended Size | Reasoning |
|---|---|---|
| Email address | VARCHAR(320) | RFC 5321 maximum |
| Person name | VARCHAR(100) | Accommodates most cultures |
| URL | VARCHAR(2048) | Practical browser limit |
| Tweet text | VARCHAR(560) | 280 chars × 2 for CJK weight |
| File path | VARCHAR(4096) | Linux PATH_MAX |
| UUID | CHAR(36) or UUID type | Fixed format |
Key Takeaways
- Always use utf8mb4 in MySQL (not utf8, which only supports 3 bytes)
- Check if your DB counts characters or bytes for the specific column type
- Account for multi-byte characters when estimating storage
- Use the String Length Calculator to verify both character and byte counts before setting column sizes
Use Case
When designing database schemas for international applications, understanding how VARCHAR limits work in your specific database prevents data truncation, insertion errors, and storage inefficiencies with multi-byte character sets like UTF-8.