Inside the Unified Log 3: Log storage and attrition
By far the most common problem experienced with the Unified log isn’t its large number of entries, but a lack of entries. You go to check your Mac’s security using SilentKnight, or Skint runs its automatic daily check, and they can’t find any log entries recording XProtect Remediator scans. Since those are obtained by analysing the log for the previous 36 hours, when your Mac’s logs only go back 8-12 hours, entries for the last set of scans are likely to be missing. This article looks at why that happens, and how macOS maintains its log.
Traditional Unix-style logs are maintained according to their age. Every 24 hours, routine housekeeping procedures delete log files over a certain age, typically five days, in the process of rolling the log. Because the Unified log could over that five-day period have swallowed many GB of storage, its maintenance service logd
deletes log records according to multiple criteria including the space they occupy, their age, and the type of entry. This is considerably more complex, and occurs in three phases, according to where the entry is stored.
Ephemeral entries
Log entries are initially written to memory, before logd
writes most of them to permanent storage on disk.
The first substantial purging of entries thus occurs when logd
decides which are ephemeral and won’t be written to disk. This can be seen by following the number of entries in a short period of high activity in the log, over time, and is shown in the chart below for a sample period of 3 seconds.
When fetched from the log within a minute of the entries being written, a total of 22,783 entries were recovered. Five minutes later there were only 82% (18,655) of those remaining. Attrition of entries then continued more slowly, leaving 80% (18,309) after 8 hours. Analysis suggests that over this period in which there were about 6,100 log entries per second written to disk, approximately 1,700 log entries per second were only kept in memory and never written to disk. That suggests about 22% were ephemeral, a proportion that’s likely to vary according to the origin and nature of log entries.
Persist entries
The great majority of log entries that survive to be written to permanent storage are kept in the tracev3 files in /private/var/db/diagnostics/Persist, where logd
maintains them according to the total size of that folder, with a target of 520-530 MB. As each tracev3 file is up to 10.5 MB in size, that results in logd
retaining about 50 files in that folder, although some are smaller than the maximum.
Two of my apps currently provide the datestamp of the start of the current collection of Persist log files as an indicator of the oldest log entry available from them: XProCheck, and Mints with its Logs button. This is a feature I intend adding shortly to LogUI.
However, not all log entries are stored in those Persist files. Looking back in time at total log entries available for a set ten minute period each day, you might see totals like:
- 1 day old 33,827 in 10 minutes
- 2 days old 98,534
- 3 days old 59,296
- 4 days old 10
- 5 days old 1
- 6 days old 40
- 7 days old 0
- 8 days old 358
- 9 days old 1.
Those for the last 3 days are almost all Persist entries, but older entries are those retained in tracev3 files in the Special folder.
Special entries
Fault and Error log entries are normally written to the tracev3 files in the Special folder, and may contain additional message content kept in the warren of folders and files inside /private/var/db/uuidtext. logd
purges entries from Special files separately, and apparently on the basis of their type and content rather than size. As a result, the Special folder can contain many tracev3 files of sizes ranging from over 2 MB to just a few KB, with their size tending to reduce with age. Any log entries recovered from dates before the oldest Persist file thus must have come from Special files.
Although files stored in the uuidtext folder are small, there can be a great many of them, and total size of that folder can exceed 1 GB. Those too are maintained by logd
.
Other folders and files
tracev3 files stored in the Signpost folder contain only Signpost log entries used for performance assessment, and are purged at a slower rate than Persist files, but not retained as long as Special files. The High Volume folder appears seldom if ever used. The timesync folder contains time synchronisation data, small files that normally cover the whole period of Special files.
The /private/var/db/diagnostics folder contains several other files, including the logs of logd
and logd_helper
, and most significantly pairs of statistical summaries written during log maintenance, named logdata.statistics.[n]
where n
is a number starting from 0, in both .txt and .jsonl (JSON) format.
Each time logd
performs maintenance on a tracev3 file, or on associated uuidtext files, it records data about the files in the current logdata.statistics files, both as plain text and in JSON format. The most useful of these records occurs when a Persist tracev3 file is rotated from being the file into which new log entries are written, to being retained without further additions. That entry records:
- the name of the tracev3 file;
- the time of rotation, thus the time immediately following the last log entry to be made to that file;
- the total number of log entries in that file, for example 42,365,476;
- for the top 20 processes that wrote entries in that period, the number of entries, the percentage of total entries, and the path to the process, listed in order of number of entries.
For example, in that tracev3 file containing a total of 42,365,476 entries, the kernel might have written 13,095,296 entries, 30.9%, and be top of the list, while runningboardd
might only have written 1,223,157 or 2.9%. These statistics can be valuable in drawing attention to periods when there were problems, and for discovering which entries are limiting the coverage of Persist files, making it impossible for apps to recover entries for XProtect Remediator scans, for example.
Statistics entries for memory rollovers can also be useful, as are those for Special file rotation, although the latter contain fewer entries than Persist files.
Extending the period of log coverage
Currently, there doesn’t appear to be any way to set logd
‘s size allowance for Persist files. When the Unified log was first introduced, it wasn’t unusual for that setting to preserve full log records covering a period of up to 20 days. As more processes now write copious entries in the log, a Mac that’s left awake and running at all times may only retain the last 20 hours of Persist entries, or even less.
Macs that don’t need to be awake and running at all times can extend their log coverage by sleeping or being shut down, when of course no entries can be written. If that isn’t possible, you can write your own XML property lists to /Library/Preferences/Logging to limit the retention of specific categories of entry. However, experience shows that only achieves small extensions to time coverage. It’s also worth bearing in mind that disabling privacy protection in the log will increase the size taken by most log entries, so shortening time covered by the retained logs.
Perhaps the wisest and most effective way to extend the time coverage of logs is to discover the causes of excess entries and address those, although that’s inevitably the most difficult solution.
One little-used technique is to turn log records in backups into logarchives, enabling old log entries to be accessed days or even years after they have been written. As an example of what can be achieved, the log entries below were written eight years ago, on 26 September 2017, saved in a logarchive, and browsed using LogUI on 26 September 2025.
I will explain how to do this in a future article in this series.
Summary
- Log maintenance is a sophisticated managed process that discards log messages for several reasons, most generally to keep total log file size within limits, rather than removing entries purely on the basis of age.
- A fifth of log entries are likely to be ephemeral, and lost from the log within the first minutes after they’re written. If you want the fullest entries possible, obtain the log excerpt as soon as possible after its entries have been written.
- Most retained log entries are written in Persist logs, where tracev3 files are removed by age to keep their total size to just over 500 MB. Those should preserve log entries for hours or days after they’re written.
- Entries for Faults and Errors are stored in Special logs, where they’re kept for longer, sometimes for weeks.
- logdata.statistics files provide detailed statistics for log files as they’re rotated, and can tell you which processes wrote most entries.
- As logs aren’t written during sleep, or when shut down, allowing sleep and shutting down will extend the duration of log records.
- Time Machine and other backups can be used to recover old logs as logarchives.