The End of the Leap Second in 2027: What Changes in UTC and in Your Code
Hello HaWkers, on October 15, 2026, in Versailles, the 28th General Conference on Weights and Measures (CGPM) approved the resolution that ends the leap second. Starting on May 20, 2027, Coordinated Universal Time (UTC) will run continuously, without that extra second that, since 1972, has been inserted 27 times into the planet's official clock.
It sounds like astronomy news, and it is. But anyone who has watched a server freeze at midnight on a June 30 knows the leap second has always been a software problem. Is your system still carrying some workaround designed for it? In this article you will learn what the CGPM decided, why the Earth's rotation forced the decision, which famous bugs the extra second caused and, most importantly, what to review in your code and infrastructure before May 2027.
What the Leap Second Is and Why It Existed
The world has two ways of measuring time. One is atomic: the second is defined by the oscillation of the cesium atom, and International Atomic Time (TAI) is the average of hundreds of atomic clocks spread across the planet. The other is astronomical: UT1 follows the actual rotation of the Earth, which is not perfectly regular.
UTC is the compromise between the two. It ticks at the pace of atomic clocks, but it was kept within 0.9 seconds of UT1. Whenever the difference got close to that limit, the International Earth Rotation and Reference Systems Service (IERS) announced, in its Bulletin C, that a second would be added at the end of June or December. The clock then showed 23:59:60 before rolling over to the next day.
Some numbers for context:
- 1972: the year of the first adjustment, when the difference between TAI and UTC was set at 10 seconds.
- 27: total leap seconds inserted since then, all of them positive.
- 37 seconds: the current difference between TAI and UTC.
- December 31, 2016: the date of the last leap second applied.
Look at that last item. It has been almost ten years since any second was added, and there is a reason for that.
Why the Decision Came Now: The Earth Is Spinning Faster
For decades, the Earth spun slightly slower than the atomic clock, which is why every adjustment added time. In recent years, the trend reversed: the rotation sped up slightly. A paper by Duncan Agnew published in Nature in March 2024 projected that a second would need to be removed around 2029, and a 2025 workshop between the consultative committee for time and frequency and the IERS estimated a 30% chance of a negative leap second before 2035.
A negative second has never been applied. No production system has ever really been tested with a 59-second minute, and the track record of positive seconds shows the industry could barely handle the "easy" case.
This is how the decision unfolded:
- November 2022: the 27th CGPM decided to abolish the leap second by 2035, without setting a date.
- January 2026: the draft of Resolution C proposed May 20, 2027 as the start date.
- October 15, 2026: the 28th CGPM approved the resolution "on the technical actions necessary to ensure the continuity of UTC".
The new rule lets the difference between UTC and UT1 grow up to 3,600 seconds, that is, one hour. In practice, experts estimate that no correction will be needed for a long time, so the limit works as a safeguard. The BIPM, the IERS and the time distribution services are now working on the May 2027 transition.
The Bugs the Leap Second Left in History
If you work with infrastructure, you have probably heard of at least one of these cases.
Reddit and the Linux Kernel in 2012
On June 30, 2012, Reddit went down for roughly 30 to 40 minutes. The cause was a bug in the Linux kernel's high-resolution timer subsystem (hrtimer): the time change confused the kernel, and machines locked up with the CPU at 100%. That same second took down or degraded services at several companies that night.
Cloudflare and Go in 2017
At the turn of 2016 into 2017, Cloudflare's DNS server (RRDNS, written in Go) computed a negative response time after the clock went back one second. That value ended up in rand.Int63n(), which panics on a negative argument. At the peak, about 0.2% of DNS queries failed, and the fix took 6 hours and 45 minutes to roll out. Shortly after, Go 1.9 started including a monotonic clock in the runtime, so time differences would never go negative again when the wall clock moves backward.
The Workaround That Became Standard: the "Smear"
To avoid dealing with 23:59:60, the big clouds started smearing the extra second across several hours. Google has done this since 2008: for 24 hours, from noon to noon UTC, its clocks run 11.6 parts per million slower. AWS adopted the same 24-hour scheme, and Meta uses a 17-hour window.
The problem is that each company smears differently. During the window, a "smeared" clock can be up to half a second away from official UTC, and two servers using different time sources disagree with each other. If you compare timestamps from different systems, that is a silent source of inconsistency.
What Your Code Does with 23:59:60
The first thing worth knowing is that most languages simply do not represent second 60. Unix time counts seconds as if every day had exactly 86,400 of them, and standard libraries follow that fiction. Try it yourself in Node.js:
// Node.js 24: how Date handles the 2016 leap second
// An ISO string with second 60 is not accepted: the result is NaN
const parsed = Date.parse('2016-12-31T23:59:60Z');
console.log(parsed); // NaN
// Date.UTC accepts 60 seconds, but "overflows" into the next minute
const overflow = new Date(Date.UTC(2016, 11, 31, 23, 59, 60));
console.log(overflow.toISOString()); // 2017-01-01T00:00:00.000Z
// Bottom line: the leap second disappears from your system.
// If an external log contains "23:59:60", handle it before parsing.
function parseWithLeapSecond(iso) {
const leap = iso.replace(/T(\d{2}):(\d{2}):60/, 'T$1:$2:59.999');
return new Date(leap);
}
console.log(parseWithLeapSecond('2016-12-31T23:59:60Z').toISOString());
// 2016-12-31T23:59:59.999ZPython is even more blunt: datetime.fromisoformat('2016-12-31T23:59:60+00:00') raises ValueError: second must be in 0..59. If you consume data from equipment, satellites or financial systems that record second 60, that error may already be hiding in some ingestion pipeline.
With the end of the leap second, this case stops showing up in new data from 2027 on. Historical data, however, is still there. If you process old logs or time series, the handling above is still necessary.
Always Measure Duration with a Monotonic Clock
The most important lesson from the Cloudflare case does not depend on the leap second. The wall clock (Date.now(), time.time(), System.currentTimeMillis()) can go backward or jump for many reasons: NTP adjustment, manual correction, VM suspension, machine migration. Measuring duration with it is a bug waiting to happen.
// Wrong: Date.now() is a wall clock and can move backward
function measureWrong(fn) {
const start = Date.now();
fn();
return Date.now() - start; // can be negative if the clock is adjusted
}
// Right: performance.now() is monotonic, it only moves forward
function measureRight(fn) {
const start = performance.now();
fn();
return performance.now() - start;
}
// In Node.js, for nanosecond precision, use process.hrtime.bigint()
function measureNs(fn) {
const start = process.hrtime.bigint();
fn();
return process.hrtime.bigint() - start; // BigInt in nanoseconds
}
console.log(`${measureRight(() => JSON.stringify({ a: 1 })).toFixed(3)} ms`);In Python, the rule is the same: time.monotonic() or time.perf_counter() for duration, time.time() only to record when something happened. In Go, since version 1.9, time.Since(start) already uses the monotonic reading embedded in time.Time, as long as you do not strip that reading with operations like t.Round(0) or serialization.
The end of the leap second removes the scheduled jumps in the wall clock, but not the other ones. Code that measures duration with a monotonic clock does not care about any of them.
Where the Leap Second Lives in Your Infrastructure
The leap second does not only show up in application code. It lives in three places worth reviewing.
1. The leap-seconds.list File
The time zone database (tzdata) and the IERS distribute the leap-seconds.list file, which lists every adjustment plus an expiration date. Several NTP and PTP daemons read this file, and some complain when it expires. This script reads the file and shows the current offset between TAI and UTC:
# Reads leap-seconds.list and shows the TAI-UTC offset and its validity
from datetime import datetime, timezone
from pathlib import Path
# NTP epoch (1900-01-01) relative to the Unix epoch (1970-01-01)
NTP_TO_UNIX = 2_208_988_800
def ntp_to_datetime(ntp_seconds: int) -> datetime:
return datetime.fromtimestamp(ntp_seconds - NTP_TO_UNIX, tz=timezone.utc)
def read_leap_seconds(path: str):
entries, expires = [], None
for line in Path(path).read_text().splitlines():
if line.startswith('#@'):
# Special line with the file's expiration date
expires = ntp_to_datetime(int(line.split()[1]))
elif line and not line.startswith('#'):
ntp, offset = line.split()[:2]
entries.append((ntp_to_datetime(int(ntp)), int(offset)))
return entries, expires
entries, expires = read_leap_seconds('/usr/share/zoneinfo/leap-seconds.list')
last_date, offset = entries[-1]
print(f'Last adjustment: {last_date:%Y-%m-%d} | TAI-UTC = {offset}s')
print(f'File valid until: {expires:%Y-%m-%d}')The path varies by system (on Debian and Ubuntu it usually lives in /usr/share/zoneinfo/). The expected output today is TAI-UTC = 37s, with the last adjustment on January 1, 2017. After May 2027, that number should freeze at 37 for good.
2. The NTP Daemon
If you use chrony, which is the default on many distributions, the setting for how to react to a leap second lives in chrony.conf. This is a good time to find out what your server would do:
# /etc/chrony/chrony.conf (excerpt)
# How to handle an announced leap second:
# system -> lets the kernel insert the second (default)
# slew -> smears the adjustment, no jump in the clock
# step -> jumps all at once
# ignore -> does nothing
leapsecmode slew
# Maximum correction rate in ppm (1000 ppm corrects 1 s in ~17 min)
maxslewrate 1000
# Reads leap seconds from tzdata, useful if the NTP source does not announce them
leapsectz right/UTCAnd to check the current state on the machine:
# chrony shows "Leap status: Normal" when there is no pending adjustment
chronyc tracking | grep -i leap
# On systemd, check whether the clock is synchronized
timedatectl show --property=NTPSynchronizedOne important caveat: do not mix smeared and non-smeared time sources in the same cluster. If half your machines use your cloud's time server (with smear) and the other half use pool.ntp.org (without smear), they will disagree during any adjustment. With the end of the leap second this risk shrinks, but the habit of standardizing your time source is worth keeping forever.
3. Systems That Rely on Different Time Scales
GPS, Galileo and other navigation systems use their own time scales, without leap seconds. GPS time, for example, is 19 seconds behind TAI, which today means an 18-second difference from UTC. Any software that converts between these scales has an adjustment table somewhere. After 2027 the table stops growing, but it cannot be deleted: old timestamps still need it.
What Gets Simpler (and What Does Not Change) After 2027
What gets simpler:
- No more
23:59:60in new data and no more adjustment announcements every six months. - Smear strategies are no longer needed, and clocks from different companies stop drifting apart because of them.
- The risk of the first negative leap second, never tested in production, is off the table.
- The "every day has 86,400 seconds" assumption, which Unix time has always pretended was true, becomes true for UTC from now on.
What does not change:
- Time zones and daylight saving time still exist and keep changing by political decision. That has always been the biggest date problem in software, and the end of the leap second does not touch it.
- Historical data with leap seconds still needs handling.
- The wall clock can still jump because of NTP, VMs or human error. Duration is still measured with a monotonic clock.
- Astronomers, satellite operators and anyone who needs UT1 still have to apply the difference themselves, and it will grow slowly.
For anyone working with dates in JavaScript, this change pairs well with the arrival of the Temporal API, which explicitly separates instants, calendar dates and time zones. If you have not seen it yet, I explained how it works in ES2026 Temporal API: The End of Date Suffering in JavaScript.
A Quick Checklist to Review Before May 2027
Nothing here is urgent, but all of it is cheap to check:
- Search your code for duration measurements done with
Date.now(),time.time()or equivalents and switch them to a monotonic clock. - Check whether any parser for logs or third-party data breaks on
:60in the seconds field. - Find out which time source each environment uses (cloud,
pool.ntp.org, internal server) and standardize it. - Review
chronyorntpdconfigurations with leap-second-specific rules and document the reason for each one. - Keep the
tzdatapackage up to date: it keeps receiving time zone changes, which are far more frequent than leap seconds. - If you convert between GPS, TAI and UTC, make sure the adjustment table is versioned and will not be "cleaned up" by someone who thinks it became dead code.
Outlook: The World Clock Chose Predictability
The CGPM decision is, at its core, an engineering choice. For more than 50 years, the planet's official clock tried to track the Earth's rotation with sub-second precision, and the price was paid by the entire digital infrastructure, one bug at a time. With the Earth threatening to require the first negative second in history, the risk became too high.
Starting May 20, 2027, UTC becomes predictable: every day has the same number of seconds and no clock needs to jump because of the sky. The gap with the actual rotation will grow slowly, and one day, maybe centuries from now, someone will have to decide what to do about it. Until then, the message for anyone who writes software is simple: treat dates as delicate data, measure duration with a monotonic clock and never trust the wall clock to always move forward.
Let's go! 🦅
📚 Want to Keep Up With What Is Coming?
This article covered the end of the leap second in 2027 and what changes in UTC and in your code, but the ecosystem changes every week and not everything becomes an article here.
On X I share what I am testing, behind-the-scenes looks at my projects and the news that shows up before it turns into a post.
Follow Me There
💡 Daily content about development, career and the tools I actually use

