Three moving parts

Infralytiqs is deliberately small in surface area. A collector accepts events over HTTPS and writes them into ClickHouse. A query API compiles report definitions into aggregate SQL. A console renders the results. You can reason about all three.

The database is not ours. You register a ClickHouse server you control, and Infralytiqs creates its database and its website_events table inside it. There is no agent to install, no proprietary wire format, and no transformation layer between what you send and what you can query.

Every capability, in detail

The rest of this page describes the platform as a whole. If you are looking for a specific surface, each one has its own guide with the configuration reference and a step-by-step walkthrough of the portal side.

WebSites Analytics. The browser SDK: a two-tag install, automatic page views and clicks, SPA route changes, consent gating, and the full configuration reference.

Mobile Apps Analytics. iOS, Android and React Native over plain HTTPS. No native SDK to embed, and offline queueing you control.

Logs Collector. Ship AEM and application logs to a Grafana Loki server you run, then read them in the console with a label browser, volume histogram and live tail.

AEMaaCS Integration. Author-side asset, storage and login activity through an OSGi bundle; published-site behaviour through the browser SDK; and the Loki streams that explain both.

Server Side Analytics. Events from Java, Node, Python or Go, with a complete Spring Boot ETL worked example correlating analytics and logs on a shared run id.

Custom Dimensions and Metrics. Attach your own string dimensions and numeric metrics to any event, have them discovered automatically, and group and aggregate by them.

Collect from anywhere

One endpoint, one payload shape, whatever the source.

Browser SDK

Load infralytiqs.min.js, call Infralytiqs.init() with your tenant and site, and page views start flowing. Custom events are one function call, and eVar/prop maps let you name your dimensions the way your team already talks about them.

Mobile apps

There is no native binary to embed โ€” iOS, Android and React Native POST the same JSON to the same endpoint. That means no SDK version to chase, and full control over when a queued batch is flushed.

Server-side services

Node, Java, Python, Go or a curl command in a cron job. Up to 1000 events per request, so a nightly job can report a whole day's activity in a handful of calls.

AEM integration

An OSGi bundle that observes AEM author traffic and replication events, then batches them to the collector. Asset uploads, downloads, share-link views, publishes, logins and scheduled DAM storage snapshots, with no page code to write.

Custom dimensions and metrics

Every event carries a custom_dimensions string map and a custom_metrics number map. ClickHouse stores them as typed Map columns, so adding a dimension needs no migration and no schema change request.

Server-side enrichment

The collector resolves country from the request IP with GeoIP, so geography works without the client asserting it. Precise browser geolocation is available too, but strictly opt-in per domain.

Store on your terms

The part that separates Infralytiqs from every hosted analytics product.

Bring your own ClickHouse

Register a server URL, optional basic auth, TLS settings and a database name. Infralytiqs runs CREATE DATABASE and CREATE TABLE there. ClickHouse Cloud, a container on your laptop and a replicated cluster behind a load balancer are all valid targets.

Cluster aware

Tick the cluster option and give it a cluster name, and the table is created with ON CLUSTER and a ReplicatedMergeTree engine instead of a plain MergeTree. Single node today, replicated tomorrow, same schema.

No sampling

Nothing in the pipeline samples. Every accepted event becomes a row and every row is counted, because a funnel built on a sample is confidently wrong rather than obviously wrong.

Retention is a TTL

The table ships with TTL event_date + INTERVAL 24 MONTH DELETE and ttl_only_drop_parts, so expiry costs nothing. Want ten years or ninety days instead? It is one ALTER TABLE on your own database.

Compression built in

Every column is declared with a ZSTD codec and event_time uses Delta, while event_type, country_code and device_type are LowCardinality. That is why keeping everything stays affordable.

Raw SQL access

It is your database, so point any SQL client at it and join event data against your own tables. Nobody needs to build you a screen before you can answer a question.

Where the boundary sits

Infralytiqs runs the collector and the console. You own the storage.

Your applications

Web

Browser SDK

infralytiqs.min.js

Mobile

iOS ยท Android ยท RN

Plain HTTPS

Backend

REST, up to 1000/batch

Server-side

AEM author

OSGi bundle

Assets & logins

Infralytiqs

Collector

Validates tenant and site

GeoIP enrich

Query API

Report DSL to SQL

Aggregates

Console

Reports ยท Logs ยท Audit

SSO protected

Your infrastructure

ClickHouse

website_events

Your credentials

Retention

24-month TTL by default

Your storage

SQL clients

Any tool you like

Direct access

Everything in the right-hand stage lives in infrastructure you control. That boundary is what makes data residency, retention and raw SQL access your decisions rather than ours.

The table Infralytiqs creates in your database

This is the actual DDL the platform runs when you register a ClickHouse server. Nothing is hidden from you, because the database is yours.

CREATE TABLE IF NOT EXISTS analytics.website_events (
    event_time          DateTime64(3) DEFAULT now64(3) CODEC(Delta(8), ZSTD(1)),
    event_date          Date MATERIALIZED toDate(event_time),
    site_id             String CODEC(ZSTD(1)),
    tenant_id           String CODEC(ZSTD(1)),
    language_iso_code   String CODEC(ZSTD(1)),
    user_id             String CODEC(ZSTD(1)),
    anonymous_id        String CODEC(ZSTD(1)),
    session_id          String CODEC(ZSTD(1)),
    event_type          LowCardinality(String) CODEC(ZSTD(1)),
    event_subtype       LowCardinality(Nullable(String)),
    custom_dimensions   Map(LowCardinality(String), String) CODEC(ZSTD(1)),
    custom_metrics      Map(LowCardinality(String), Float64) CODEC(ZSTD(1)),
    asset_id            Nullable(String) MATERIALIZED custom_dimensions['asset_id'],
    search_term         Nullable(String) MATERIALIZED custom_dimensions['search_term'],
    page_url            String CODEC(ZSTD(1)),
    page_path           String ALIAS path(page_url),
    country_code        LowCardinality(String) CODEC(ZSTD(1)),
    device_type         LowCardinality(String) CODEC(ZSTD(1)),
    device_os           LowCardinality(String) CODEC(ZSTD(1)),
    utm_source          LowCardinality(Nullable(String)),
    latitude            Float64 DEFAULT 0 CODEC(ZSTD(1)),
    longitude           Float64 DEFAULT 0 CODEC(ZSTD(1)),
    location_accuracy   Float64 DEFAULT 0 CODEC(ZSTD(1)),
    event_id            UUID DEFAULT generateUUIDv4() CODEC(ZSTD(1))
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (user_id, event_time, event_type, event_id)
TTL event_date + INTERVAL 24 MONTH DELETE
SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1;

Event fields

What you send in the JSON body, and what the collector fills in for you. Anything beyond this list belongs in custom_dimensions or custom_metrics.

Field Type Set by Notes
event_type LowCardinality(String) You Your event name. Defaults to unknown if omitted
event_subtype Nullable(String) You Optional second level, e.g. asset_publish_status_success
tenant_id ยท site_id String URL Taken from the request path only โ€” a client cannot assert them
event_time DateTime64(3) Server or you Defaults to now64(3); send it yourself to backfill history
user_id String You Your identifier. Empty until you choose to identify someone
anonymous_id ยท session_id String SDK First-party identifiers written by the browser SDK
page_url String SDK or you page_path is an ALIAS column computed as path(page_url)
custom_dimensions Map(LowCardinality(String), String) You Queryable as custom_dimensions['plan']
custom_metrics Map(LowCardinality(String), Float64) You Numeric facts you want to sum or average
country_code LowCardinality(String) Collector Resolved by GeoIP from the request IP; the IP is not stored
device_type ยท device_os LowCardinality(String) SDK Form factor and OS family
utm_source Nullable(String) You Campaign attribution
latitude ยท longitude ยท location_accuracy Float64 SDK, opt-in Only when captureLocation is enabled for the domain. 0,0 means no precise location
asset_id ยท search_term Nullable(String) Derived MATERIALIZED from the matching custom_dimensions keys
event_id UUID Server generateUUIDv4(), and part of the sort key

Build reports without writing SQL

Reports are definitions, not code. The query API compiles them to aggregate SQL against your table.

Seven aggregations

Count (all), Unique (exact), Sum, Average, Min, Max, and Latest value by event time. Applied to any allowed column or to a key inside your custom maps.

Dimensions you recognise

Grouped in the builder as Identity, Event, Time, Page, Device and Marketing โ€” User ID, Event Type, Page Path, Country, Device OS, UTM Source and the rest โ€” plus every custom key the API discovers in your own data.

Ranges and granularity

Fourteen presets from Last 1 hour through This year, or an explicit window, bucketed by minute, hour, day, week or month. The range applies to every panel at once.

Drill-down that keeps context

Click a bar and the value becomes a runtime filter on a drill-down report, right down to an individual user's event stream. Deep-linkable, so you can paste the state to a colleague.

Report suites

Group reports into suites per ClickHouse server, set a default, and copy a whole suite when you add another environment. Dashboard, toolbar and drill-down panels live side by side.

Share and embed

Mint a scoped token and embed a suite in your own application, or open the chrome-less direct-reports view. The token grants read access to reports and never exposes connection details.

Operate it properly

The parts you only appreciate once it is in production.

SSO sign-in

Google, Microsoft and any generic OIDC provider, configured per domain. Access follows your existing joiner and leaver process.

Audit logs

A platform audit trail of who changed which configuration and when, live-polling in the console, so a surprising change is traceable rather than mysterious.

Log explorer

A Loki-backed log view sits beside the reports. When an event count drops, the logs that explain it are one tab away rather than in another tool.

Tenants and sites

A tenant groups sites; a site scopes a stream. Point several sites at one database, or give each its own. Use the reserved all-sites segment for tenant-wide configuration.

Realtime panels

Live user counts bucketed by the second, as a line or a bar, with per-bucket drill-down into who is active right now.

DAM storage quotas

Purpose-built panels for AEM: a storage quota bar per folder and a stacked variant across folders, fed by scheduled snapshots from the AEM integration.

See it running

The reports page walks through every visualisation the console can render, and the documentation covers each integration end to end.