Anatomy of a visitor ID
What is actually behind a Veriprint visitorId: three durable storage anchors, a stability-weighted signal vector, and an EMA that lets the profile drift with the device.
A Veriprint visitorId is not one value but three components stacked together: three durable storage anchors, a stability-weighted signal vector, and an exponential moving average that keeps the stored profile current. Each layer covers a way the layer above it can fail.
1. Three durable anchors
The cheapest way to recognize a device is to have told it its own ID last time. Veriprint plants the ID in three storage mechanisms with different lifetimes and different clearing behavior:
- Cookie: survives normal browsing, dies to "clear cookies".
- localStorage: partitioned per origin, cleared by a different user action than cookies.
- Cache API: the ID encoded in a cached response; routinely survives when the other two are wiped.
Any single surviving anchor re-links the visitor deterministically, and the other two are re-planted on the next call. The response tells you which path matched via matchedVia, so you can see anchor health in your own traffic. Users who clear all three, or open a private window that partitions all storage, fall through to the probabilistic layer.
2. The signal vector
When no anchor survives, identification comes from ~70 entropy sources, kept as a structured vector rather than hashed into one value:
{
"timezone": "Europe/Berlin", // weight ×5, stable for years
"hardwareConcurrency": 8, // weight ×5, physical
"deviceMemory": 8,
"fonts": ["Inter", "Fira Code"], // weight ×3
"screen": "2560x1440@2",
"canvas": "a91f…", // weight ×1, drifts on updates
"webgl": "07bc…" // weight ×1
}
The candidate vector is scored against stored profiles with stability-weighted similarity; a score of 0.82 or higher re-links to the existing visitorId. That score is the confidence field on the response, computed per request, never a constant. Network signals (IP, geo, ASN, datacenter and TOR flags) are resolved server-side and inform vpnLikely and bot scoring, but carry little identity weight, because IPs rotate.
3. EMA decay and re-anchor
A profile frozen at first sight goes stale: six months of gradual drift eventually adds up to a failed match even when each individual step was small. So on every successful match, the stored profile moves toward the observed vector with an exponential moving average:
profile[i] = alpha * observed[i] + (1 - alpha) * profile[i];
Fast-drifting signals get a higher alpha, so a new canvas hash is adopted within a couple of visits, while a timezone change moves the profile slowly and costs confidence until it recurs. After a probabilistic match, all three anchors are re-planted: the expensive path immediately buys back the cheap one.
What this adds up to
Anchors give determinism when storage survives. The weighted vector gives recognition when it does not. The EMA keeps both honest as the device changes. The result is an ID that is strong over weeks, good over months, and, because this is probability rather than magic, degrades gracefully instead of failing silently. Read the confidence field and branch on it.