UTF-8 vs UTF-16 vs ASCII: Character Encoding Explained

Shah Fahad
Shah Fahad
Technical Lead & AI Systems Architect
July 14, 2026 · 4 min read
Illustration comparing how ASCII, UTF-8, and UTF-16 encode characters into bytes

Every character you read on a screen is stored as a number, and a character encoding is the rulebook that maps those numbers to bytes. ASCII, UTF-8, and UTF-16 are the three you will meet most often. Choosing or mislabeling one is the reason you sometimes see garbled text like é where an é should be. Here is how they differ and why the web settled on UTF-8.

A Quick Vocabulary

First, two terms. Unicode is a giant catalog that assigns a unique number, called a code point, to every character in every writing system, plus emoji and symbols, over 149,000 of them. An encoding (UTF-8, UTF-16) is a scheme for turning those code points into actual bytes. ASCII predates Unicode and is both a character set and its own encoding.

The Three Encodings

ASCII is the original 7-bit encoding from the 1960s. It defines just 128 characters: the English alphabet, digits, punctuation, and control codes. Each fits in a single byte. It is tiny and universal but cannot represent é, ñ, , or an emoji at all.

UTF-8 is a variable-width Unicode encoding using 1 to 4 bytes per character. Its defining trick: the first 128 code points are encoded identically to ASCII in a single byte. So every valid ASCII file is already valid UTF-8. Characters beyond ASCII use 2, 3, or 4 bytes as needed.

UTF-16 is also variable-width but its smallest unit is 2 bytes. Most common characters take 2 bytes; less common ones (including emoji) take 4 bytes via a mechanism called surrogate pairs.

Illustration comparing byte layouts of ASCII, UTF-8, and UTF-16 for the same characters

Byte Sizes and Coverage

Encoding Bytes per character Characters covered ASCII compatible
ASCII 1 (7 bits used) 128 Is ASCII
UTF-8 1 to 4 (variable) All of Unicode Yes, byte-for-byte
UTF-16 2 or 4 (variable) All of Unicode No

The practical consequences:

  • For plain English text, UTF-8 uses 1 byte per character while UTF-16 uses 2, so UTF-8 files are roughly half the size.
  • For scripts like Chinese, Japanese, or Korean, those characters are 3 bytes in UTF-8 but 2 bytes in UTF-16, so UTF-16 can be more compact for CJK-heavy text.
  • Both cover the entire Unicode range, so neither loses characters, only bytes.

A Concrete Example

Consider the letter A, the accented é, and the emoji 😀:

Char   ASCII        UTF-8              UTF-16
A      41           41                 00 41
é      unsupported  C3 A9  (2 bytes)   00 E9
😀     unsupported  F0 9F 98 80        D8 3D DE 00
                    (4 bytes)          (surrogate pair)

ASCII cannot represent the last two at all. UTF-8 uses 1, 2, and 4 bytes respectively, while UTF-16 uses a fixed 2 bytes for the first two and a 4-byte surrogate pair for the emoji.

The Byte Order Mark (BOM)

Because UTF-16 stores 2-byte units, a reader must know the byte order: big-endian (00 41) or little-endian (41 00). A Byte Order Mark, the code point U+FEFF placed at the start of the file, signals which. UTF-16 relies on the BOM (or an external declaration) to be read correctly.

UTF-8 has no byte order to worry about because its unit is a single byte. A UTF-8 BOM exists but is optional and usually discouraged for web files, since it can break scripts and confuse parsers that do not expect it.

Why UTF-8 Won the Web

UTF-8 became the dominant encoding of the internet for a few compounding reasons:

  1. ASCII compatibility. Decades of existing ASCII documents and code were instantly valid UTF-8, so adoption cost almost nothing.
  2. Space efficiency for the web's dominant content. HTML tags, URLs, JSON keys, and English text are all ASCII, so they stay 1 byte each.
  3. No byte-order ambiguity, and therefore no mandatory BOM.
  4. It covers all of Unicode, so one encoding handles every language and emoji.

The HTML5 standard recommends UTF-8, and it is now the declared encoding of the vast majority of websites. UTF-16 remains common in memory inside languages like Java, JavaScript, and C#, but for files and network transport, UTF-8 is the default.

Explore the Bytes

See exactly how characters map to code points and bytes:

Takeaway

ASCII is the 128-character ancestor, limited to 1 byte. UTF-8 and UTF-16 both cover all of Unicode, but UTF-8's variable 1-to-4-byte design stays compact for ASCII text and needs no BOM, which is exactly why it became the web's standard. When in doubt, save and serve your files as UTF-8 without a BOM.

Shah Fahad
Shah Fahad
Technical Lead & AI Systems Architect

Shah Fahad is a technical lead and AI systems architect who builds production AI platforms end to end — from multi-tenant backends and agentic systems to the bare-metal infrastructure they run on.

♥ Enjoying these free tools?

FAHAQ keeps every tool free with no paywalls. Donations help cover the servers and keep it fast and growing — even a couple of dollars makes a difference.

Donate

More from the blog