Skip to content

CONCEPT Cited by 1 source

MySQL VARCHAR length requirement

MySQL VARCHAR declarations require an explicit maximum length. Postgres allows VARCHAR without a length, behaving like an unbounded text column. The asymmetry surfaces immediately in any Postgres → MySQL schema migration.

In MySQL for the varchar type, we have to set a max value, whereas in Postgres we did not.

sources/2026-04-21-planetscale-migrating-from-postgres-to-mysql

Mechanisms

  • MySQLVARCHAR(N) where N is the max character count. If you don't know a bound, the drop-in answer is TEXT (no length, storage backed by a separate off-page region for large values).
  • PostgresVARCHAR with no length stores arbitrary- length text, up to 1 GB. The type is functionally interchangeable with TEXT in Postgres.

Migration choices

When moving a Postgres VARCHAR (unconstrained) column to MySQL:

  • Switch to TEXT. Drop-in, no length guess required. Trade-off: TEXT is not directly indexable without a prefix length (see concepts/blob-text-index-prefix-requirement).
  • Keep VARCHAR(N). Pick N large enough to cover any existing row, but know that underestimating truncates data at insert time — this is a real operational hazard.
  • Profile actual column lengths first. SELECT MAX(LENGTH(col)) in Postgres gives an empirical upper bound before the migration.

SERIAL has a parallel pitfall

The PlanetScale post flags a related declarational asymmetry for integer identity columns:

If we set the serial type in MySQL, it'll default the underlying data type to a bigint unsigned auto_increment.

Postgres's SERIAL is INTEGER-backed; MySQL's SERIAL is a 64-bit alias. Capacity and storage footprint differ.

Last updated · 378 distilled / 1,213 read