TL;DR, Quick Answer
8 min readThreads text posts are capped at 500 characters, and Meta counts each emoji as its number of UTF-8 bytes rather than as one character. A grinning face costs 4, a skin-toned pointing hand costs 8, and a four-person family emoji costs 25. That is why a post your character counter calls 475 characters can be rejected by Threads at 517.
What is the Threads character limit?
Meta sets the Threads character limit at 500 characters for text posts, and counts each emoji as its number of UTF-8 bytes instead of as a single character. Both rules sit in the Threads API documentation under Single thread posts, in a two-bullet list Meta labels Limitations. For scale, Bluesky caps a post at 300 graphemes and Mastodon documents a 500-character default, so the raw number is unremarkable and the counting method is where Threads differs.
The 500 figure shows up in two places in Meta's docs. The emoji rule shows up in only one of them. Anyone who reads the overview page and stops there walks away with half the spec.
| Limit | Documented value | Meta's page |
|---|---|---|
| Text post length | 500 characters | Posts, Overview |
| Emoji counting | Number of UTF-8 bytes | Posts |
| Carousel children | Minimum 2, maximum 20 | Posts, Overview |
| Links per post | 5 or fewer | Posts |
| Topic tag length | 1 to 50 characters | Posts |
| Published posts | 250 per 24-hour moving period | Overview |
| Replies | 1,000 per 24-hour moving period | Overview |
| Deletions | 100 per 24-hour moving period | Overview |
| Location searches | 500 per 24-hour moving period | Overview |
Why do character counters disagree with Threads?
Character counters disagree with Threads because they count an emoji as one character and Threads counts it as several. Meta's sentence is short enough to quote in full: "Emojis are counted as the number of UTF-8 bytes." The same note is repeated on the text parameter row of the POST /{threads-user-id}/threads endpoint, worded as "For the post character limit, emojis are counted as the number of UTF-8 bytes."
That is the whole explanation Meta gives, and it is where the documentation starts arguing with itself. The phrase "number of UTF-8 bytes" is a hyperlink, and it points at the npm package grapheme-splitter. A grapheme splitter groups code points into what a reader sees as one character. It has nothing to do with byte lengths. So the docs tell you to count bytes and then link to a tool that counts the opposite unit, with no sentence connecting the two.
The reconciliation is left to you. Split the string into graphemes first, which is what the linked package does, then charge each emoji grapheme its UTF-8 byte length rather than 1. Meta never spells that out. Every counter that skips the second half reports a number that is too small, and every counter that applies the byte rule to the whole string reports a number that is too large for accented or non-Latin copy.

How many characters does one emoji cost on Threads?
An emoji costs between 3 and 25 against the Threads character limit, depending on how many code points it is built from. Emoji outside the Basic Multilingual Plane take 4 bytes each. The variation selector U+FE0F that turns a symbol into color emoji takes 3. The zero width joiner U+200D that welds parts together takes 3. Skin tone modifiers take 4.
| Emoji | Code points | Counters say | Threads counts |
|---|---|---|---|
| β¨ | U+2728 | 1 | 3 |
| β | U+2705 | 1 | 3 |
| π | U+1F600 | 1 | 4 |
| π₯ | U+1F525 | 1 | 4 |
| β€οΈ | U+2764 U+FE0F | 1 | 6 |
| ππ½ | U+1F449 U+1F3FD | 1 | 8 |
| π³οΈβπ | U+1F3F3 U+FE0F U+200D U+1F308 | 1 | 14 |
| π©βπ©βπ§βπ¦ | U+1F469 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 | 1 | 25 |
The family emoji is the one that ruins schedules. It reads as a single glyph, it sits in the same emoji picker as the rest, and it eats 5 percent of the post on its own. A rainbow flag costs more than a fourteen-letter word.
A post that passes your counter and fails Threads
Take 470 characters of plain copy and close it with five emoji: π β€οΈ ππ½ π§΅ π©βπ©βπ§βπ¦. A grapheme counter reports 475, comfortably inside the cap, so the post looks safe.
| Segment | Counter | Threads |
|---|---|---|
| Body copy | 470 | 470 |
π U+1F389 | 1 | 4 |
β€οΈ U+2764 U+FE0F | 1 | 6 |
ππ½ U+1F449 U+1F3FD | 1 | 8 |
π§΅ U+1F9F5 | 1 | 4 |
| π©βπ©βπ§βπ¦ | 1 | 25 |
| Total | 475 | 517 |
Threads sees 517 and refuses the post. The gap is 42, and 21 of those come from a single emoji. Swap the four-person family for πͺ U+1F46A, which is one code point and 4 bytes, and the same post drops to 496 and publishes. Nothing about the wording changed.
This is also why three different counters give three different answers for the same string. JavaScript's String.prototype.length reports 491 for that post, because it counts UTF-16 code units. Array.from(post).length reports 483, because it counts code points. A grapheme splitter reports 475. Threads wants 517, and none of the three built-in methods produces it.

How do you count a Threads post the way Threads does?
Count a Threads post by splitting it into graphemes, charging 1 for each ordinary grapheme and the UTF-8 byte length for each emoji grapheme. Intl.Segmenter handles the splitting in the browser and in Node without a dependency.
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
const encoder = new TextEncoder();
const EMOJI = /\p{Extended_Pictographic}/u;
function threadsLength(text) {
let total = 0;
for (const { segment } of segmenter.segment(text)) {
total += EMOJI.test(segment) ? encoder.encode(segment).length : 1;
}
return total;
}
threadsLength(post); // 517Do not reach for Buffer.byteLength(text, 'utf8') as a shortcut. It happens to return 517 for the example above, but only because the body copy is pure ASCII. Run it over "cafΓ©" and it returns 5 where a reader counts 4. Run it over Japanese copy and it triples the count, because each kana is 3 bytes. Meta states the byte rule for emoji and for nothing else.
Which raises the gap Meta has not filled. The docs never define what a character is for the other 500 slots. There is no sentence saying whether "γγγ«γ‘γ―" counts as 5 or 15, whether a combining accent counts as 1 or 2, or whether an ordinary non-ASCII character is measured in code points, graphemes or bytes. If you publish in a language that is not ASCII, the only honest position is that the limit is undocumented at the margin, so leave headroom rather than aiming for exactly 500.
AdaptlyPost
Start 7-Day FREE Trial
All-platform analytics
Social Inbox
AI-powered assistant
What else rejects a Threads post besides length?
Links reject a post before length does. Threads restricts a post to 5 links or fewer, and since December 22, 2025 a post carrying more fails at the media creation step, POST /{threads-user-id}/threads, with the error code THREADS_API__LINK_LIMIT_EXCEEDED. Meta counts unique URLs, so a link_attachment that repeats a URL already in text counts once, while a link_attachment pointing somewhere new adds one to the tally.
Topic tags have their own rule. A tag must be 1 to 50 characters, cannot contain a period or an ampersand, and only the first valid tag in a post is used. In-text tags also terminate at spaces, at signs, exclamation marks, question marks, commas, semicolons and colons, which means a tag written mid-sentence often ends earlier than the author intended.
Carousels are capped at 20 children with a minimum of 2, and Meta is explicit that "Publishing a carousel counts as a single post" against the 250-post quota. You can read your own remaining quota from GET /{threads-user-id}/threads_publishing_limit, which returns quota_usage alongside a config object holding quota_total of 250 and quota_duration of 86400 seconds.
One thing Meta does not publish is a named error for going over 500. There is a documented code for too many links and none for too much text. Since you cannot catch a specific error string, the check has to happen in your own code before the request goes out.
Where adaptlypost fits
adaptlypost publishes to Threads through the API, so the same 500-character rule and the same emoji arithmetic apply to a scheduled post and a hand-typed one. Platform limits belong to Threads. What a scheduler changes is when you find out about them, because a post drafted in a content calendar is checked long before its send time rather than at the moment it fails.
The counting problem gets sharper when one draft goes to several networks at once, which is the normal case in multi-platform posting. The same emoji costs a different amount on each network, so a caption sized for one is not automatically safe on another. If you write captions with the AI caption writer, treat emoji as budget rather than decoration and keep the final flourish short. For scheduling specifically, see the Threads scheduling tool, and for what those posts did afterwards, Threads analytics.
Frequently Asked Questions
Is the Threads character limit 500 characters?
Yes. Meta documents the Threads character limit as 500 characters for text posts, stated in the Limitations list on the Threads Posts page and repeated in the Other Limitations list on the Threads Overview page. The number has not changed in the documentation as of its April 14, 2026 update.
Why does my Threads post get rejected when the counter says I am under 500?
Your counter is charging 1 per emoji and Threads is charging the emoji's UTF-8 byte length. Five emoji can add 40 or more to the real count, so a post a counter calls 475 characters can reach 517 on Threads. Compound emoji built with zero width joiners are the largest offenders at up to 25 each.
How many characters does an emoji use on Threads?
Between 3 and 25. A symbol like β¨ costs 3, a standard emoji like π costs 4, a heart with a variation selector costs 6, a skin-toned hand costs 8, and the four-person family emoji π©βπ©βπ§βπ¦ costs 25. The cost is the sum of the UTF-8 byte lengths of every code point in the emoji.
Does the Threads character limit apply to replies and carousel captions?
Meta documents the 500-character limit for text posts and applies the emoji byte rule to the text parameter on both single posts and carousel containers. Replies have their own separate quota of 1,000 per 24-hour moving period, which is a count of replies rather than a length limit.
What error does Threads return when a post is too long?
Meta does not publish an error code for exceeding 500 characters. The only documented publishing error of this kind is THREADS_API__LINK_LIMIT_EXCEEDED, returned by POST /{threads-user-id}/threads when a post carries more than 5 links. Validate length in your own code before you call the endpoint.
How many posts can a Threads profile publish per day?
- Meta limits a profile to 250 API-published posts within a 24-hour moving period, and a carousel of up to 20 images or videos counts as one post against that total. Query
GET /{threads-user-id}/threads_publishing_limitto readquota_usageagainst aquota_totalof 250.
How can I check my remaining Threads posting quota before I publish?
Call GET /{threads-user-id}/threads_publishing_limit and read quota_usage against the returned config. Meta's config object holds a quota_total of 250 and a quota_duration of 86400 seconds, matching the 24-hour moving window for published posts. Checking this endpoint before you send a batch tells you how much of the day's allowance is already spent.
What happens if a Threads post has more than 5 links?
The post fails at the media creation step, POST /{threads-user-id}/threads, with the error code THREADS_API__LINK_LIMIT_EXCEEDED. This rule has applied since December 22, 2025, and Meta counts unique URLs rather than every link mention, so a link_attachment repeating a URL already in the text counts once. There is no equivalent named error for exceeding the 500-character limit.
How long can a topic tag be on Threads?
A Threads topic tag must run 1 to 50 characters, and it cannot contain a period or an ampersand. Only the first valid tag in a post is used, and an in-text tag ends early if it hits a space, an at sign, or punctuation like an exclamation mark, comma, or colon.
How many images or videos can a Threads carousel hold?
A Threads carousel needs at least 2 children and allows at most 20. Meta counts the whole carousel as a single post against the 250-post daily quota, regardless of how many children it contains.
AdaptlyPost
Start 7-Day FREE Trial
All-platform analytics
Social Inbox
AI-powered assistant
Put this into practice with AdaptlyPost
Was This Article Helpful?
Let us know what you think!
See us more often in Google
One click marks AdaptlyPost as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.
Before you go...
AdaptlyPost
Schedule your content across all platforms
Manage all your social media accounts in one place with AdaptlyPost.
All-platform analytics
Social Inbox
AI-powered assistant
Related Glossary Terms


Three Minutes, Not Sixty Seconds: How Long Can a YouTube Short Be
Most pages say 60 seconds. How long can a YouTube Short be is three minutes, and the music and copyright limits that bite well before that.


Rights Matching on YouTube: What Is Content ID and What a Claim Does
Answered: what is Content ID, why YouTube says only Audio Library music is copyright-safe, and how a claim redirects money instead of hitting your channel.


Make AI Content Creation Work With Human Judgment
Treat AI content creation as a drafting tool and it saves hours. Where it works for social, the guardrails that protect brand voice, and what to fact-check.
Related Articles


Explained Clearly - Batching Means
Context switching is the real cost. What batching means in practice, which tasks group well together, and how one session can cover a whole month.


Explained Clearly - Body Copy
Headlines earn the click; body copy earns the action. How to structure it for ads and social, keep it scannable, and cut it down without losing the argument.


Explained Clearly - Boomerang Meaning
One second of motion looped both ways: the Boomerang meaning, how to shoot one inside Stories, the effects available, and ideas that still feel fresh.

