Graphemes match visible symbols
A grapheme segmenter keeps many emoji sequences and combining marks together as one user-perceived character.
Code points describe Unicode values
A flag emoji can use two regional-indicator code points even though a reader sees one flag.
UTF-16 units matter in JavaScript APIs
Characters outside the basic multilingual plane use surrogate pairs and can make a simple string length larger than the code-point count.
Bytes matter in storage and protocols
UTF-8 uses one to four bytes per code point. A byte limit is not interchangeable with a visible-character limit.
Normalization can change equality without changing appearance
The letter é can be stored as one precomposed code point or as a base letter followed by a combining mark. Those strings can look identical while their code-point and byte totals differ. This counter reports the input as supplied and does not silently normalize it, because normalization could change identifiers, hashes, or protocol payloads. If a destination documents NFC or another normalization form, normalize in that destination's approved workflow and count the exact final value again.
Use all four measures to diagnose a mismatch
Begin with grapheme clusters when the question is how many symbols a reader sees. Compare the code-point and UTF-16 totals when a programming API reports a different length, especially around flags, skin-tone modifiers, family emoji, combining accents, or scripts with joining marks. Use UTF-8 bytes for database, message, and transport limits. Unicode segmentation rules and browser engines evolve, so a consequential boundary should still be tested in the actual form or API that will accept the text.