UTF-8 stores Unicode text as one to four bytes per character, so software can save English letters cheaply and still handle emoji, Arabic, Hindi, Chinese, and thousands of other symbols. Unicode 16.0 includes 154,998 encoded characters [source: Unicode], and UTF-8 is the standard way many systems turn those characters into bytes.
TLDR: UTF-8 is a variable-length encoding for Unicode. Plain English text uses one byte per character, while characters such as é, €, 字, and 😊 use more bytes. A support team storing 1 million mostly English chat messages may use about half the storage of UTF-16, while still accepting names like Renée and messages like ありがとう. The catch is that one visible character is not always one byte, or even one Unicode code point.
What UTF-8 Actually Does
Unicode gives each character a number called a code point. For example, the letter A is U+0041. The euro sign is U+20AC. The smiling face emoji 😊 is U+1F60A.
Those code points are still abstract numbers. Computers need bytes. That is where UTF-8 comes in. It converts Unicode code points into byte sequences that can be stored in a file, sent through an API, placed in a database, or shown in a browser.
UTF-8 is called variable-length because it does not use the same number of bytes for every character. It uses:
- 1 byte for basic ASCII characters, such as
A,7, and?. - 2 bytes for many Latin accented letters, Greek letters, Cyrillic letters, and more.
- 3 bytes for many Asian scripts and common symbols.
- 4 bytes for characters outside the Basic Multilingual Plane, including many emoji.
Why ASCII Still Matters
UTF-8 was designed to keep old ASCII text working. This is a huge reason it spread so widely. Every ASCII byte from 0x00 to 0x7F means the same thing in UTF-8.
That means the word cat is stored as:
c=0x63a=0x61t=0x74
So cat takes exactly 3 bytes. No extra padding. No special marker. Old tools that handle ASCII often behave well with UTF-8, at least for plain English text.
Honestly, it feels like text encoding should have stopped being annoying years ago. Yet one bad setting in a CSV export can still turn café into café, wasting twenty minutes on a problem that looks like data corruption but is really an encoding mismatch.
How Bytes Are Chosen
UTF-8 uses bit patterns to show how many bytes belong to a character. The first byte tells the decoder what to expect.
| Range | Byte Count | Pattern | Example |
|---|---|---|---|
U+0000 to U+007F |
1 | 0xxxxxxx |
A |
U+0080 to U+07FF |
2 | 110xxxxx 10xxxxxx |
é |
U+0800 to U+FFFF |
3 | 1110xxxx 10xxxxxx 10xxxxxx |
字 |
U+10000 to U+10FFFF |
4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
😊 |
Continuation bytes always start with 10. This makes UTF-8 fairly easy to scan. If software lands in the middle of a byte sequence, it can often move backward or forward until it finds a valid starting byte.
A Simple Encoding Example
Take the character é. Its Unicode code point is U+00E9. In binary, that is 11101001. Since it is above U+007F, it cannot fit in one UTF-8 byte.
UTF-8 stores it using two bytes:
1100001110101001
In hexadecimal, that is C3 A9. If a program reads those bytes as UTF-8, it displays é. If it reads them as another encoding, the output may become é. That ugly result is called mojibake.
Characters, Code Points, and What People See
A common trap is assuming one visible character equals one code point. It often does, but not always.
For example, é can be stored as a single code point, U+00E9. It can also be stored as e plus a combining accent: U+0065 followed by U+0301. Both may look the same on screen.
Emoji can be even trickier. A family emoji may contain several people, skin tone marks, and joiner characters. It appears as one symbol, but it may contain many code points and many UTF-8 bytes.
This matters for search, validation, usernames, passwords, database limits, and text counters. A field that allows “20 characters” needs a clear rule. Does that mean bytes, code points, or user-perceived characters? The wrong answer can break forms in quiet, irritating ways.
Why UTF-8 Won
UTF-8 became popular because it solves several problems at once. It is compact for English and many programming files. It supports every Unicode character. It avoids null bytes for ordinary ASCII text, which helped older C-based systems. It also works well in web pages, JSON, XML, logs, and source code.
For mostly English content, UTF-8 is usually smaller than UTF-16. For text made mostly of Chinese, Japanese, or Korean characters, UTF-16 may use fewer bytes. Still, UTF-8 often wins because mixed-language systems need one practical default. Web servers, APIs, editors, and databases are less painful when they agree on one encoding.
Common UTF-8 Problems
- Wrong decoding: Bytes saved as UTF-8 are read as Windows-1252 or another legacy encoding.
- Bad database settings: A database column accepts text, but not full 4-byte UTF-8, so emoji fail.
- Byte limits: A system allows 255 bytes, not 255 visible characters.
- Normalization issues: Two visually identical strings use different code point sequences.
- Unexpected BOM: Some UTF-8 files begin with a byte order mark, which can confuse older tools.
The practical fix is simple: store, transmit, and read text as UTF-8 everywhere unless there is a strong reason not to. Database tables, HTTP headers, HTML meta tags, CSV imports, and source files should all agree.
FAQ
- Is UTF-8 the same as Unicode?
- No. Unicode defines characters and code points. UTF-8 defines how those code points are stored as bytes.
- How many bytes does a UTF-8 character use?
- It uses 1 to 4 bytes. ASCII characters use 1 byte. Many emoji use 4 bytes.
- Why does broken text like é appear?
- That usually means UTF-8 bytes were decoded with the wrong character encoding.
- Does UTF-8 support every language?
- It can encode every character in Unicode, which covers modern scripts, many historic scripts, symbols, and emoji.
- Should databases use UTF-8?
- Usually, yes. For MySQL, full Unicode support normally requires
utf8mb4, not the older limitedutf8setting.
