Home / Databases

Storage

Databases

The database server can run on a 64-bit kernel and still store a 32-bit time. The column type is the contract.

MySQL / MariaDB

TIMESTAMP is documented as 1970-01-01 00:00:01 UTC through 2038-01-19 03:14:07 UTC. That is the same ceiling as signed time32. DATETIME runs from year 1000 to 9999 and is the usual migration. MySQL 8.0.28 onwards widened UNIX_TIMESTAMP(), FROM_UNIXTIME() and CONVERT_TZ() on compatible 64-bit platforms toward year 3001. The column type did not become 64-bit by magic; check the schema.

The INT you forgot

An INT named created_unix is a 32-bit field on every engine. So is a protobuf int32, a JSON number stuffed into a 32-bit language type, and a binary log format with a 4-byte epoch. Audit names, not slogans.

PostgreSQL

timestamptz is not a Unix time32. Application code that dumps it to a 32-bit epoch for an API can still overflow. Treat the wire format as a separate system.

How to find TIMESTAMP columns

SELECT table_schema, table_name, column_name, data_type, column_type
FROM information_schema.columns
WHERE data_type = 'timestamp'
   OR (data_type IN ('int','int unsigned')
       AND column_name REGEXP 'time|epoch|unix|ts$');

Treat every hit as a 2038 contract until proven otherwise. Changing TIMESTAMP to DATETIME is the usual MySQL migration; it is not timezone-aware the same way, so decide whether you need UTC storage plus a zone column.

UNIX_TIMESTAMP() is not the column

MySQL 8.0.28+ can convert times past 2038 in UNIX_TIMESTAMP() / FROM_UNIXTIME() on 64-bit hosts. A TIMESTAMP column on that same server still cannot store 2038-01-19 03:14:08 UTC. Test the schema, not the function.

What “the database is 64-bit” hides

Postgres timestamptz, Oracle TIMESTAMP, and SQL Server datetime2 are not Unix time32. The overflow moves to the client: a Go int32, a Java int, a protobuf int32, a JSON number parsed into a 32-bit language type. Dump one row as the integer the API actually emits.