Data Analyst
You own: answering business questions with data — including questions about model performance, cost, and drift.
What's new for you
| Was | Now in GeneFlow |
|---|---|
| ML metrics in slide decks | All in the warehouse via gf_* exports |
| Cost-per-prediction was opaque | gf_inference_logs.cost_usd is queryable |
| No way to answer "which model serves this product?" | Lineage + gf_endpoints joined |
Day-1 setup
You don't write code against GeneFlow directly — you query the gf_* tables in your warehouse (replicated via CDC). Talk to your AE if they aren't there yet.
Workflow 1 — Per-product model health
SELECT
e.name AS endpoint,
e.model_name,
e.model_version,
AVG(l.latency_ms)::INT AS avg_latency_ms,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY l.latency_ms) AS p95_latency_ms,
100.0 * AVG(CASE WHEN l.status_code >= 400 THEN 1 ELSE 0 END) AS error_rate_pct,
COUNT(*) AS reqs
FROM gf_endpoints e
LEFT JOIN gf_inference_logs l
ON l.endpoint_id = e.id AND l.ts >= now() - INTERVAL '24 hours'
WHERE e.tenant_id = 'ACME' AND e.status = 'READY'
GROUP BY e.name, e.model_name, e.model_version
ORDER BY reqs DESC;
Workflow 2 — Cost vs. revenue per model
SELECT
e.model_name,
SUM(l.cost_usd) AS daily_inference_cost,
SUM(l.cost_usd) * 365 AS annualized_cost,
COUNT(*) AS daily_inferences
FROM gf_endpoints e
JOIN gf_inference_logs l ON l.endpoint_id = e.id
WHERE l.ts >= now() - INTERVAL '1 day'
GROUP BY e.model_name
ORDER BY daily_inference_cost DESC;
Join to your revenue tables for cost-of-prediction-as-% of revenue.
Workflow 3 — Drift incidents over time
SELECT date_trunc('day', fired_at) AS day,
severity,
COUNT(*) AS firings
FROM gf_drift_alerts
WHERE tenant_id='ACME' AND fired_at >= now() - INTERVAL '30 days'
GROUP BY 1, 2 ORDER BY 1 DESC;
Workflow 4 — Compare model versions in production
-- Yesterday's inferences split by version
SELECT model_version,
COUNT(*) AS reqs,
AVG(latency_ms)::INT AS avg_ms,
SUM(cost_usd) AS cost
FROM gf_inference_logs
WHERE endpoint_id = 'ep_abc...' AND ts >= now() - INTERVAL '1 day'
GROUP BY model_version;
Useful during canary rollouts.
Workflow 5 — Cohort: prompts in Production
SELECT name,
MAX(version) FILTER (WHERE current_stage='Production') AS prod_version,
MAX(version) AS latest_version
FROM gf_prompt_versions
WHERE tenant_id='ACME'
GROUP BY name;
Common gotchas
gf_inference_logsis sampled — production endpoints with high QPS sample at 1% by default. Don't trust raw counts for revenue calcs; trust rates.- Tenant filter on every query — multi-tenant. Mistakes mix tenants.
feature_snapshotis JSONB —feature_snapshot->>'amount'returns text; cast to numeric before aggregating.
Where to go next
- 10-bi-developer.md — for dashboards
- GLOSSARY.md — definitions
- api-reference.md — for live API queries