Why are some MySQL fields 255 characters long?
By: Stewart Leonard
Tags: MySQL, Database, Web Development, Utf 8

If you’ve read some older guides on MySQL or you’ve inherited someone else’s database then you’ve probably come across this phenomenon. If it’s not varchars with 255 characters it’s integers with odd lengths like 7 or 15.

An example of varchar(255) from a tutorial site | Source: mysqltutorial.org

The one constant you can rely on is that they are always 1 less than a power of 2.

7 rather than 8 (²⁴)

255 rather than 256 (²⁸)

Because lists in computing start at 0?

Nope. Prior to MySQL 5.0.3 had a limit on the maximum size of varchar fields. That limit was indeed 256 bytes but you couldn’t put 256 characters in there. There are many theories on this floating around such as:

The NULL character takes up 1 byte — wrong!

Being empty takes up 1 byte — wrong!

To understand this you have to understand how characters are stored in a computer.

ASCII (American Standard Code for Information Interchange) is the most well-known method of encoding text and uses a constant bit rate — each character takes up 8 bits, 1 byte. However, it’s limited to only 256 possible options and that includes special codes for new lines, carriage returns and all manner of fancy symbols. It simply doesn’t have enough combinations to display all the intricate characters from other languages — accents, umlauts, Cyrillic characters and more.

Enter the modern hero — UTF, the Unicode Transformation Format. There are multiple levels of UTF complexity starting at UTF-8 and followed by UTF-16 and UTF-32. The important consideration here is that characters stored in UTF use a variable bit rate — they can be 1, 2 or 4 bytes. This allows for a much greater diversity but also complicates memory storage.

Back to that missing byte

The missing byte was used to store the length of the string stored in the field. If using ASCII you could just count the size of the memory in use but UTF’s variable bit rate meant that the computer had to process the string to work out how long it was. Storing the length was just plain faster.

The length could never exceed 255, so 1 byte was enough to store the length, but depending on how many extended UTF characters were included (those that used more than 1 byte) this would reduce the maximum potential length.

MySQL supports Unicode characters up to 3 bytes long, so this means that there is a potential maximum length of only 85 characters if all of those characters used their full allocation.

Note: MySQL only supports Unicode characters within the BMP (Basic Multilingual Plane) while the Unicode specification allows for characters to take up to 32 bits or 4 bytes.

But that’s how it used to be right?

MySQL 5.0.3 came along and removed this restriction. Varchar fields no longer had a specific limit but that doesn’t mean it’s infinite.

MySQL still limits each ROW to 65,535 bytes and 4096 columns. In practice, the memory limit is far more impactful that the column limit (or at least I hope so!!!). What this means is that while your varchar fields can be bigger, you still have to be aware of the memory usage of the entire row.

So should I stick to powers of 2 still?

From my experience, there’s no tangible benefit from limiting field sizes to powers of 2. The row as a whole is stored in memory along with a host of other metrics and indexing data.

It’s far more relevant to consider the user implications of field size e.g. is my field large enough for long names or email addresses while avoiding obvious bloat for no reason.

The new age of MySQL has set you free of your binary boundaries!