Java
Programming
System.currentTimeMillis
System.nanoTime
Performance Measurement

System.currentTimeMillis vs System.nanoTime

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

System.currentTimeMillis() and System.nanoTime() both return numbers related to time, but they answer different questions. One is for wall-clock timestamps, and the other is for measuring elapsed time.

Choosing the wrong one can lead to subtle bugs. A benchmark based on currentTimeMillis() can be distorted by clock changes, while a timestamp based on nanoTime() is meaningless outside the current JVM process.

Use currentTimeMillis() for Real-World Time

System.currentTimeMillis() returns the current wall-clock time as milliseconds since the Unix epoch. That makes it suitable for:

  • logging timestamps
  • storing event times
  • comparing against real dates and times
java
long createdAt = System.currentTimeMillis();
System.out.println(createdAt);

The important limitation is that wall-clock time can move. NTP synchronization, manual clock changes, leap adjustments, and VM time changes can all affect the value.

That is why currentTimeMillis() is not the best timer for measuring how long code took to run.

Use nanoTime() for Elapsed Time

System.nanoTime() is designed for measuring durations. It uses a monotonic time source with an arbitrary origin, so only differences between two readings are meaningful.

java
1long start = System.nanoTime();
2
3doWork();
4
5long elapsedNanos = System.nanoTime() - start;
6System.out.println("Elapsed: " + elapsedNanos + " ns");

This is the right choice for:

  • microbenchmarks
  • timeout calculations
  • profiling short operations

Even though the method name says "nano," it does not guarantee true nanosecond precision. It simply returns time in nanosecond units with the best timer the platform provides.

Why the Difference Matters

Suppose you measure a timeout using wall-clock time:

java
1long deadline = System.currentTimeMillis() + 5000;
2while (System.currentTimeMillis() < deadline) {
3    // wait
4}

If the system clock jumps backward, this loop may run longer than intended. If the clock jumps forward, it may finish too early.

The monotonic form is safer for durations:

java
1long deadline = System.nanoTime() + 5_000_000_000L;
2while (System.nanoTime() < deadline) {
3    // wait
4}

Because nanoTime() is monotonic, it is much better suited for elapsed-time logic.

Benchmarking Caveat

Even though nanoTime() is the right primitive for measuring durations, simple hand-written benchmarks can still be misleading because of JIT warmup, dead-code elimination, and GC pauses. For serious benchmarking in Java, libraries such as JMH exist for a reason.

The important point is still the same: if you measure elapsed time manually, nanoTime() is the correct clock source. currentTimeMillis() is a timestamp source, not a benchmarking tool.

A Simple Rule of Thumb

Ask yourself what you need:

  • "What time did this happen?" Use currentTimeMillis(), or better yet Instant.now().
  • "How long did this take?" Use nanoTime().

That simple distinction covers most cases. The methods are not interchangeable even though both return long.

If you remember only one rule from this topic, remember that timestamps are about real-world chronology and durations are about monotonic differences. Java gives you a different clock source for each because they solve different problems well.

That distinction prevents many subtle timing bugs.

Common Pitfalls

  • Using currentTimeMillis() for benchmarking or timeout measurement.
  • Treating nanoTime() as a wall-clock timestamp.
  • Comparing nanoTime() values across JVM restarts or different machines.
  • Assuming nanoTime() implies true hardware nanosecond resolution.

Summary

  • 'currentTimeMillis() gives wall-clock time since the Unix epoch.'
  • 'nanoTime() gives a monotonic time source for measuring elapsed time.'
  • Use wall-clock time for timestamps and monotonic time for durations.
  • 'nanoTime() values only make sense when subtracted from each other.'
  • For modern timestamp APIs, Instant.now() is often clearer than raw epoch milliseconds.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.