The idea: one int, two byte orders

Memory is a row of bytes, each with its own address. A 32-bit integer such as 0x12345678 needs four of them, so the CPU must pick an order. Big-endian puts the most significant byte, 12, at the lowest address, the way we write the number. Little-endian puts the least significant byte, 78, there. The page runs the same operations on both, in lockstep: each Step moves one byte in each lane, and a byte keeps its colour (orange for the most significant, blue for the least) wherever it goes.

The int 0x12345678 stored at addresses 0x100 to 0x103. Little-endian memory holds 78, 56, 34, 12; big-endian memory holds 12, 34, 56, 78. So address 0x100 holds the low byte 78 in little-endian and the high byte 12 in big-endian.
The same value, two layouts: little-endian starts with the low byte, big-endian with the high byte.

Little-endian: the low byte first

x86 and x86-64 are little-endian, and so are ARM and RISC-V as they are almost always run (ARM can switch, but Linux, Android, iOS and Windows on ARM all use little-endian). So the computer you are reading this on is almost certainly little-endian. One nice property: the value starts at the same address at every width. The byte at the int's address is its low byte, so reading the int 42 as one byte still gives 42 (Demo: read 1 byte of the int 42 at its address). Adding long numbers byte by byte also starts at the lowest address and carries upward.

Big-endian: the high byte first

Big-endian is network byte order: the IP, TCP and UDP headers, DNS and most binary protocols send the most significant byte first. Java's DataOutputStream and ByteBuffer default to it, as do PNG and JPEG headers, and IBM's s390x and older SPARC and PowerPC machines. Its nice property is that a hex dump reads like the number: 12 34 56 78 (Demo: store 0x12345678).

On one machine, the order never shows

A CPU reads memory in the same order it writes it. Store an int, load it back, and both lanes get 0x12345678 (Demo: store, then load it back). Endianness only matters when the bytes are looked at in a different way than they were written: sent to another machine, written to a file, or read through a pointer of another width.

Sending ints: htonl and ntohl

write(sock, &x, 4) sends the 4 bytes in address order. From an x86 machine that is 78 56 34 12, and a reader that follows the protocol (big-endian) decodes 0x78563412 (Demo: send without htonl). The fix is htonl ("host to network, long") before sending and ntohl after receiving. On a little-endian CPU it is one bswap instruction; on a big-endian CPU it does nothing, so the same source code is right on both (Demo: send with htonl). The 16-bit versions htons/ntohs are used for port numbers.

Two rows. Without htonl: an x86 sender's memory 78 56 34 12 goes on the wire as 78 56 34 12 and the big-endian reader gets 0x78563412, marked wrong. With htonl: bswap turns the register into 0x78563412, memory becomes 12 34 56 78, the wire carries 12 34 56 78 and the reader gets 0x12345678, marked right.
Sending an int's raw bytes from x86 reverses it at the other end; one htonl before the write fixes it.

What each order makes easy

Little-endianBig-endian
Wherex86, x86-64, ARM, RISC-V (almost every CPU today)Network protocols, Java streams, many file formats, s390x
Byte at the lowest addressleast significantmost significant
Hex dump of 0x1234567878 56 34 12 (reads reversed)12 34 56 78 (reads like the number)
Read a smaller width at the same addresssame value if it fits ✓gets the top part ✗
Sending to the networkneeds htonl (1 swap)already in order (0 swaps)
Compare as bytes (memcmp) gives numeric ordernoyes, for unsigned values

Neither order is faster on its own; a CPU wires its loads to one of them. What costs time is converting, and that is one cheap instruction. Big-endian keys sort correctly as byte strings, which is why databases and key-value stores (for example, LSM-tree keys) often encode integers big-endian even on x86.

Common mistakes

  • "Endianness reverses the bits." It orders bytes. The bits inside a byte are the same on both: 0x78 is 0111 1000 everywhere.
  • Swapping strings. A UTF-8 or ASCII string is a list of single bytes, so it has no byte order. Only multi-byte numbers do (and UTF-16 text, which is why it has a byte-order mark).
  • Swapping twice. Calling htonl on a value that is already in network order breaks it again. Convert once, at the edge where the bytes enter or leave.
  • Casting a byte buffer to int *. It works on the machine you test on and breaks on the other order (and may be misaligned). Decode the bytes with shifts, or with ntohl/be32toh.

See also Number Bases for hex and bytes, Floating Point for another multi-byte number (a double has a byte order too), and TCP Sockets for the bytes on the wire.

What the page leaves out

Only 32-bit ints are shown; 16-bit and 64-bit values work the same way with 2 and 8 bytes. It leaves out mixed orders such as the PDP-11's "middle-endian" 34 12 78 56 and the word-swapped doubles of old ARM, bi-endian CPUs that can switch at run time, bit order on serial links (which is a separate question), alignment, and the endian-independent formats that sidestep the issue: text formats like JSON, and varints in Protocol Buffers.