Real-time Analytics with Counters and SSE
Track page views, count events, and stream live activity — all with InfiniteOcean's built-in primitives. This is how the InfiniteOcean admin dashboard works.
Running Drops. This tutorial uses Drops, a compact language that replaces curl commands. Run them via POST /exec or paste into the live editor.
1 The Building Blocks
InfiniteOcean has two primitives that make analytics trivial:
- Atomic counters — Increment fields on entities without read-modify-write races. Just POST a drop with
{"+views": 1}and the counter increments atomically. - SSE streams — Connect to
/live/*and receive drops in real-time as they're written. No polling, no WebSocket setup.
Together: counters for aggregation, SSE for live feed.
2 Counting Page Views
Every time someone visits a page, increment a counter with the incr command:
incr analytics/daily @2026-02-10 .page_views
incr analytics/daily @2026-02-10 .requests
The + prefix means "increment this field by the given amount." If the entity doesn't exist yet, it starts at 0. This is atomic — 1000 concurrent requests won't lose a count.
3 Reading the Counts
read analytics/daily @2026-02-10
Returns: {"page_views": 4521, "requests": 12034, ...}
The counter values are merged into the entity read automatically.
4 Per-Endpoint Tracking
Use dynamic field names to track different endpoints:
-- Track a POST /drop request
incr analytics/endpoints @2026-02-10 ."POST /drop"
-- Track a GET /entity request
incr analytics/endpoints @2026-02-10 ."GET /entity/*"
Read back the entity and you get a full breakdown: {"POST /drop": 4567, "GET /entity/*": 2341, "POST /sql": 891}
5 Querying with SQL
Query across multiple days with SQL:
sql `SELECT key AS date, page_views, requests FROM "analytics/daily" ORDER BY key DESC LIMIT 7`
Returns the last 7 days of analytics. SQL works on entities the same way it works on any table.
6 Live Activity Feed with SSE
Write event drops for live tracking:
-- Write an event drop (no key = events accumulate, never overwritten)
write analytics/events { method: "POST", path: "/drop", status: 200 }
Connect to the SSE stream to receive events in real-time:
HTTP only. SSE (Server-Sent Events) connections use a persistent HTTP stream — there's no Drops equivalent. Use EventSource in JavaScript or curl -N to connect.
curl -N https://api.infiniteocean.io/live/analytics/events \
-H "X-Ocean-Key: YOUR_KEY"
data: {"method":"POST","path":"/drop","status":200,...}
data: {"method":"GET","path":"/entity/users/123","status":200,...}
In the browser:
const events = new EventSource('/live/analytics/events?_key=YOUR_KEY');
events.onmessage = (e) => {
const event = JSON.parse(e.data);
addToLiveFeed(event); // render in your UI
};
7 Putting It Together
A minimal dashboard in about 15 lines of JavaScript:
// Fetch daily stats
const res = await fetch('/entity/analytics/daily/2026-02-10', {
headers: { 'X-Ocean-Key': key }
});
const stats = await res.json();
document.getElementById('views').textContent = stats.payload.page_views;
// Live feed
const sse = new EventSource(`/live/analytics/events?_key=${key}`);
sse.onmessage = (e) => {
const ev = JSON.parse(e.data);
// prepend to activity list
};
That's it. No database to set up, no aggregation pipeline, no WebSocket server. Counters accumulate, SSE streams, and SQL queries across it all.
8 How the Admin Dashboard Works
The InfiniteOcean admin dashboard at /admin uses exactly this pattern internally. Every HTTP request increments counters on _admin/daily, _admin/hourly, _admin/endpoints, and _admin/status entities. The live feed publishes event drops via the bus. The dashboard reads counter values and connects to SSE — all built on the same API primitives available to every user.