Big-Endian vs Little-Endian: Byte Order Explained
Endianness decides whether a multi-byte number's most or least significant byte is stored first in memory. Why it matters and how to spot it.
Endianness describes the order in which a computer stores the individual bytes of a multi-byte value in memory — big-endian stores the most significant byte first, at the lowest memory address, while little-endian stores the least significant byte first. A single byte has no order to worry about; the question only comes up once a value spans more than one byte, like a 32-bit integer.
A concrete example
Take the 32-bit hexadecimal value 0x12345678. Stored across four consecutive memory addresses:
| Address | Big-endian | Little-endian |
|---|---|---|
| 0 | 0x12 | 0x78 |
| 1 | 0x34 | 0x56 |
| 2 | 0x56 | 0x34 |
| 3 | 0x78 | 0x12 |
Big-endian reads left to right the same way the number is written on paper — “big end” (most significant byte) first. Little-endian stores the “little end” (least significant byte) first, which reads backward from how humans write the number but has a computational advantage: the address of the value and the address of its least significant byte are always the same, which simplifies certain arithmetic and type-casting operations at the hardware level.
Which architectures use which
Most consumer hardware today is little-endian. The x86 and x86-64 architecture family, which powers the overwhelming majority of desktops, laptops, and servers, has always been little-endian. ARM processors are technically bi-endian — capable of operating in either mode — but are overwhelmingly deployed in little-endian mode in practice, including in phones and Apple Silicon Macs. RISC-V defaults to little-endian as well.
Big-endian shows up mostly in networking rather than general-purpose computing: it’s traditionally called “network byte order” because internet protocol headers — IP, TCP, UDP — specify multi-byte fields like port numbers and addresses in big-endian format, regardless of what endianness the sending or receiving machine’s CPU uses natively.
Why it matters in practice
Endianness is invisible almost all of the time, because a compiler and standard library handle byte order consistently within a single program running on a single machine — you read and write an integer as an integer, and the language runtime deals with the underlying bytes. It becomes visible in a few specific situations:
- Network programming. Since network protocols standardize on big-endian, code that packs raw values into network packets has to explicitly convert from the host machine’s native byte order to network byte order (and back on receipt) — this is what functions like
htons/ntohsin C’s networking APIs exist to do. - Binary file formats. A format’s specification fixes an endianness for its fields. Reading a binary file produced on a machine with different native endianness than the reading machine — or reading a format that doesn’t match your platform’s default — requires explicit byte-swapping, or the values come out scrambled.
- Low-level memory inspection. Anyone reading raw memory or a hex dump directly — debugging with a memory viewer, working with a buffer overflow at the byte level, or parsing a binary protocol by hand — needs to know the target’s endianness to interpret multi-byte values correctly. A 4-byte integer that looks like
78 56 34 12in a hex dump is0x12345678on a little-endian machine, not0x78563412. - Cross-platform serialization. Any format meant to be portable across machines with different native endianness — from network protocols to some file formats — has to pick one byte order and stick to it, converting on both ends, rather than relying on whatever the local CPU happens to use.
Detecting endianness at runtime
Because most application code never touches raw bytes directly, endianness usually only needs to be handled explicitly in lower-level code — parsers, serializers, network stacks — rather than in everyday application logic. Languages that expose raw byte buffers typically provide an explicit way to specify which endianness to read or write in, rather than leaving it to guesswork. A typical pattern in a language with typed array or buffer APIs looks like specifying “read these four bytes as a 32-bit integer, little-endian” or “big-endian” explicitly as a parameter, rather than relying on whatever the host machine happens to default to — which matters precisely because code reading a file or network packet often runs on a different machine, with potentially different native endianness, than the one that wrote it.
A classic runtime trick for detecting a machine’s native endianness (in a language without a direct API for it) is to write a multi-byte integer into a buffer, then read back its first byte: if the first byte holds the least significant byte of the value, the machine is little-endian; if it holds the most significant byte, the machine is big-endian. This is rarely necessary in application code today, but it’s a useful mental model for what endianness actually means at the hardware level — it’s entirely about memory layout, not about the value itself, which is why the same integer can be “correct” under two completely different byte sequences depending on which convention is being used to read it.
Why little-endian won on general-purpose hardware
There’s no universally agreed single reason little-endian became dominant on general-purpose CPUs, but a commonly cited factor is arithmetic convenience: operations like addition process a multi-byte number starting from its least significant byte (where carries originate), and little-endian storage puts that byte at the lowest, most immediately addressable memory location. Whatever the historical reasons, the practical result today is that most software runs its whole life on little-endian hardware and never has to think about endianness at all — until it has to talk to something outside that one machine, whether that’s the network, a file written elsewhere, or hardware that made the opposite choice.
The takeaway
Endianness is a hardware-level detail about which end of a multi-byte value comes first in memory, and it stays invisible as long as a single program on a single architecture reads back what it wrote. It surfaces the moment bytes cross a boundary between systems that might disagree — over a network, through a binary file, or under a debugger — which is exactly why network protocols fixed big-endian as a standard “network byte order” decades ago, so two machines with different native endianness can still agree on how to interpret the bytes between them.
Keep reading
Chisato · · 4 min read What Is Virtual Memory? Paging and Address Translation
Virtual memory gives every process its own private address space, mapped to physical RAM by the OS and CPU — enabling isolation, swapping, and overcommit.
Chisato · · 5 min read What Is Memory Interleaving?
Memory interleaving spreads consecutive addresses across multiple memory banks so the system can access them in parallel instead of one at a time.
Chisato · · 4 min read Speculative Execution Explained: Speed vs Security
Speculative execution lets a CPU guess ahead and run instructions before it knows they're needed, buying speed at the cost of the timing side channels behind Spectre and Meltdown.