Counting unique visits to your site without cookies

Sai Charan Chinta
Unibuddy
Published in
3 min readSep 16, 2022

We want to empower our sales department with enough information on visits coming to our client applications and compare it with conversion (visit to signup) data. These are crucial data points needed to prove the value addition that Unibuddy provides and that we are giving our clients (universities) a good ROI, directly impacting the contract renewals.

We ended up implementing a solution that can count the number of unique visits we are getting without using cookies, doesn’t collect any PII, and complies with global privacy laws.

Pre-requisites: Basic knowledge of Cloudfront and lambda@edge

Solution

Let’s assume a unique visit is when a user comes to any of our client applications(let’s call it a widget) for the first time within a week.

All our client applications are specific to the university in question. So we can exactly attribute a visit to a university. When a user visits a widget, the logo of the university is downloaded from our servers and stored in the browser cache with an expiry of one week (in line with our assumption above).

Any visit to the widget within a week will not require the browser to download the logo because it’s already stored and loaded directly from the cache. And this happens as long as the user comes to the widget any number of times within a week. This is precisely what we defined as a unique visit.

We leverage this behaviour of the browser to uniquely and anonymously count a visit from a user. So every time a request for a logo image hits our server, we count it as a unique visit.

This is a high-level flow of how a unique visit is identified.

High-Level Flow

Implementation

All of our static files are stored in S3 and served through a CloudFront distribution. Cloudfront provides lambda@edge which can run a lambda every time it serves a request.

  1. We created a function that records a visit every time a request for a logo image is hit.
  2. We came up with a unique URL pattern(e.g. — /logos/<university-id>/<image-name>) specific to serving logo image requests and then added path-based behaviour rules at CloudFront to only run this function for these requests.
  3. When the request URL is matched to be a request for a logo image(using regex), we record a visit and then re-direct the request to the original resource(logo image) in S3.

A simplified view of the implementation could look like this:

The edge function implementation is pretty straightforward.

A sample script which records a visit

I did not add more technical details because it needs a fair bit of knowledge on CloudFront events, when to use the right events, how CloudFront cache works, and the difference between CloudFront function vs lambda@edge. But if you are wondering what the final implementation looks like, it looks like this:

Closing thoughts

I found CloudFront functions and lambda@edge to be great tools for solving some unique problems with interesting implementations. AWS CDK made it a breeze to write and deploy them. Although, debugging could be a bit tricky due to the complicated way a request is served from the browser to CloudFront to your servers.

If you are thinking the solution is over-engineered for a simple problem, read more about privacy & GDPR laws 😅; Unibuddy provides solutions to universities from across the regions each with different jurisdictions.

--

--