X Xerobit

Character Limits Cheatsheet: Every Limit That Matters for Developers

Meta titles, descriptions, Twitter, SMS, Open Graph, HTTP headers, SQL identifiers — every character limit you'll actually hit, with the Unicode caveats that will bite you.

Mian Ali Khalid · · 7 min read
Use the tool
Word Counter
Count words, characters, sentences, paragraphs, and lines. Reading time estimate, char-limit indicators for X, LinkedIn, meta titles, and more.
Open Word Counter →

Knowing that Twitter allows 280 characters is one of those facts that sounds simple until you’re building an SMS sender and hitting truncation bugs on emoji, or writing meta descriptions that show up ellipsized in search results. The limits matter, the edge cases matter more, and “character” means something different depending on where you’re counting.

This is the cheatsheet. Use the Word Counter on this site to count characters and words in real time as you write or paste content.

What “character” actually means

Before the limits: a “character” is not a byte, and it’s not always one Unicode code point either.

Bytes vs code points vs grapheme clusters

A byte is 8 bits. ASCII characters are 1 byte each. Beyond ASCII, it depends on the encoding:

  • UTF-8 encodes code points above U+007F in 2–4 bytes. The Euro sign is U+20AC — 3 bytes in UTF-8. Most emoji are 4 bytes.
  • UTF-16 uses 2 bytes for most code points, 4 bytes for anything above U+FFFF (surrogate pairs). JavaScript uses UTF-16 internally, so "😀".length returns 2 in JavaScript.

A Unicode code point is the abstract number (U+0041 = A, U+1F600 = 😀). Most platforms count by code points when they say “characters.”

A grapheme cluster is what a human calls “one character” — the visible unit. The flag emoji 🇩🇪 is actually two code points (U+1F1E9 U+1F1EA). The letter é can be one code point (U+00E9, precomposed) or two (U+0065 + U+0301, base + combining accent). Both look identical. Counting code points instead of grapheme clusters is the bug that causes string truncation to split combining characters.

The practical rules

PlatformWhat they count
Twitter/XUnicode code points (weighted: most are 1, URLs are 23)
SMS (GSM-7)GSM-7 characters (7-bit alphabet, 160 per segment)
SMS (Unicode)UTF-16 code units (70 per segment, 67 with concatenation)
MySQL VARCHAR(n)Characters (code points), not bytes
PostgreSQL VARCHAR(n)Characters (code points)
JavaScript string.lengthUTF-16 code units (emoji count as 2)
Python len(string)Unicode code points
HTTP headersBytes (RFC 7230 requires US-ASCII in header names)

SEO and metadata limits

Meta title (page <title>)

Google typically displays 50–60 characters before truncating with an ellipsis. The real limit is pixel-width — approximately 600px on desktop — so a title made of wide characters (W, M) truncates sooner than one made of narrow characters (i, l, t). The 50–60 character rule is a reasonable proxy.

<title>Character Limits Cheatsheet for Developers — Xerobit</title>
<!-- 55 characters — safe zone -->

Google will rewrite your title if it judges it too short, too keyword-stuffed, or not representative of the page. Writing a title that accurately describes the page’s content matters more than hitting exactly 55 characters.

Meta description

Google truncates snippets at roughly 150–160 characters on desktop, 120 characters on mobile. It’s a soft limit — Google sometimes shows more when the query matches text in the description, sometimes shows less.

<meta name="description" content="Every character limit that matters for
developers — meta titles, SMS, HTTP headers, SQL identifiers, and the Unicode
edge cases that cause real bugs." />
<!-- 159 characters — within the safe range -->

Meta descriptions that are too short (under 70 characters) often get replaced by Google with content extracted from the page body. Descriptions that duplicate the title are also commonly replaced.

Open Graph tags

Open Graph controls the preview cards on Facebook, LinkedIn, Slack, iMessage, and most apps that unfurl URLs.

TagRecommended maxHard limit
og:title60 chars~100 chars before truncation
og:description200 chars~300 chars
og:image8MB file size

LinkedIn and Slack impose their own truncation on top of the Open Graph values. In practice, keep og:title under 60 and og:description under 150 to cover all surfaces.

Social platforms

Twitter / X

ContentLimit
Tweet280 characters
URL (any length)Counts as 23 characters
Username in @mentionCounts toward 280
Poll option25 characters each
Alt text1,000 characters
Bio160 characters
Display name50 characters

Twitter counts Unicode code points, not bytes. Emoji count as 2 code points (surrogate pair range), then Twitter applies weighting. The URL shortener (t.co) wraps every link regardless of original length, costing you exactly 23 characters.

LinkedIn

ContentLimit
Post3,000 characters
Article title150 characters
Article body125,000 characters
Comment1,250 characters
Company description2,000 characters
Profile headline220 characters

LinkedIn preview cards (when you share a URL in a post) pull from Open Graph tags. The preview truncates titles at ~70 characters and descriptions at ~200 characters.

YouTube

ContentLimit
Video title100 characters (70 before truncation in search)
Video description5,000 characters
Description above fold~157 characters before “Show more”
Tag30 characters per tag
Tags total500 characters total
Channel description1,000 characters

For search click-through, write the first 60–70 characters of the title as a standalone, meaningful description of the video. The description’s first 157 characters are the most valuable — they appear in search snippets and the player before the fold.

SMS and messaging

GSM-7 (standard SMS)

GSM-7 is a 7-bit encoding covering the Latin alphabet plus common symbols. A single SMS segment holds 160 GSM-7 characters. When you concatenate multiple segments (long SMS), each segment’s payload drops to 153 characters because 7 characters are used for the User Data Header that tells the handset how to reassemble segments.

Single SMS:    160 characters maximum
Concatenated:  153 characters per segment (multiple segments)

The GSM-7 alphabet includes A–Z, a–z, digits, common punctuation, and a few special characters (£, €, etc.). Characters outside GSM-7 force the message into Unicode mode.

Unicode SMS

When your message contains any character outside GSM-7 — including emoji, smart quotes " ", and non-Latin scripts — the message switches to UCS-2 encoding (effectively UTF-16):

Single Unicode SMS:    70 characters maximum
Concatenated Unicode:  67 characters per segment

This is the trap that silently doubles your SMS cost. A single emoji in a 160-character message turns it into a 2-segment Unicode message. Monitor this if you’re building notification systems — one curly quote from a CMS field can break your SMS budget assumptions.

iMessage, WhatsApp, Telegram

These use internet protocols and have effectively unlimited message length for practical purposes (WhatsApp caps at 65,536 characters, Telegram at 4,096 per message). The character limit concern for these platforms is in the UI/UX layer, not the transport layer.

HTTP and web protocols

HTTP header fields (RFC 9110)

HTTP header names must be ASCII tokens. Header field values are sequences of visible ASCII and whitespace — no hard length limit in the RFC, but in practice:

HeaderPractical limit
Cookie header4,096 bytes per cookie value; browsers limit total cookie header to ~8,192 bytes
Authorization headerNo RFC limit; proxies often reject headers over 8KB
URL lengthNo RFC limit; servers typically enforce 8,192–16,384 bytes; Chrome allows up to ~2MB
User-AgentNo RFC limit; typically 50–200 bytes

Nginx’s default large_client_header_buffers is 4 buffers of 8KB each, meaning any single header over 8KB will be rejected with a 400 or 494.

URL length

There is no URL length limit in RFC 3986. The limits come from implementations:

ContextLimit
Chrome~2,083,000 characters
IE 112,083 characters (the infamous IE limit)
Most web servers8,192–16,384 bytes
Apache default8,190 bytes
Nginx default8,192 bytes

For public-facing URLs, stay under 2,048 characters to avoid IE-era proxies and enterprise software with old limits.

Database identifiers

PostgreSQL

IdentifierLimit
Table name63 bytes
Column name63 bytes
Index name63 bytes
Database name63 bytes

PostgreSQL silently truncates identifiers longer than 63 bytes. You can create a table named a_very_long_table_name_that_exceeds_the_limit_somehow_in_some_edge_case_scenario and PostgreSQL will truncate it at 63 bytes without error. The truncated name is what gets stored; using the full name in queries still works because PostgreSQL truncates the query identifier before looking it up.

MySQL / MariaDB

IdentifierLimit
Table name64 characters
Column name64 characters
Index name64 characters
Database name64 characters
Alias256 characters

MySQL 64 vs PostgreSQL 63 — this difference is irrelevant in practice but worth knowing if you’re writing cross-database migration tooling.

SQLite

SQLite has no documented limit on identifier length and defaults to generous internal limits. In practice: avoid identifiers over 255 characters if you want predictable behavior across SQLite versions.

Ideal content length for SEO

“How long should a blog post be?” is actually two different questions.

For competitive topics

For topics with high search volume and multiple established competitors in the top 10, length correlates with ranking because longer content tends to cover the topic more completely, earn more links, and satisfy more search intents in one document. The practical target for competitive keywords is 1,500–2,500 words.

Beyond 2,500 words, you hit diminishing returns unless the topic genuinely demands more depth (technical references, comprehensive guides). Padding to 3,000 words by repeating yourself doesn’t help — Google’s quality signals reward density, not length.

For informational and long-tail queries

For lower-volume, specific queries (“how to center a div in CSS”), a 500-word post that fully answers the question outperforms a 2,000-word post that buries the answer in filler. 800–1,200 words is typically sufficient for informational queries where the user wants a direct answer.

The actual metric

Word count is a proxy. What matters is whether your post covers the topic better than the current top results. Analyze the top 3–5 results for your target keyword: what questions do they answer, what do they miss, what format do they use? Match depth, exceed quality.

The Word Counter shows your word count and estimated reading time as you write. Aim for a reading time that matches what a reader would actually expect for the topic — 5–8 minutes for a comprehensive technical post, 2–3 minutes for a quick how-to.

The Unicode edge cases you’ll actually hit

Emoji in character-limited fields

A single emoji like 😀 is:

  • 1 grapheme cluster (what a human sees as “one character”)
  • 1 Unicode code point (U+1F600)
  • 4 bytes in UTF-8
  • 2 code units in UTF-16 (JavaScript "😀".length === 2)
  • 1 character as counted by Twitter, most databases, and most APIs

If you’re validating a VARCHAR(160) in MySQL and a user submits a message with emoji, MySQL counts the emoji as 1 character but stores it as 4 bytes. If your column uses utf8 (MySQL’s broken 3-byte UTF-8), emoji will truncate or error. Use utf8mb4 in MySQL.

Zero-width joiners and flags

The family emoji 👨‍👩‍👧‍👦 is 7 code points joined by zero-width joiners (ZWJ, U+200D). Most platforms count this as 1 “character” visually but may count 7 code points internally. Flag emoji (🇩🇪) are 2 regional indicator code points. These wreak havoc on naive substring() calls — you can split a ZWJ sequence and get a broken, invisible partial emoji.

Use grapheme-aware string libraries when truncating user content:

  • Python: grapheme package or \X in regex with the regex module
  • JavaScript: Intl.Segmenter (modern) or the graphemer npm package
  • Ruby: Unicode::DisplayWidth

Further reading


Related posts

Related tool

Word Counter

Count words, characters, sentences, paragraphs, and lines. Reading time estimate, char-limit indicators for X, LinkedIn, meta titles, and more.

Written by Mian Ali Khalid. Part of the Dev Productivity pillar.