Skip to content

Database tables

Four tables, created by the package migrations (loaded automatically, no publishing). user_id and eventable_id are strings, so UUID and ULID keys work.

One row per visitor id. First-touch columns are written once; geo, device and locale hold the last known values.

ColumnTypeDescription
idbigintPrimary key
tokenstring(64), uniqueVisitor id
first_seen_at / last_seen_attimestampFirst and latest recorded activity
first_landing_urltextURL of the first recorded request
first_referrer_urlstring(2048)Referrer of the first request
first_referrer_hoststring, indexIts host
utm_source (index), utm_medium, utm_campaign, utm_term, utm_contentstringFirst-touch UTM
refstring, indexFirst-touch ref
search_termstring, indexFirst-touch search keyword
extra_paramsjsonFirst-touch click IDs and pattern matches
country_code (string(2), index), region, city, timezonestringLast known geo
lat, lngdecimal(10,7)Last known coordinates
geo_metajsonDriver-specific geo fields
localestring(10), indexApp locale of the latest request
browser_languagestring(10)First Accept-Language entry
device_type, client_type (index), platform, browserstringLast known device
device_metajsonBrand, model, OS/browser version, engine
is_botbool, indexLatest request was a bot
user_type, user_idstring, indexLinked user
tenant_idstring, default '', indexSet by the app, never by the package
created_at, updated_attimestamp

One browsing session. Attribution and geo/device are a snapshot from the moment the session opened.

ColumnTypeDescription
idbigintPrimary key
visitor_idFK visit_visitors, cascade on delete
started_attimestamp, indexOpened
last_activity_attimestamp, indexLatest event
ended_attimestamp, nullableSet by visits:close-stale-sessions
duration_secondsunsigned int, nullableSet by visits:close-stale-sessions
page_views_countunsigned intRecorded page views
landing_urltextURL of the first request
exit_urltextLast page view, set when closed
referrer_url (string(2048)), referrer_host (index)stringReferrer of the first request
utm_source (index), utm_medium, utm_campaign, utm_term, utm_content, refstringLast-touch attribution
search_termstringLast-touch search keyword
extra_paramsjsonLast-touch click IDs
ipip address, index
country_code (index), region, city, timezone, lat, lng, geo_metaGeo snapshot
locale, browser_languagestring(10)
device_type (index), client_type (index), platform, browser, device_metaDevice snapshot
user_agenttext
is_botbool, indexSticky: true once any request of the session was a bot
user_type, user_idstring, indexUser snapshot
created_at, updated_attimestamp

Indexes: (visitor_id, started_at), (visitor_id, ended_at, last_activity_at).

One page view or action. No updated_at.

ColumnTypeDescription
idbigintPrimary key
session_idFK visit_sessions, cascade on delete
visitor_idFK visit_visitors, cascade on deleteDenormalized for direct queries
typestring(20), indexpage_view or action
namestring, indexAction name; null for page views from TrackVisit
urltextFull URL
pathstring, indexPath without query string — Top pages groups by it
route_namestring, indexLaravel route name; null for collect events
is_botbool, index
bot_name, bot_categorystringFor bots
eventable_type, eventable_idstring, indexModel passed to Visits::track()
metajson
created_attimestamp, index

Indexes: (eventable_type, eventable_id), (session_id, created_at), (name, created_at), (type, created_at).

Rollups written by visits:aggregate.

ColumnTypeDescription
idbigintPrimary key
datedate, indexDay
tenant_idstring, default ''
metricstring(40)visitors, sessions, page_views, conversions
dimensionstring(40), default '''' for the total, otherwise a name from aggregate.dimensions
dimension_valuestring, default ''
countunsigned bigint

Unique key: (date, tenant_id, metric, dimension, dimension_value).

Request-derived strings are cut to their column length before saving, so an oversized value loses its tail instead of failing the visit: referrer URL and host (since 0.12.0), UTM/ref values, search_term, path and the name passed to Visits::track() (255 characters, since 0.13.1). Before 0.13.1 a longer value of these on a database in strict mode failed RecordVisitJob and the visit was lost (Data too long / value too long in failed_jobs).