macOS Monterey Dock watches /Users/Shared/

June 30 2022 by Jeff Johnson

Lately I've noticed that every time I login to my user account on macOS Monterey, the root process fseventsd goes nuts, using almost 100% CPU for 5 to 10 minutes straight. I don't know how long this issue has been happening, because the fans rarely go nuts on my new M1 MacBook Pro. I would've noticed immediately from the fans revving on my 2014 Intel MacBook Pro, but it doesn't run Monterey, which is why I had to buy a new one this year. The fseventsd process is part of the FSEvents framework, implementing the File System Events API:

The file system events API provides a way for your application to ask for notification when the contents of a directory hierarchy are modified. For example, your application can use this to quickly detect when the user modifies a file within a project bundle using another application.

It also provides a lightweight way to determine whether the contents of a directory hierarchy have changed since your application last examined them. For example, a backup application can use this to determine what files have changed since a given time stamp or a given event ID.

I've written about the File System Events API before. Obviously it's not very "lightweight" in this case. I took a spindump in Activity Monitor and found that the fseventsd thread with heavy CPU time had a line that said "blocked by turnstile waiting for Dock". The Dock process itself had a thread named "Launch Pad Source FSEvent". I used the fs_usage command-line tool to discover exactly which files were accessed:

sudo fs_usage -e -w -f filesys

The output showed first that fseventsd opened many files in the /System/Volumes/Data/.fseventsd/ folder. These files contain the data about past file system events that occurred on your Mac. You can look at them yourself:

sudo ls -l /System/Volumes/Data/.fseventsd/

My folder contains over 127,000 files taking more than 12 GB of disk space, with dates going back to May 1. I don't know the format of the files, but I could open them in BBEdit and get the gist. Along with some binary data, you can see clear text file paths, so you know which files were involved in each file system event. Anytime any file on my Mac was modified in the past couple months, it's recorded there. I didn't check whether fseventsd opened every single file in the folder, but I did see that it was going through the files systematically, at least a couple weeks back in time.

According to fs_usage, after fseventsd opened a /.fseventsd/ file, it attempted to access files referenced by the corresponding file system event. Bizarrely, however, fseventsd only attempted to access files under the /Users/Shared/ folder, ignoring all other files!

While looking at the fs_usage output, I noticed that the Dock process itself was also very active. Analyzing these entries, I found that they were also concerned almost exclusively with files under the /Users/Shared/ folder! It looks like Dock called the FSEventStreamCreate function to get all the file system events in /Users/Shared/ and then called the getxattr function (man getxattr) to get the extended attributes of each referenced file. I don't know why Dock is accessing extended attributes of files in /Users/Shared/ or what it's looking for. I do wish it would stop.

The string "/Users/Shared" is contained within the Dock executable file on macOS Monterey. (And on the macOS Ventura beta too.)

strings - /System/Library/CoreServices/

The Dock executable on Big Sur doesn't contain the string "/Users/Shared". This explains why I never saw the fseventsd issue on Big Sur. The final piece of evidence convicting Dock of the crimes against my CPU is that I found a new way to reproduce the issue besides login. While fseventsd is resting at 0% at CPU, I run this command to restart the Dock, and suddenly fseventsd goes nuts again:

killall Dock

You may or may not experience the same high CPU usage as me. I believe the reason it happens for me is that I have a lot of files inside the /Users/Shared/ folder. I like the keep the size of my home folder relatively small, because I perform daily encrypted backups of my home folder and upload them to a server for offsite redundancy. I actually have a symlink from ~/Library/Developer to /Users/Shared/Developer, because Xcode puts GB worth of data in the Developer folder, such as simulator runtimes and the ever popular DerivedData. I keep open source code in /Users/Shared/, sometimes including the WebKit project, which is enormous. My iTunes library is also in /Users/Shared/. The Apple engineers who decided it was a good idea to monitor /Users/Shared/ probably didn't test with a folder the size of mine. That's unfortunate, because operating system designers need to anticipate that it can be used in ways that they personally don't.

The worst part for me is that even if I move my files in /Users/Shared/ to a different location on disk, that won't immediately solve the problem, because all of the old file system events are still there. It might take months for them to expire and get deleted by the system. The only immediate solution would be to manually empty the whole /.fseventsd/ folder. I'm not sure whether that would be safe…

I've filed FB10514236 with Apple Feedback.

Jeff Johnson (My apps, PayPal.Me)