Overview
Snapp collects metrics at redirect time.
There is no background crawler, no client-side tracker requirement, and no delayed job pipeline.
Every visit is captured synchronously when a short URL is resolved.
Metrics are designed to be:
- lightweight
- append-only
- organization-scoped
- query-efficient
- filterable by URL, date, UTM, and organization
When metrics are recorded
Metrics are recorded during shortcode resolution, immediately before redirect.
A visit is logged when:
- the URL is active
- the URL is not expired
- VirusTotal and watchlist checks pass
- secret protection (if present) is satisfied
If any of these fail, no metric is written.
Internal vs external visits
Each metric row stores both:
metric.organizationId→ the visitor organizationurl.organizationId→ the owner organization
This enables classification into:
internal visits
Visitor belongs to the same organization as the URL owner.external visits
Visitor belongs to a different organization or is anonymous.
This distinction is computed at query time, not stored redundantly.
Data captured per visit
Each metric entry may include:
- timestamp
- URL id
- owner id
- visitor organization id (if authenticated)
- browser
- OS
- device type
- language
- referrer
- country / region / city (when available)
- UTM payload (JSON)
Metrics are append-only. They are never mutated after insertion.
Organization scope
All metrics queries are scoped by:
url.organizationId = active organization
This guarantees:
- organizations cannot see each other’s metrics
- admins can switch organization context explicitly
- no cross-organization aggregation occurs implicitly
URL-level metrics
On a single URL page, metrics are aggregated per day.
The chart displays:
- internal visits
- external visits
- stacked by day
Missing days are filled client-side to preserve chart continuity.
The data model returned to the UI is:
{
internal: { day: Date; visits: number }[]
external: { day: Date; visits: number }[]
}
Aggregation happens in SQL using DATE(timestamp) grouping.
Dashboard metrics
The organization dashboard aggregates metrics across all URLs in scope.
Available breakdowns:
- visitors per day (internal vs external)
- browsers
- operating systems
- devices
- languages
- referrers
- countries
- regions
- cities
- visitor organizations
All queries share the same base constraints.
Date range handling
Metrics support arbitrary date ranges.
Defaults:
from: 7 days agoto: today (end of day)
Ranges can be controlled via:
- date picker
- preset ranges (week, month, six months, year)
All dates are applied server-side using >= from and <= to.
UTM support
UTMs are stored as structured JSON:
{
"utm_source": { "key": "utm_source", "value": "twitter" },
"utm_campaign": { "key": "utm_campaign", "value": "launch" }
}
This allows:
- filtering by UTM keys
- filtering by UTM key/value
- discovering which UTMs exist for a dataset
UTM key discovery
Snapp scans recent metrics to extract available UTM keys.
This avoids maintaining a separate index table and keeps storage minimal.
Limits are enforced to prevent unbounded scans.
UTM filtering
Two independent filters exist:
UTM keys filter Restrict metrics to visits containing specific UTM keys.
UTM value filter Restrict metrics to a specific value for a given UTM key.
Filters are combined at query time using JSON operators.
Permission enforcement
Metrics visibility is controlled by role:
- regular users see metrics only for URLs they own
- admins can see metrics across the organization
- organization context must be explicitly selected
This is enforced in SQL via:
user.role === 'user'
? metric.ownerId = user.id
: no restriction
There is no client-side trust.
Performance characteristics
- Metrics inserts are single-row writes
- Aggregations are computed on-demand
- Queries use grouped indexes and bounded scans
- No joins cross organization boundaries
- No background jobs are required
The redirect path remains fast and deterministic.
What metrics do NOT do
- No cookies are set by the redirect itself
- No cross-site tracking
- No fingerprinting
- No third-party scripts required
- No mutation of existing metrics
Snapp metrics are observational, not behavioral.