Guide

To a computer, everything is bytes. A number, a name, a timestamp and an emoji are all sequences of 8-bit values. The meaning comes from the encoding that both sides agree on. When they disagree, or when the encoding cannot hold what you gave it, you get some of the most common bugs in software. A counter goes negative. A bill is off by a cent. A customer's name shows as José. A report is wrong for one hour every March.

These bugs rarely appear in tests, because test data is small, ASCII, in UTC and in dollars. They appear in production when a counter passes 2^31, a customer pays in yen, a name has an accent, or the clocks change. This topic shows how each representation works and where it breaks.

The big idea

Every value has a fixed format, and the format sets its limits. An integer has a range. A float has a number of significant digits. A text string has a length, and that length depends on which unit you count. A timestamp names a moment, but it also depends on a place and a calendar.

The safe habit is to know the format of each value and convert only at the edges: when data comes in, when it goes into a database and when it goes to a user.

Concepts in this section

Read them in order. The first page gives the foundation the others use.

StepConceptWhat it answers
1Binary, integers and overflowWhy does a counter wrap to a negative number, and what order do bytes come in?
2Floating point and moneyWhy is 0.1 + 0.2 not 0.3, and how should money be stored?
3Unicode and UTF-8How is text turned into bytes, and why does "length" have four answers?
4Base64 and URL encodingHow do binary and special characters travel through text-only channels?
5Timestamps and time zonesHow do you store a time so that it stays correct across zones and DST?

Common mistakes

  • Using 32-bit counters or IDs for anything that grows with users.
  • Storing money as a float. Store integer minor units or a decimal type.
  • Using string length as a storage limit. Bytes, characters and graphemes differ.
  • Storing local time without a zone. Keep the moment in UTC and the zone as a name.
  • Building URLs by pasting strings together. Use the library builder.

Key takeaways

  • Each representation has a fixed range or precision. Know it before you pick a type.
  • Default to 64-bit integers for IDs and counters, and send them to browsers as strings.
  • Floats are approximate. Compare them with tolerances, and keep money exact.
  • UTF-8 is the right default for text. Normalize identifiers and use utf8mb4 in MySQL.
  • Store instants in UTC, exchange RFC 3339 timestamps, and measure durations with a monotonic clock.

Further learning

Each concept page ends with its own reading list. For how these values are packed into messages and files, see serialization.