The Complete Guide to SMS Character Counting, Segments & Thread Splitting
What is an SMS character counter — and why 160 is only half the story
An SMS character counter tells you how long your text message is, but the number it shows is only the beginning. Unlike an email or a chat message, an SMS travels over a signaling channel that was designed in the 1980s with hard physical limits. A single SMS can carry 140 bytes of payload. How many characters fit into those 140 bytes depends entirely on the alphabet your phone uses to encode the message. Type a plain English message and you get the generous GSM-7 alphabet: 160 characters per message. Slip in a single emoji, a curly smart quote, or an em dash, and the entire message silently switches to UCS-2 encoding — and your limit collapses to just 70 characters. That is why a free, accurate SMS character counter like SegText matters: it does not just count characters, it replicates the exact encoding decision your carrier's SMSC will make.
Most naive counters get this wrong. They count JavaScript string length and call it a day. But carriers do not bill you for string length — they bill you for septets and code units, for extension-table escape sequences, and for User Data Header overhead on every part of a concatenated message. A message that looks like 161 characters on a naive counter might actually consume 162 septets because it contains a euro sign. SegText implements the real GSM-7 default alphabet from the 3GPP TS 23.038 specification, including all nine extension-table characters that cost two septets each, so the numbers you see here match what your gateway will charge you for.
GSM-7: the 160-character alphabet
GSM-7 is a 7-bit character set, which means each character is packed into 7 bits instead of 8. Eight of those 7-bit characters fit into 7 bytes, and 160 of them fit into the 140-byte SMS payload (160 × 7 bits = 1120 bits = 140 bytes — the math is exact). The alphabet covers basic Latin letters, digits, common punctuation, and a handful of accented characters like è, é, ü, ñ, and å. It also includes currency symbols that surprise many developers: the pound sign £, the yen sign ¥, and the generic currency sign ¤ are all GSM-7 safe. The euro sign €, on the other hand, lives in the extension table and costs two septets — a classic billing trap for European marketers.
The extension table is GSM-7's hidden surcharge. Nine characters — the form feed, caret ^, curly braces { }, backslash \, square brackets [ ], tilde ~, pipe |, and the euro sign € — are encoded as an escape character followed by the character code. Each one consumes two of your 160 septets. A marketing message full of brackets and tildes can lose a dozen billable units without containing a single exotic character. SegText flags every extension-table character it finds so you can see exactly where your septets are going.
UCS-2: the 70-character fallback
The moment your message contains any character outside the GSM-7 alphabet — an emoji, a smart quote, Chinese or Arabic script, even a humble ellipsis … — the entire message is re-encoded as UCS-2. Each character now takes 16 bits, so only 70 characters fit in the 140-byte payload. Worse, the switch is all-or-nothing: one emoji in a 150-character message does not just cost extra for the emoji, it converts all 150 characters to 16-bit encoding and blows the message up to three segments. This is the single most expensive mistake in bulk SMS, and it is invisible on phones and in most marketing dashboards.
There is an important subtlety in how UCS-2 characters are counted. Characters outside the Basic Multilingual Plane — which includes virtually all emoji — are stored as UTF-16 surrogate pairs, consuming two 16-bit code units each. So a message with 35 emoji has used all 70 of its units. SegText counts UCS-2 in code units exactly like the carriers do, so an emoji-heavy message shows its true size, not a flattering underestimate.
SMS segment calculator math: 160/153 and 70/67
When a message exceeds one segment, it is sent as a concatenated SMS: several segments that the receiving phone reassembles. Each segment after the first needs a 6-byte User Data Header (UDH) so the phone knows the order of the parts and which message they belong to. Those 6 bytes come out of your 140-byte payload. For GSM-7, 6 bytes equals 48 bits, which is just under 7 septets — so each concatenated segment holds 153 characters instead of 160. For UCS-2, 6 bytes equals exactly 3 code units, leaving 67 characters per segment instead of 70. A 161-character GSM-7 message therefore becomes two segments of 153, billed as two messages. This is why the 160-to-161 boundary is the most expensive single character in SMS marketing.
A proper SMS segment calculator must also handle the exact boundary conditions. Exactly 160 GSM-7 septets is one segment with zero characters left; 161 septets is two segments with 145 characters left in the second. Exactly 306 septets is two full segments; 307 starts a third. SegText computes segments, per-segment capacity, and remaining characters with these exact rules, and its segment map visualizes how your message is sliced — including mid-word splits, because carriers split on septet boundaries, not on word boundaries.
Unicode traps: the characters silently doubling your bill
The cruelest SMS billing surprises come from characters you cannot even see. Word processors and phones love to "help" by replacing straight quotes with curly ones (“ ” ‘ ’), hyphens with en and em dashes (– —), and three dots with a proper ellipsis (…). Every one of these forces UCS-2. Zero-width spaces, byte-order marks, and non-breaking spaces pasted from web pages are invisible and equally destructive. SegText's unicode-trap optimizer scans your message for all of these, names each offender, and suggests a GSM-7-safe replacement: curly quotes become straight quotes, em dashes become hyphens, the degree sign becomes the word "deg", and common emoji become ASCII emoticons like :) or text like [ok].
The optimizer shows a before-and-after segment comparison, so the savings are concrete rather than theoretical. In practice, cleaning the traps out of a typical pasted marketing message often drops it from two or three UCS-2 segments back to a single GSM-7 segment — cutting the cost of that campaign by half or more with zero change to the message's meaning. The fixes are applied to your text with one tap, and every replacement is shown before you commit, so nothing is rewritten behind your back.
How SMS pricing works: the cost estimator
SMS gateways, aggregators, and carriers bill per segment, not per message. A "message" of 300 GSM-7 characters is billed as two segments; a 75-character message containing one emoji is billed as two segments as well, because it crosses the 70-unit UCS-2 boundary. Promotional SMS in India typically costs around ₹0.12 to ₹0.25 per segment on domestic routes, while international termination can cost several rupees or tens of cents per segment depending on the destination. These rates multiply fast: a 10,000-recipient campaign at two segments instead of one doubles the entire campaign budget.
SegText's cost estimator takes the live segment count from your message and multiplies it by whatever per-segment rate you enter, in your choice of currency. Change the message, and the total updates instantly. It is the fastest way to answer the question every SMS marketer eventually asks: "how much will this exact text cost me to send?" Use it while drafting to keep campaigns inside a single segment, and use the trap optimizer alongside it to squeeze multi-segment drafts back down.
Thread splitters for X, Threads and Bluesky
A tweet thread splitter solves a different but related problem: social platforms limit each post's length — 280 characters on X (Twitter), 500 on Threads, and 300 on Bluesky — and long-form posts must be divided into a numbered thread. Doing this by hand is tedious and error-prone: split mid-word and the thread looks sloppy; miscount the prefix and a post overflows the limit. SegText's thread splitter divides your text at word boundaries, never breaking a word unless a single word is longer than the limit, and prefixes every chunk with a numbered marker like (1/5).
The numbering is smarter than it looks. The prefix itself consumes characters, so the splitter first estimates how many chunks there will be, reserves space for the longest prefix, and re-packs if the digit count changes the total — guaranteeing that no chunk, prefix included, ever exceeds the platform limit. Each chunk shows its own character count so you can verify at a glance, and one-tap copy buttons let you post the thread in order without retyping. Whether you call it a tweet thread splitter, a thread maker, or a long-post divider, the goal is the same: a clean, professional thread with zero manual counting.
Seven habits that keep SMS in one segment
First, draft in plain text and paste into SegText before you paste into your gateway — word processors inject curly quotes by default. Second, watch the encoding badge: the moment it flips from GSM-7 to UCS-2, find the culprit with the trap scanner. Third, remember the extension-table nine: ^ { } \ [ ] ~ | € and the form feed each cost double, so use them sparingly in tight messages. Fourth, respect the 160/153 cliff — if you are at 158 septets, you have room for two more characters, not twelve. Fifth, shorten URLs with a link shortener before counting, since every character of a long URL burns septets. Sixth, put opt-out language and branding after the core message so truncation, if it ever happens, cuts the least important part. Seventh, price every campaign draft with the cost estimator; a message that is "just a bit over" one segment is the most expensive kind of draft to approve.
How to use SegText
Type or paste your message into the candybar phone above and watch the LCD update live: encoding, segment count, billable units, characters remaining, and a visual segment map. Press OPTIMIZE or open the Unicode-Trap Optimizer to scan for UCS-2-forcing characters and apply GSM-7-safe fixes with a before-and-after segment comparison. Enter your gateway's per-segment rate in the Cost Estimator to price the message instantly. For social posts, paste your long text into the Thread Splitter, choose X, Threads, or Bluesky, and copy the numbered chunks in order. Everything runs entirely in your browser — your messages are never uploaded, stored, or sent anywhere.