Unix Epoch Time Milliseconds vs Microseconds: Fix Bugs

You're Probably Logging the Wrong Timestamp Precision Right Now

Picture this: you're debugging a race condition in your API. Two requests hit your server within microseconds of each other, and your logs show timestamps that look identical. You fire up your favorite Unix timestamp converter, paste both values, and get the same human-readable time for both. "They really did arrive at the same moment," you conclude. You move on, chase a different theory, and waste three hours.

Here's what actually happened: your logging framework was returning epoch time in microseconds, but the converter tool you used assumed milliseconds. It silently truncated the extra digits, collapsing two distinct moments into one. The race condition was real. Your tooling lied to you.

This mistake is absurdly common. And it happens because most developers never explicitly learn the difference between Unix epoch time in milliseconds and microseconds — they just grab whatever number the language hands them and assume it's universal.

Let's fix that, step by step, from the perspective of someone who lives in timestamp converter tools daily and is tired of seeing people lose precision without realizing it.

The Core Misconception: "A Timestamp Is A Timestamp"

No, it isn't.

Unix epoch time — the number of seconds (or fractions thereof) since January 1, 1970, 00:00:00 UTC — comes in at least three common flavors in modern programming:

  • Seconds: 10 digits as of 2001 onward (e.g., 1718234400)
  • Milliseconds: 13 digits (e.g., 1718234400000)
  • Microseconds: 16 digits (e.g., 1718234400000000)

The misconception is treating these as interchangeable. They are not. Each represents a completely different resolution of time, and mixing them up doesn't just round things — it destroys ordering, breaks comparisons, and silently corrupts log analysis.

Why This Confusion Exists

Different programming ecosystems default to different precisions, and they rarely announce which one they're using:

  • JavaScript Date.now() returns milliseconds. Always. No exceptions.
  • Python time.time() returns seconds as a float, but time.time_ns() gives nanoseconds as an integer.
  • Java System.currentTimeMillis() returns milliseconds, while Instant.now().getNano() gives you nanoseconds.
  • Go time.Now().UnixMicro() returns microseconds, but time.Now().UnixMilli() returns milliseconds.

If you're passing a JavaScript timestamp into a Go function that expects microseconds, you're off by a factor of 1,000. And no compiler will warn you, because both are just integers.

Step 1: Count the Digits Before You Convert Anything

This is the single most important habit you can build when working with any Unix timestamp converter tool. Before you paste a number into a converter, count its digits.

Here's your cheat sheet:

  • 10 digits → seconds. This is the original Unix epoch format.
  • 13 digits → milliseconds. This is what JavaScript and Java use by default.
  • 16 digits → microseconds. Common in Go, Rust, and high-resolution logging.
  • 19 digits → nanoseconds. Python's time_ns(), some C++ chrono implementations.

Let's use a real number. Right now, as I write this, the Unix epoch time in seconds is approximately 1718234400. That's 10 digits. In milliseconds, the same moment is 1718234400000 — 13 digits. In microseconds, it's 1718234400000000 — 16 digits.

Same instant. Three completely different numbers. If your timestamp converter doesn't ask you which precision you're inputting, it's guessing. And if it guesses wrong, your debugging is built on fiction.

Step 2: Understand What You're Actually Losing

Here's an analogy that makes this concrete. Imagine you're recording the time someone enters a building.

  • Seconds is like writing "2:15 PM" — you know they arrived sometime within that 60-second window, but you can't tell if it was the start or the end.
  • Milliseconds is like writing "2:15:03.247 PM" — now you know within a thousandth of a second.
  • Microseconds is like writing "2:15:03.247891 PM" — you're capturing time at a resolution faster than a single CPU instruction.

For most web applications, millisecond precision is plenty. Human-perceivable latency lives in the tens of milliseconds. A user clicking a button and a server responding 50 milliseconds later — that's a noticeable delay, and milliseconds capture it fine.

But if you're building anything where sub-millisecond ordering matters — high-frequency trading logs, distributed system event sourcing, kernel-level tracing, or real-time audio buffer scheduling — milliseconds are useless. Two events that fire 300 microseconds apart will both get stamped with the same millisecond. Your log will show them as simultaneous. They weren't.

Step 3: Match Your Converter to Your Input

When you land on a Unix timestamp converter tool, the first thing you should check is whether it handles multiple precisions or silently assumes one. Many free online converters default to seconds and choke on 13-digit inputs, returning dates in the year 56,000-something. Others assume milliseconds and convert a 10-digit seconds timestamp into some moment in January 1970.

The right tool — and the right workflow — works like this:

  1. Identify the source. What language or system produced this timestamp? That usually tells you the precision. JavaScript? Milliseconds. Go's UnixMicro()? Microseconds. Raw C time()? Seconds.
  2. Count the digits. Confirm your assumption. 10/13/16/19 — the digit count is your ground truth.
  3. Convert at the correct precision. If your converter doesn't let you specify, find one that does. A proper epoch time converter should accept seconds, milliseconds, microseconds, and nanoseconds as distinct input modes.
  4. Verify the output. Does the human-readable result make sense for the context? If your log entry says the event happened in 1970 or in the year 50,000, you've got a precision mismatch.

Step 4: Be Consistent Across Your Entire Stack

The most expensive timestamp bugs don't come from a single conversion mistake. They come from mixed precisions across a system.

Here's a real-world pattern that bites teams constantly: a frontend written in JavaScript logs events with millisecond timestamps. The backend, written in Go, logs with microsecond timestamps. Both get shipped to the same log aggregation service. Someone writes a query to find events that happened within 500 units of each other, treating both streams as the same unit.

500 milliseconds is half a second — a reasonable window for "these two events are related."

500 microseconds is half a millisecond — a window so tight it will almost never match two events from different services.

The query returns nothing. The team assumes the events aren't correlated. The actual bug goes unfound.

The fix is simple but boring: pick one precision for your entire observability stack and normalize everything to it at ingestion time. Most modern observability platforms default to milliseconds. If your Go service emits microseconds, divide by 1,000 before shipping. If your Python script logs seconds, multiply by 1,000. Normalize early, convert once, and never think about it again.

Step 5: Know When Microseconds Actually Matter

Not every system needs microsecond precision. Adding it where it doesn't matter creates larger log files, more complex parsing, and zero additional insight. Here's a practical guide:

  • Use seconds for anything human-facing: blog post timestamps, user session expiry, calendar events.
  • Use milliseconds for web request logging, API response timing, cache TTLs, and most application-level observability.
  • Use microseconds for distributed tracing spans, database query profiling within a single node, kernel tracing, and any system where you need to establish causal ordering between events that fire within the same millisecond.
  • Use nanoseconds only when you're measuring CPU-level operations, cache latency, or working with hardware interfaces. For everything else, it's overkill.

The Bottom Line

The difference between Unix epoch time in milliseconds and microseconds isn't a trivia question. It's the difference between a log that tells you the truth and a log that tells you a plausible lie. Every time you paste a timestamp into a converter, you're making an implicit assumption about precision. Make it explicit instead.

Count the digits. Know your language's defaults. Use a converter that respects the distinction. And when in doubt, remember: 13 digits is milliseconds, 16 digits is microseconds, and never, ever treat them as the same thing just because they both look like big numbers.

Frequently Asked Questions

What is the difference between milliseconds and microseconds in Unix time?

Unix epoch time measures the number of seconds since January 1, 1970, but programming languages often break this down into smaller fractions for precision. Milliseconds represent one-thousandth of a second (10^-3), while microseconds represent one-millionth of a second (10^-6). This means a microsecond timestamp provides a much higher level of precision for measuring extremely fast events.

How many digits are in a millisecond vs microsecond Unix timestamp?

A standard Unix timestamp in seconds is typically 10 digits long. When expressed in milliseconds, the timestamp grows to 13 digits, and in microseconds, it expands to 16 digits. Counting the digits is a quick way to determine which time unit a given timestamp is using.

Is Unix time in seconds, milliseconds, or microseconds?

The original Unix epoch time standard is defined in seconds. However, modern programming often uses milliseconds or microseconds to track high-resolution time. It ultimately depends on the specific programming language or system implementation you are using.

Does JavaScript Date.now() return milliseconds or microseconds?

In JavaScript, the Date.now() method returns the current Unix timestamp in milliseconds. JavaScript does not natively support microsecond precision in its standard Date object. To achieve microsecond precision in JS, you would need to use the performance.now() method alongside the current timestamp.

How do you convert Unix timestamp milliseconds to microseconds?

To convert a millisecond Unix timestamp to microseconds, you simply multiply the value by 1,000. For example, a timestamp of 1609459200000 milliseconds becomes 1609459200000000 microseconds. This is a common operation when interfacing with systems that require higher time precision.

How to get Unix timestamp in microseconds in Python?

In Python, you can use the time module to get a microsecond-level Unix timestamp. Specifically, time.time_ns() returns the current time in nanoseconds, which you can divide by 1,000 to get microseconds. Alternatively, time.time() returns seconds as a float, where the decimal portion represents fractions of a second.

Why do some programming languages use milliseconds for Unix time?

Languages like JavaScript and Java use milliseconds because it offers a balance between human-readable dates and system performance without requiring overly large numbers. Milliseconds are generally sufficient for most web applications and logging tasks. Microseconds are typically reserved for scientific computing, high-frequency trading, or detailed performance profiling.

How to convert Unix timestamp microseconds to seconds?

To convert a microsecond Unix timestamp back to standard seconds, you need to divide the number by 1,000,000. For instance, 1609459200000000 microseconds divided by 1,000,000 equals 1609459200 seconds. Always use integer division if you want to drop the fractional seconds, or float division to retain the exact decimal value.

What is the Y2038 problem for millisecond and microsecond timestamps?

The Y2038 problem affects 32-bit Unix systems that store timestamps in seconds, causing them to overflow in January 2038. If a 32-bit integer is used for milliseconds, it overflows much sooner, and for microseconds, it overflows in just a few hours. This is why modern systems use 64-bit integers to safely store high-precision timestamps far into the future.

How do I extract milliseconds or microseconds from a 13-digit timestamp?

A 13-digit Unix timestamp is already in milliseconds, so no extraction is needed for the base unit. If you need microseconds from a 13-digit timestamp, you multiply by 1,000, but you cannot extract true microsecond precision if it wasn't recorded originally. To get the exact fractional seconds, you can use the modulo operator with 1000 on the millisecond timestamp.