DEV Community

Anthony Yerhot
Anthony Yerhot

Posted on

From Traffic to Behavior: Why I Built Shape Beacon

I deployed my first public domain earlier this year. I learned something very quickly: traffic according to Cloudflare is defined by something as small as a wispy breeze coming from a crawling script, not the stampede of human feet.

I got pretty pumped up by the stats Cloudflare was feeding me. But I was skeptical and wanted more.

I started with a simple KV counter. It just counted how many views my splash page had.

Then I put those numbers next to Cloudflare's.

My worker: 23 page views.

KV Tally

Cloudflare: 649 unique visits.

Cloudflare Dashboard

Same site. Same week. A very different story.

I still wanted more data.

Not bounce rate, clicks, or page views.

I wanted something that actually measured the physical interaction happening on my site.

So I created my own layer of analytics: Shape Beacon.

With this tool, I can look at that same week and get a different picture. Shape Beacon detected meaningful behavioral interaction in only 10 sessions during that same period.

Shape Beacon Dashboard

So what is it actually doing?

Shape Beacon temporarily collects browser interaction, reduces it into behavioral signals, and then throws away the raw event buffer.

_handleChunkLimit() {
    const events = this.collector.getRawEvents();
    this.chunkHistory.push(this._analyzeBuffer(events));

    this.collector.reset();
}
Enter fullscreen mode Exit fullscreen mode

The important part isn't the event counter. It's what happens afterward: the raw interaction is used as input to the calculation, not retained as the analytics product.

From there, the engine looks at the physical characteristics of the interaction.

const dx = ev.x - prev.x;
const dy = ev.y - prev.y;
const dist = Math.hypot(dx, dy);

totalDist += dist;
velocities.push(dist / dt);
Enter fullscreen mode Exit fullscreen mode

Distance, velocity, timing, and directional changes become behavioral signals.

Shape Beacon doesn't need to know what the user is looking at to describe how they interact with the page.

Those signals are reduced into four behavioral dimensions:

  • Intensity
  • Rhythm
  • Exploration
  • Coherence

The engine compares the four-dimensional point against tuned behavioral shapes.

for (const [shape, ideal] of Object.entries(this.tune.shapes)) {
    const dist = Math.hypot(
        metrics.intensity - ideal[0],
        metrics.rhythm - ideal[1],
        metrics.exploration - ideal[2],
        metrics.coherence - ideal[3]
    );

    distances[shape] = 1 / (dist + 0.0001);
}
Enter fullscreen mode Exit fullscreen mode

The session is treated as a point in behavioral space and compared against the shapes that exist within that space.

The result is a small behavioral fingerprint.

What gets sent?

When the session ends, Shape Beacon sends a <1KB JSON payload containing the processed behavioral signal.

No raw coordinates, clicks, or keystrokes are stored.

It's a lightweight JavaScript SDK that can also be routed through a first-party proxy.

The goal is to extract more meaning from less data.

The problem I'm exploring with Shape Beacon is:
What did that interaction look like?

I've recently deployed Shape Beacon as a free tool. I'm also exploring where this approach fits within modern edge platforms and have submitted Shape Beacon for consideration to Cloudflare, Vercel, and Netlify. Those applications are currently pending, so we'll see where this experiment goes.

The goal was simple: respect the end-user's browser while still giving developers meaningful behavioral data.

Cheers,
Anthony

Shape Beacon

Top comments (0)