~/guides/-guides-unix-timestamp-guide-
guides · Formatting

Unix Timestamp Guide: Seconds, Milliseconds, and Time Zones

Avoid common date bugs when moving between logs, APIs, and user-facing timestamps.

last updated · June 1, 2026by @vultio

Why timestamp bugs are so common

Unix timestamps look simple because they are just numbers, but they hide three separate problems that often get mixed together: the unit, the time zone, and the human display format. A bug in any one of those layers can make a system look hours, days, or even decades off.

Most production timestamp failures are not advanced calendar math issues. They are basic contract mistakes such as seconds vs milliseconds, UTC vs local time, or undocumented assumptions between backend and frontend code.

Seconds vs milliseconds: the first check to make

As a rule of thumb, 10-digit Unix timestamps usually represent seconds, while 13-digit timestamps usually represent milliseconds. Passing one where the other is expected is one of the fastest ways to create impossible-looking dates.

ValueLikely unitTypical meaning
1717333200secondsNormal Unix timestamp from logs or APIs
1717333200000millisecondsJavaScript Date.now()-style timestamp
1717333too short / suspiciousProbably truncated or wrong source value

Store UTC, render local

The safest operational model is simple: store and exchange canonical timestamps in UTC, then convert to local time only at the presentation layer. That keeps logs, APIs, databases, and cross-region services aligned on one source of truth.

If you mix local storage and local rendering across servers, browsers, and background jobs, daylight-saving shifts and regional differences quickly turn into confusing off-by-one-hour bugs that are hard to reproduce.

Common timestamp failure modes

Milliseconds passed into a seconds-based API

Dates appear far in the future or are rejected as invalid.

Seconds passed into a JavaScript Date constructor expecting milliseconds

Dates appear around 1970 or otherwise wildly incorrect.

Local time assumed to be UTC

Displayed dates shift by the viewer or server offset.

Undocumented time zone rules in CSV exports

Analysts and support teams interpret the same value differently.

API contract rule: document the unit explicitly

Never force consumers to guess. If an API returns a number timestamp, the schema or docs should say whether it is seconds or milliseconds. Better yet, show an example value and label it clearly.

The same goes for imports, exports, and webhooks. Ambiguity at the contract layer is much more expensive than adding one sentence to the documentation.

A quick debugging checklist

  1. Count the digits first.
  2. Check whether the source system documents seconds or milliseconds.
  3. Verify whether the timestamp is intended to represent UTC or local wall-clock time.
  4. Compare raw numeric value and rendered display side by side before blaming business logic.
  5. Test with a known reference date so you can see exactly where the conversion drift begins.

The recurring trap: an instant is not the same as a schedule

A Unix timestamp represents a precise instant. It does not, by itself, explain business intent such as “run this every day at 9:00 AM in Rome” or “charge at local midnight.” Those are scheduling rules layered on top of time, not raw timestamps.

Teams run into trouble when they collapse those ideas together. The stored timestamp may be perfectly correct while the scheduling model is wrong for daylight saving changes, locale expectations, or tenant-specific time zones. Knowing that distinction saves a lot of false debugging.

Real-world places timestamp bugs show up

Webhook replay tools

A test event appears expired because the replay service expects seconds while your app sends milliseconds.

CSV exports for support teams

One dashboard labels times as local while the export silently emits UTC values.

Frontend countdowns

The browser renders local time correctly, but the API rounded or serialized the wrong unit before it arrived.

Data migrations

Old rows are interpreted with a legacy timezone assumption that no longer matches the current application contract.

A reliable documentation pattern

If you publish timestamps in an API or export format, document three things together: the unit, the timezone assumption, and one concrete example. For example: “created_at is a Unix timestamp in milliseconds, expressed in UTC, for example 1717333200000.”

That single sentence prevents a surprising number of bugs because consumers no longer have to reverse-engineer meaning from the value itself. Clear timestamp contracts are cheap to write and expensive to skip.