Solutions · Product analytics

Product analytics, on infrastructure you control.

Ingest events at scale on managed ClickHouse, pre-aggregate with materialized views, and serve customer-facing dashboards with sub-second response. EU-hosted.

Stop renting your analytics database

Vendor product-analytics tools are expensive at scale and opaque on data ownership. ClickHouse on Luceris gives you the same speed (often faster — vectorized execution, columnar compression, materialized aggregates) on infrastructure you control. Bring your own event schema, write your own queries, expose the results in your own UI.

MergeTree for raw events

Order by `(ts, user_id)` for time-range scans; partition by month for cheap retention enforcement.

Materialized views for aggregates

Pre-aggregate funnel steps, retention cohorts, and DAU/MAU at insert time. Queries against the aggregate complete in milliseconds.

JSON column for flexible payloads

New event types do not require a schema migration — store the payload as JSON, extract fields with `JSONExtract*` functions.

S3 cold storage for old data

TTL moves data older than 90 days to S3-backed storage; queries still work, just at lower latency.

Code sample

sql
Event table + DAU materialized view
CREATE TABLE events (
  ts        DateTime CODEC(DoubleDelta, ZSTD(1)),
  user_id   UInt64,
  kind      LowCardinality(String),
  payload   JSON
) ENGINE = MergeTree
PARTITION BY toYYYYMM(ts)
ORDER BY (ts, user_id)
TTL ts + INTERVAL 365 DAY TO DISK 'cold';

-- Materialized view: daily-unique-active-users, per event kind.
CREATE MATERIALIZED VIEW events_dau
ENGINE = AggregatingMergeTree
ORDER BY (day, kind)
AS SELECT
  toDate(ts) AS day,
  kind,
  uniqState(user_id) AS users
FROM events
GROUP BY day, kind;

-- Read DAU in milliseconds for the last 30 days.
SELECT day, kind, uniqMerge(users) AS dau
FROM events_dau
WHERE day >= today() - 30
GROUP BY day, kind
ORDER BY day DESC, dau DESC;

Ingest pipeline

Two common patterns: (1) your app writes events to Kafka; a ClickHouse Kafka engine table consumes them and a materialized view inserts into the main table. (2) Your app POSTs JSON batches to /clickhouse over HTTP; ClickHouse parses them with `INSERT … FORMAT JSONEachRow`. Pattern (1) scales further; pattern (2) is simpler to start.

Examples

  • Funnel analysis — first event, drop-off per step, cohort comparisons
  • Retention curves — Day-N return rate by signup cohort
  • In-app analytics dashboards — surface usage stats to your customers
  • Conversion attribution — multi-touch attribution across event streams
  • A/B test analysis — significance over millions of events

Frequently asked questions

How is this different from Amplitude or Mixpanel?
You own the database, the schema, and the queries. Pricing is per-cluster-resource, not per-event. Data stays in the EU on infrastructure under your contract.
What ingestion rate can a Free cluster handle?
The Free tier is sized for prototyping — a few thousand events per second is comfortable. Production workloads (hundreds of thousands to millions of events per second) need the Contact-us tier.
Can I run my analytics queries against the materialized view directly?
Yes — that's the whole point. The view is a real table you can query with `SELECT`, `JOIN`, `WHERE`. Use `uniqMerge`, `sumMerge`, etc. to finalize the aggregate state.

Product analytics that scale with your traffic, not your bill.

Free tier ClickHouse cluster with 10 GB compressed storage — enough for a real prototype.