Free — no signup required

Time Namespaces

2 min read

Time Travel for Containers

For years, Linux had no way to give a process a different view of time than the host system. This created a real problem for testing: if you wanted to verify that your certificate rotation logic worked correctly when a cert expired in 2030, you had to either mock time in your application code (fragile, requires code changes) or actually change the system clock (which breaks every other process on the machine, including your CI runner).

Linux 5.6 (released March 2020) introduced Time Namespaces (CLONE_NEWTIME). A time namespace allows a process (and its children) to have a different offset applied to two specific clocks:

  • CLOCK_MONOTONIC: The container sees a different "uptime" than the host.
  • CLOCK_BOOTTIME: The container sees a different boot time than the host.

Critically, CLOCK_REALTIME is not offset by time namespaces. This is a deliberate design choice — wall clock time is shared globally, because changing it for one container would break TLS, Kerberos, and other security protocols that depend on absolute time agreement.

How It Works
The kernel stores an offset per namespace. When a process in a time namespace calls clock_gettime(CLOCK_MONOTONIC), the kernel returns actual_monotonic + namespace_offset. The process has no way to distinguish this from real elapsed time. A process can be unshared into a fresh time namespace with a chosen monotonic/boottime offset (e.g., one year forward), and every clock read inside that namespace — including what /proc/self/timens_offsets reports — reflects the shifted value from that point on, while the host and every other process on the machine sees the real time, untouched.

Practical Use Cases
* Certificate expiry testing: Shift time forward by 2 years inside a container to test renewal logic without touching the host clock.
* Reproducible builds: Ensure build tools that embed timestamps produce consistent output regardless of when the build runs.
* Chaos engineering: Simulate clock skew between microservices by running them in different time namespaces with different offsets.
* Gaming/simulation: Run a simulation that needs to believe it has been running for months, without actually waiting months.

Container runtimes (Docker, containerd, Podman) do not yet expose time namespace configuration through their standard CLI flags as of 2024 — you typically need to use unshare directly or configure it at the OCI runtime level. This is an area of active development.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free