Drop the raw IP at the edge
The collector hashes project, UTC day, IP, and user agent into a session id, resolves a coarse country and city, then discards the raw address. Nothing downstream — queue, store, or live feed — ever sees it.
The browser keeps a visitor id in local storage, not a cookie. Identification stays first-party: the operator runs the collector and the data stays in their database.
Label bots before they pollute the dashboard
AI crawlers and scrapers fetch pages like readers but behave nothing like them. A substring list over the user agent labels them at ingest, and the dashboard can include or exclude them per view.
Labeling early keeps every later aggregate honest. Filtering at query time cannot recover a pipeline that never recorded what was a bot.
// Pattern: Cookieless collect gate with edge bot labeling
interface CollectGate {
readonly sessionId: 'HMAC(projectId, UTC day, IP, userAgent)';
readonly storeRawIp: false;
readonly visitorKey: 'localStorage id, never a cookie';
readonly botLabels: ['GPTBot', 'ClaudeBot', 'CCBot', 'generic bot/spider/crawler'];
readonly overPlanBehavior: 'HTTP 204 accepted, event not enqueued';
}Gate by plan without lying to the sender
Events a plan does not allow are answered with success and quietly not enqueued. The sender never retries a storm, and the operator never stores what was not paid for.
This is how FluxTrace handles analytics ingest: edge discipline, an honest status code, and storage that matches the entitlement.
Have a similar architectural challenge?
Talk with our engineering team about trade-offs, cutovers, and sizing for your system.
