Expiration is handled in
Expiration is based on hardware specs, specifically on memory size and CPU cores. This means on mobile and old systems expiration will be more aggressive than on high-end hardware, to try keep the database size at a reasonable (and performant) value.
All of expiration uses the Storage async API, that ensures I/O is in a separate thread, plus it won't block any read thanks to the use of the WAL journaling system.
Common expiration runs on a timer, every 3 minutes and uses a simple adaptive algorithm: if the last step was unable to expire enough entries the next one will expire more entries, otherwise if the previous step completed the cleanup the next step will be delayed. This ensures expiration doesn't lag behind without hitting performances when there is no need for it.
Apart this periodic expiration, there are other steps on idle, on shutdown on clear history.
On idle it expires a larger chunk of pages, then timed expiration is stopped. This ensures to not interfere with standby tasks and preserves battery on mobile.
Most of the times the adaptive algorithm will ensure the database is clean before shutdown, so the only task executed on shutdown will be removal of session data (like session annotations). In some cases, like when a clear history is executed just before shutdown, a larger step is executed instead.
When Places maintenance runs (about once a week, on daily idle), an orphans expiration step is executed, this ensures database cleanup.
Usually there is no need to tweak or set any preference, since adaptive behavior should satisfy each need, though in case of unexpected issues it's possible to act on some hidden preferences:
- places.history.expiration.interval_seconds: Minimum number of seconds between expiration steps. Default is 180 seconds.
- places.history.expiration.max_pages: The maximum number of pages that may be retained in the database before starting to expire. Default value is calculated on startup and put into the places.history.expiration.transient_current_max_pages preference. This transient version of the preference is just mirroring the current value used by expiration, setting it won't have any effect.