How URL Percent-Encoding Actually Works

Percent-encoding exists to solve one specific problem: URLs have to be made of a limited, predictable set of characters, but the data people put in them almost never is.

URLs can only safely contain a limited character set

Characters like spaces, accented letters, and non-Latin scripts are not part of the safe character set defined for URLs, and certain punctuation marks have special structural meaning within a URL's syntax, so both categories need to be converted before they can appear literally.

Reserved characters have syntactic meaning and must be encoded when used as literal data

Characters like &, =, ?, #, and / define the structure of a URL (separating query parameters, marking a fragment, and so on). If one of these characters needs to appear as literal data inside a value rather than as structure, it must be percent-encoded so it is not misread as part of the URL's syntax.

Unreserved characters never need encoding

Letters, digits, and a handful of symbols (-, ., _, ~) are always safe to use directly in a URL and are never percent-encoded, since they carry no special structural meaning and fall within the universally safe character set.

The %XX format represents one encoded byte in hexadecimal

Percent-encoding a character means converting it to its byte representation (using UTF-8) and writing each byte as a percent sign followed by two hexadecimal digits β€” a space becomes %20 because 0x20 is the space character's byte value in ASCII/UTF-8.

Non-Latin characters often encode to multiple %XX groups

A single character outside the basic ASCII range, such as a Korean, Japanese, Chinese, or accented Latin character, is typically represented by two to four bytes in UTF-8, so it becomes two to four separate %XX sequences β€” which is why an encoded URL containing non-English text looks disproportionately long.

A space can appear as either %20 or +, depending on context

%20 is the generic percent-encoding for a space anywhere in a URL. The + symbol as a stand-in for a space is a separate, older convention specific to form submissions encoded as application/x-www-form-urlencoded, not a universal rule for all URLs.

What percent-encoding is actually solving

A URL is ultimately meant to be a compact, transportable piece of text that works reliably across browsers, servers, email clients, and countless other systems, many of which historically only handled a narrow set of ASCII characters safely. Percent-encoding converts anything outside that safe set, plus any reserved character being used as literal content, into a standardized %XX format based on the character's UTF-8 byte representation, guaranteeing the resulting string is unambiguous and safe to pass around regardless of what system handles it.

The mistakes that actually break encoded URLs

Double-encoding β€” running percent-encoding on a string that has already been percent-encoded β€” is one of the most common real-world bugs, since it turns an existing % into %25, silently corrupting the URL in a way that is not obvious just by looking at it. The other frequent mix-up is treating + and %20 as interchangeable everywhere; + only means "space" inside form-encoded query data, and using it in a URL path or elsewhere can be misread as a literal plus sign instead of a space.

Frequently Asked Questions

Why does a single Korean, Japanese, or Chinese character turn into a long string of percent signs when encoded?

Because those characters fall outside the basic ASCII range and are represented by multiple bytes in UTF-8 β€” commonly three bytes each for many CJK characters β€” and every one of those bytes gets its own separate %XX sequence, so a short string of non-Latin text can expand into a much longer encoded string.

What is the actual difference between %20 and + for representing a space?

%20 is the general-purpose percent-encoding for a space and is valid anywhere in a URL. The + symbol representing a space is a narrower, older convention that only applies within application/x-www-form-urlencoded form data, so using + outside that specific context can be misinterpreted as a literal plus character.