130Build a browser-side analytics delivery system with batching, sampling, offline queueing, and deduplication
Problem
At scale, analytics costs real money and real bandwidth. Build a delivery pipeline that sends fewer, better events:
createAnalyticsPipeline({ transport, storage, sampleRate = 1, random = Math.random, online = true, batchSize = 20, dedupeWindowMs = 1000, now = Date.now, retryDelay = 1000, createId = () => crypto.randomUUID() }) returns { ready, track(name, props, { id, critical }), flush(), setOnline(online), queueSize }.
- Sampling per session: decide once whether this browser session is sampled (
random() < sampleRate) and store the decision instorageunder"analytics:sampled", so reloads keep it. Unsampled sessions drop ordinary events; events tracked withcritical: true(errors, purchases) are always kept. - Deduplication: drop an event whose
idwas already tracked (iddefaults to a newcreateId()), and drop an event with the samenameandpropsas one tracked less thandedupeWindowMsago (double clicks, re-renders). - Batching: events
{ id, name, props, ts }are queued; when online and the queue reachesbatchSize, flush. - Offline queueing: the queue is saved in
storageunder"analytics:queue"after every change and loaded on start (readyresolves after loading), so nothing is lost across reloads or offline periods.setOnline(true)flushes. - Delivery:
flush()sends batches of up tobatchSize, oldest first, withawait transport.send(batch). A successful batch is removed; a failure stops the flush, keeps the events and schedules a retry afterretryDelay.
storage has getItem, setItem and removeItem.
Try it yourself
Write your solution, run it, then submit to check it against the tests.
Press Run or ⌘ Enter to execute your code.
Step-by-step
Deciding per event makes funnels meaningless (a sampled "add to cart" without its "checkout"). Decide once per session, store the decision, and always keep critical events so errors and revenue are never undercounted.
Unlock the full solution
What's inside
- Step-by-step
- Approach
- Solution
- Complexity
- Edge cases
- Follow-up questions
- Tests
Includes 2 code listings, 5 edge cases, 4 follow-up questions.
One-time payment by UPI, card or net banking. Launch price.