MySQL 8.0 Character Set Decision: utf8mb4, utf8mb3, or latin1?
Choose utf8mb4 for new MySQL 8.0 InnoDB tables, avoid utf8mb3 truncation of emoji, and validate with SHOW VARIABLES and HEX().
21 Oct 2025, 10:46 UTC

The problem: MySQL "utf8" is not UTF-8
You insert an emoji or another four-byte Unicode character into a MySQL table, and the value is silently truncated or replaced with a question mark. The cause is often MySQL's utf8 identifier. Despite the name, utf8 is an alias for utf8mb3, which supports only the Basic Multilingual Plane and cannot store four-byte UTF-8 sequences such as emoji.
Useful takeaway: for new MySQL 8.0 InnoDB tables, standardize on utf8mb4 with collation utf8mb4_0900_ai_ci. Reserve utf8 or latin1 only for legacy schemas with known constraints.
Decision and constraints
Decision: Use utf8mb4 / utf8mb4_0900_ai_ci for new tables unless a specific legacy requirement overrides it.
Constraints:
- MySQL 8.0 defaults to
character_set_server=utf8mb4andcollation_server=utf8mb4_0900_ai_ci. utf8mb3is deprecated and may be removed in a future release.- A character set defines how text is encoded; a collation defines sorting and comparison rules.
- Supplementary-plane characters include emoji and some rare CJK ideographs.
Supported options compared
| Character set | Bytes per character | Unicode coverage | MySQL 8.0 status | Best for |
|---|---|---|---|---|
utf8mb4 | 1–4 | Full Unicode, including supplementary planes | Default; recommended | New applications |
utf8 (utf8mb3) | 1–3 | Basic Multilingual Plane only | Deprecated | Legacy schemas only |
latin1 | 1 | Western European repertoire | Supported; limited repertoire | Legacy Western European data |
Trade-offs to evaluate
Storage and index keys
utf8mb4 can use up to four bytes per character, while latin1 uses one and utf8mb3 uses up to three. That extra storage matters most for indexed columns. InnoDB index key length limits are measured in bytes, so a long VARCHAR column consumes more of its budget under utf8mb4. Verify limits for your row format before indexing very long text columns.
Sort order and comparison semantics
Changing collation can change ORDER BY, GROUP BY, LIKE, and uniqueness behavior. Retest representative queries after conversion.
Client character-set mismatch
A table declared as utf8mb4 does not protect you if the application connection uses a different character set. Verify character_set_client and collation_connection separately.
Implementation: create a new table
Run this in the MySQL client or a migration script connected to the target database. Required permission: CREATE on the schema.
CREATE TABLE user_profiles (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
display_name VARCHAR(100) NOT NULL,
bio TEXT,
PRIMARY KEY (id)
) ENGINE=InnoDB
CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;
Expected check:
SHOW CREATE TABLE user_profiles;
The statement should end with CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci. Risk: none for a brand-new table.
Implementation: convert an existing table
Run this in the MySQL client. Required permission: ALTER on the table.
ALTER TABLE user_profiles
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;
CONVERT TO changes the table and its character-based columns. It rebuilds the table, so plan for temporary storage and lock time. Test on a replica first. Because this operation changes state, keep a backup before running it.
Expected check:
SHOW CREATE TABLE user_profiles;
Confirm CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci, then inspect information_schema.COLUMNS for per-column character set and collation.
Validation
- Check server, database, and connection defaults.
SHOW VARIABLES WHERE Variable_name IN (
'character_set_server','collation_server',
'character_set_database','collation_database',
'character_set_client','collation_connection'
);
Expect utf8mb4 and utf8mb4_0900_ai_ci for newly created objects.
- Insert and round-trip a four-byte character. The emoji U+1F600 (😀) encodes as
F0 9F 98 80in UTF-8.
INSERT INTO user_profiles (display_name) VALUES ('😀');
SELECT HEX(display_name) FROM user_profiles WHERE display_name = '😀';
Expected result: F09F9880. A replacement character would appear as EFBFBD, and truncation would return fewer bytes or no row.
- Run the query workload. Execute representative
ORDER BY,GROUP BY, andLIKEstatements before and after conversion to detect sort-order or cardinality regressions.
Limitations and practical checks
- Storage growth. Compare
DATA_LENGTHandINDEX_LENGTHininformation_schema.TABLESbefore and after conversion. - Index key limits. Long indexed
VARCHARorVARBINARYcolumns are more likely to approach InnoDB index key limits underutf8mb4. Verify limits for your target row format and MySQL version. - Connection mismatch. Set the application connection to
utf8mb4(for example,SET NAMES utf8mb4or the equivalent driver option) so client and server agree. - Rollback is destructive for supplementary-plane data. If you convert
utf8mb4data containing emoji back toutf8mb3orlatin1, those four-byte values cannot round-trip and will be lost or replaced. Only roll back after confirming no supplementary-plane data exists, or restore from backup instead.
When to deviate
Use latin1 only when storing exclusively Western European text under strict storage constraints and when every client in the stack is already configured for latin1. Use utf8mb3 only when maintaining a legacy schema that cannot be converted yet; do not choose it for new development.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.