How to make MySQL handle UTF-8 properly
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
If you want MySQL to handle UTF-8 properly, the real goal is usually utf8mb4, not MySQL's older utf8 character set. utf8mb4 supports the full Unicode range, including emoji and other four-byte characters, so the fix is not just one setting in one place. The server, database, tables, columns, and client connection all need to agree.
Why utf8 Is Not Enough
MySQL's historical utf8 character set stores only up to three bytes per character. That means many real Unicode characters, especially emoji and some less common symbols, cannot be stored correctly there.
For full UTF-8 handling, use:
- character set
utf8mb4 - an appropriate
utf8mb4collation
If you leave even one important layer on the old character set, you can still get truncated text, question marks, or collation surprises.
Set the Database Defaults
Start by creating or converting the database to utf8mb4:
For an existing database:
This sets the default for new objects, but it does not automatically fix every existing table and column.
Convert Existing Tables and Columns
To convert a table:
This is important because a database default alone does not rewrite old table definitions. If the table or a specific text column still uses an older character set, inserts can still fail or store corrupted values.
Check the current table definition when debugging:
Make the Client Connection Use utf8mb4
Even when the schema is correct, the client connection can still break things if it negotiates the wrong character set. In JDBC, specify the connection clearly:
In modern MySQL setups, the better practical goal is that the server and driver both operate with utf8mb4 support end to end. Depending on the driver version, explicit connection properties may or may not be necessary, but mismatched connection encoding is still a common source of trouble.
For a session-level sanity check:
That tells you what the server and the current connection are actually using.
Server Defaults Matter Too
If new databases and connections should default to utf8mb4, configure the MySQL server accordingly in its config file:
This reduces the chance that new schemas are created with legacy defaults by accident.
Index and Length Considerations
Switching to utf8mb4 increases the maximum bytes per character. That can affect index sizes on older schemas. If a migration fails on indexed VARCHAR columns, inspect the index definitions rather than assuming the conversion itself is wrong.
In modern MySQL versions this is usually easier than it once was, but the principle still matters: full Unicode support has storage implications.
Common Pitfalls
The biggest mistake is using MySQL's old utf8 and assuming it means full UTF-8. It does not.
Another issue is changing the database default but forgetting existing tables and columns. Old schema objects keep their original character sets until converted.
Developers also overlook the client connection. A correct table definition cannot fully protect you from a misconfigured connection encoding.
Summary
- Use
utf8mb4, not MySQL's olderutf8, for proper full-Unicode support. - Configure the database, tables, and text columns consistently.
- Make sure the client connection also uses the expected encoding.
- Check server and session character-set variables when debugging.
- Remember that existing schema objects must be converted explicitly, not just future defaults.
Related reading
- How to make OleDb code run asynchronous?
- how to make oracle UTL_HTTP.request asynchronous?
- How to make primary key as autoincrement for Room Persistence lib
- How to make Sequelize use singular table names
- How to make Spring server to start even if database is down?
- How to manually create a mdf file for localdb to use?
- How to map a composite key with JPA and Hibernate?
- How to model dimension tables in TiDB?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.