Understanding Unix filesystem timestamps

Published on 2022-10-25.

The POSIX standard requires that operating systems maintain filesystem metadata that record when each file was last accessed. Let's take a look at what all that means.

A lot of information on the Internet about filesystem timestamps are either outdated or misunderstood. Some people also tend to generalize a specific option's pros and cons across all setups, not knowing when the option is actually appropriate. For example, I might think that setting atime to on is unconditionally bad because it will have a detrimental effect on the performance of the filesystem without knowing that atime is required by some applications in order to function properly.

The POSIX standard mandates that metadata for three timestamps are stored in the filesystem regarding each file. These three timestamps are:

An example of a change to the ctime property is when the file permissions change. Changing file permissions doesn't access the file itself, so atime doesn't change. The file is also not modified in any way, so the mtime options also doesn't change. Still, we have changed the permissions of the file itself, and this must be registered somewhere. The POSIX standard gives this job to the ctime field.

But why would we need to store that information in the first place? Well, if we make a backup of the file, a backup tool may need to know if the file permissions has changed in order to determine if a new backup is required, or if it can simply skip the file because nothing has changed. Another operation that also changes the ctime option is renaming a file.

As you can properly guess, the atime property comes with both a performance penalty and a wear penalty on a very busy filesystem because every read operation on a file also generates a write operation. When you read the file, the atime metadata field is updated, which requires a write.

So, a file's atime, mtime, and ctime are set to the current time whenever you read, write, or change the attributes of the file. Searching a directory also counts as reading it. And a file's atime and mtime can be set directly, via the touch command.

On any UNIX-like operating system, like Linux or BSD, you can display a file's timestamps with the stat command.

On Arch Linux:

$ stat /bin/ls
  File: /bin/ls
  Size: 137744          Blocks: 272        IO Block: 4096   regular file
Device: 254,0   Inode: 29897362    Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-04-21 22:11:19.000000000 +0200
Modify: 2022-04-17 20:21:13.000000000 +0200
Change: 2022-04-21 22:11:19.555074371 +0200
 Birth: 2022-04-21 22:11:19.555074371 +0200

On OpenBSD:

$ stat -x /bin/ls
  File: "/bin/ls"
  Size: 317048       FileType: Regular File
  Mode: (0555/-r-xr-xr-x)         Uid: (    0/    root)  Gid: (    7/     bin)
Device: 4,0   Inode: 25942    Links: 1
Access: Tue Sep 27 19:40:00 2022
Modify: Tue Sep 27 19:40:00 2022
Change: Thu Oct 20 16:11:01 2022

Each operating system has it's own set of time related mount options that directly control how atime, mtime and ctime is affected. You can take a look at the man page for the mount command on your operating system to read about each of these options.

Depending on the operating system and filesystem we have some of the following mount options:

OpenBSD and FreeBSD does not have the relatime option for the mount command. On OpenBSD the noatime option behaves more like Linux's relatime.

OpenZFS controls it's own mount properties and you don't use the mount command for ZFS. OpenZFS supports relatime regardless of operating system, but the ZFS relatime option behaves different from the Linux mount relatime option, which is important to understand.

On OpenZFS, relatime controls the manner in which atime is updated.

When atime is set to on, and relatime is also set to on, relatime "rules", meaning access time is set relative to mtime and ctime as described above (with the 24 hours rule). If atime is set to on and relatime is set to off, then atime works as it normally would.

If atime is set to off, relatime has no effect whether it is set to on or off.

So in order to get the effect of relatime, both atime and relatime needs to be set to on on OpenZFS.

On Linux, since kernel 4.0, the option lazytime was introduced. lazytime reduces writes to disk by maintaining changes to atime, ctime and mtime timestamps only in memory. The disk timestamps are then updated only if the file inode needs to be updated for some change unrelated to file timestamps, or if a sync to disk occurs, or if an undeleted inode is evicted from memory, or lastly, if more than 24 hours has passed since the last time the in-memory copy was written to disk.

To disable atime, in order to improve both performance and wear of the disks, a filesystem can be mounted with the noatime option when needed. On ZFS this is done by setting the atime option to off for the specific pool and dataset.

However, turning atime off can break certain applications like mail related applications. As such, on FreeBSD, atime is enabled on the /var/mail directory.

The reason why atime is required by some mail applications is because they compare mtime and atime to determine if the mail is read or not. Some backup applications also require atime to be enabled in order to function correctly.

A less "drastic" alternative to completely disabling atime is to use relatime. relatime was developed to mitigate the problems that disabling atime can present.

By default, all filesystems are now mounted with relatime enabled, on most Linux distributions.

The default option of atime on OpenZFS is on, which means that a file's access time is written to the ZFS metadata (not the file itself) every time the file is accessed. This means that we're getting a write to disk every time the file is read. Furthermore, if we leave atime set to on, we also experience an increase in shapshot size because the snapshot retains the original metadata access time, while the running filesystem contains the newly updated access time.

In my humble opinion, the best approach is to manually tune the filesystems to your specific requirements. You can for example choose to disable atime completely for the / (root partition) and then enable relatime for the /var/spool or /var/mail directories, if you need that.

If you know for a fact that you don't need atime, such as if you're running a storage system, disable it by mounting the filesystem with noatime, or if it's ZFS, by setting atime to off for the entire pool and all datasets. This will not only improve performance, but also the wear and tear of the disks, especially if you're using SSDs.

A lot of misunderstanding regarding the level of endurance of SSDs exist on the Internet. The fact is that a lot of different things affects both the quality and reliability of an SSD, but the determining factor to wear out an SSD, is writes and erasing.

When you write to a NAND cell, or when you erase it, the electrons jump through the insulating layers via the Fowler-Nordheim Tunneling and that is what eventually physically wears our the SSD.

Things like room temperature can effect the data retention of the SSD, and the cell technologies (MLC, TLC, QLC) affect this, but that is not what wears it out, it is only the writing and erasing. Thus, disabling atime definitely has an effect of the wear and tear of an SSD.

Partitions like /home can be mounted with relatime or noatime depending on your specific needs and the applications being run on your system.

System administration tasks that use file access properties

On most normal day usage of desktops and laptops, you never need to know when a file was last accessed, however as a system administrator running a server, you might need to:

I recommend that you always specifically set your mount options for the requirements of your system.

Relevant reading