How Chromium's cookies get evicted
I was recently asked if I knew how Chromium’s cookies were evicted/garbage-collected. My answer was that I don’t know, but I can find out. This post is what I discovered while digging through the code. Hopefully it will be useful to someone else (or at the very least, to future me).
There's not a lot of prose in this one, mostly code pointers and references..
TL;DR - If you want some of your cookies to stick around over others, make them high priority and secure. If you want to explicitly delete some cookies, override them with an expired cookie, that matches their "domain" and "path".
# The Cookie Monster’s limits
As it turns out, Chromium has a cookie monster in its network stack. But even monsters have their limits. In this particular case, there’s a limit to the amount of cookies the cookie monster can hold.
It has limits on the maximum number of overall cookies (3300), as well as maximum number of cookies per domain (180). Once those limits are met, a certain number of cookies will be purged in order to make room for others - 300 overall and 30 per domain cookies.
Given that cookies are being partitioned, there are also limits per partitioned domain, but currently at least they are identical to the per domain one (so, 180 cookies).
Another interesting constant - cookies accessed in the last 30 days are safe from global purge. That is, other websites can’t cause your recent cookies to be purged, but can cause your older ones to go away if the overall cookie limit is exceeded.
# Eviction
The general eviction mechanism used in Chromium’s Cookie Monster is a variant of Least-Recently-Used (LRU).
Cookies are sorted based on access recency and the least recently accessed ones get evicted first.
Access time is defined as either the creation time of the cookie, or the last time the cookie was used (e.g. on a request header), give or take a minute.
When a new cookie is set, that kicks off a garbage collection process, which purges the least recently accessed ones for the domain, as well as the overall least recently accessed cookies.
The cookie monster determines what is its “purge goal” - how many cookies will be deleted in order to make room for more.
Initially, all expired cookies are deleted. Then the rest of the purge happens in rounds until the purge goal is met.
The first round targets non-secure cookies with low-priority and then secure, low-priority ones. At a minimum, 30 of those will be preserved, with priority to the secure ones.
Then non-secure medium-priority cookies go on the chopping board, followed by non-secure high-priority cookies.
Finally, secure medium-priority and then high-priority are considered.
From the medium-priority ones, at least 50 will be preserved (priority to secure ones), and at least a 100 high-priority ones would be as well.
Otherwise, if you want to explicitly delete some older cookies in order to make room for the ones you care about, setting an expired cookie deletes a previous copy and doesn’t add it back. In order to set a matching cookie, you want its "domain" and "path" to be identical to the cookie you're aiming to delete.
Note: Cookie priority is a proprietary Chromium feature. It does seem useful, so it’s a shame it wasn’t standardized. By default, cookies are of medium priority.
# Summary
Again, I hope the above is somewhat useful to someone. If you want to make sure specific cookies survive over others, or you want to delete old ones, you now know how to do that (at least in Chromium).
I haven't dug into the way other engines handle cookies, but I suspect that for Safari that happens in the (closed-source) OS level.
Finally, I wish cookie priority was standardized. It seems like a useful feature, and one that I wasn't aware of before digging into the code.
Update: Mike West tells me that there was a draft to standardize "priority", but that it didn't get Working Group adoption. Also, the priority bump for "secure" cookies is part of RFC6265bis.