Real-Time Analytics & Dashboards
HeliosDB Lite serves real-time dashboards from the database that takes the writes, without an ETL copy to a warehouse: columns used in aggregations are declared STORAGE COLUMNAR so analytical scans read only the columns they need, EXPLAIN classifies each query as OLTP or OLAP, and dashboard queries run in plain SQL over the PostgreSQL wire or the REST API.
Executive Summary
Key value propositions:
- Zero lag between data ingestion and dashboard visibility
- Instant schema changes (no materialized view rebuild delays)
Problem Being Solved
The Real-Time Analytics Paradox
Problems:
- Data staleness: Dashboard shows data from hours/days ago
- Infrastructure complexity: 3 systems to manage (app DB, ETL, warehouse)
- Operational burden: Data engineers debugging ETL failures
- Consistency issues: Data warehouse may diverge from source-of-truth
- Schema migration nightmare: Changes require ETL reconfiguration
Enterprise Pain Points
Operational Burden:
- ETL failures happen daily (data consistency issues)
- Data refresh delays cause customer complaints
- Schema changes require coordinated updates across all systems
- Query optimization requires dedicated analytics engineer
- Data governance becomes fragmented across systems
Analytical Limitations:
- Real-time analytics impossible (hourly refresh at best)
- Data consistency issues (warehouse diverges from source)
- Cannot easily join real-time + historical data
- Complex transformations lose data provenance
Implementation Examples
Example 2: Real-Time Dashboard Frontend (React)
import React, { useState, useEffect } from 'react';
export function RealtimeDashboard() {
const [metrics, setMetrics] = useState(null);
const [connected, setConnected] = useState(false);
useEffect(() => {
// Server-Sent Events for real-time updates
const eventSource = new EventSource('/api/metrics/stream');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
setMetrics(data);
};
eventSource.onerror = () => {
setConnected(false);
eventSource.close();
};
eventSource.onopen = () => {
setConnected(true);
};
return () => eventSource.close();
}, []);
if (!connected || !metrics) {
return <div>Connecting to dashboard...</div>;
}
return (
<div className="dashboard">
<div className="metrics-grid">
<MetricCard
label="Total Revenue"
value={`$${metrics.total_revenue.toLocaleString()}`}
trend="+12%"
/>
<MetricCard
label="Average Order"
value={`$${metrics.avg_order_value.toFixed(2)}`}
trend="+3%"
/>
<MetricCard
label="Total Orders"
value={metrics.total_orders.toLocaleString()}
trend="+8%"
/>
<MetricCard
label="New Customers"
value={metrics.new_customers.toLocaleString()}
trend="+15%"
/>
</div>
<div className="last-updated">
Last updated: {new Date(metrics.timestamp * 1000).toLocaleTimeString()}
</div>
</div>
);
}
function MetricCard({ label, value, trend }) {
return (
<div className="metric-card">
<div className="metric-label">{label}</div>
<div className="metric-value">{value}</div>
<div className="metric-trend">{trend}</div>
</div>
);
}
Example 3: Advanced Analytics Queries (SQL)
-- 1. Top products by revenue (real-time)
SELECT
product_id,
product_name,
SUM(amount) as revenue,
COUNT(*) as order_count,
AVG(amount) as avg_order_value
FROM orders
WHERE timestamp > datetime('now', '-24 hours')
GROUP BY product_id, product_name
ORDER BY revenue DESC
LIMIT 10;
-- 2. Customer cohort analysis with trending
SELECT
DATE(registration_date) as cohort_date,
COUNT(DISTINCT customer_id) as new_customers,
SUM(CASE WHEN DATE(order_timestamp) = DATE('now')
THEN 1 ELSE 0 END) as active_today,
SUM(amount) as total_revenue,
AVG(amount) as avg_order_value
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
GROUP BY cohort_date
ORDER BY cohort_date DESC;
-- 3. Real-time conversion funnel (with vector search for related products)
SELECT
'visit' as stage,
COUNT(DISTINCT session_id) as count,
COUNT(DISTINCT session_id)::float /
MAX(COUNT(DISTINCT session_id)) OVER () as conversion_rate
FROM pageviews
WHERE timestamp > datetime('now', '-1 hour')
UNION ALL
SELECT
'add_to_cart' as stage,
COUNT(DISTINCT session_id) as count,
COUNT(DISTINCT session_id)::float /
(SELECT COUNT(DISTINCT session_id) FROM pageviews
WHERE timestamp > datetime('now', '-1 hour')) as conversion_rate
FROM cart_events
WHERE timestamp > datetime('now', '-1 hour')
UNION ALL
SELECT
'purchase' as stage,
COUNT(DISTINCT order_id) as count,
COUNT(DISTINCT order_id)::float /
(SELECT COUNT(DISTINCT session_id) FROM pageviews
WHERE timestamp > datetime('now', '-1 hour')) as conversion_rate
FROM orders
WHERE timestamp > datetime('now', '-1 hour');
-- 4. Correlation analysis (products bought together)
WITH product_pairs AS (
SELECT
o1.product_id as product_1,
o2.product_id as product_2,
COUNT(*) as co_purchase_count
FROM orders o1
JOIN orders o2 ON o1.order_id = o2.order_id
AND o1.product_id < o2.product_id
WHERE o1.timestamp > datetime('now', '-30 days')
GROUP BY product_1, product_2
)
SELECT
p1.product_name as product_1_name,
p2.product_name as product_2_name,
co_purchase_count,
co_purchase_count::float /
(SELECT SUM(co_purchase_count) FROM product_pairs) as correlation
FROM product_pairs
JOIN products p1 ON p1.product_id = product_1
JOIN products p2 ON p2.product_id = product_2
ORDER BY co_purchase_count DESC
LIMIT 20;
-- 5. Anomaly detection (unusual patterns)
SELECT
DATE(timestamp) as date,
SUM(amount) as daily_revenue,
AVG(SUM(amount)) OVER (ORDER BY DATE(timestamp)
ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) as avg_7_day,
STDDEV(SUM(amount)) OVER (ORDER BY DATE(timestamp)
ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) as stddev_7_day,
CASE
WHEN ABS(SUM(amount) - AVG(SUM(amount)) OVER
(ORDER BY DATE(timestamp) ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)) >
2 * STDDEV(SUM(amount)) OVER
(ORDER BY DATE(timestamp) ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)
THEN 'ANOMALY'
ELSE 'NORMAL'
END as status
FROM orders
WHERE timestamp > datetime('now', '-90 days')
GROUP BY DATE(timestamp)
ORDER BY date DESC;
Example 5: Docker Compose - Analytics Stack
# Dockerfile - Analytics application
FROM rust:latest as builder
WORKDIR /app
COPY Cargo.* ./
COPY src ./src
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y curl
COPY --from=builder /app/target/release/analytics-app /usr/local/bin/
RUN mkdir -p /data && chmod 700 /data
RUN useradd -m -u 1000 app
USER app:app
EXPOSE 8080 3000
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/health || exit 1
ENTRYPOINT ["analytics-app"]
# docker-compose.yml - Complete analytics stack
version: '3.8'
services:
# HeliosDB-Lite analytics backend
analytics-api:
build: .
environment:
RUST_LOG: info
DATABASE_PATH: /data/analytics.db
BIND_ADDRESS: 0.0.0.0:8080
volumes:
- analytics-data:/data
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 3s
retries: 3
# Frontend dashboard
dashboard:
image: node:18-alpine
working_dir: /app
volumes:
- ./dashboard:/app
- /app/node_modules
ports:
- "3000:3000"
environment:
REACT_APP_API_URL: http://localhost:8080
command: npm start
depends_on:
- analytics-api
# Event ingestion service
event-collector:
image: node:18-alpine
working_dir: /app
volumes:
- ./collector:/app
- /app/node_modules
environment:
ANALYTICS_API_URL: http://analytics-api:8080
KAFKA_BROKERS: kafka:9092
depends_on:
- analytics-api
- kafka
command: npm start
# Kafka for high-volume event streaming (optional)
kafka:
image: confluentinc/cp-kafka:latest
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
depends_on:
- zookeeper
zookeeper:
image: confluentinc/cp-zookeeper:latest
environment:
ZOOKEEPER_CLIENT_PORT: 2181
volumes:
analytics-data:
Conclusion
- Real-time data freshness
- Affordable economics
- Operational simplicity
Performance depends on workload and hardware. Published figures are measured on representative fixtures; see the benchmarks page and reproduce them on your own workload.