---
title: "Postgres + TimescaleDB for AI Voice Metrics: Hypertables That Don't Slow Down (2026)"
description: "Voice agents emit ASR latency, TTS latency, barge-in counts, and turn-level token use. TimescaleDB's hypertables + continuous aggregates handle billions of rows while keeping dashboards under 200 ms."
canonical: https://callsphere.ai/blog/vw7h-postgres-timescaledb-ai-voice-metrics-2026
category: "AI Infrastructure"
tags: ["TimescaleDB", "Postgres", "Voice AI", "Observability", "Metrics"]
author: "CallSphere Team"
published: 2026-03-29T00:00:00.000Z
updated: 2026-05-07T22:22:41.509Z
---

# Postgres + TimescaleDB for AI Voice Metrics: Hypertables That Don't Slow Down (2026)

> Voice agents emit ASR latency, TTS latency, barge-in counts, and turn-level token use. TimescaleDB's hypertables + continuous aggregates handle billions of rows while keeping dashboards under 200 ms.

> **TL;DR** — TimescaleDB turns Postgres into a time-series engine optimized for ingest + downsampled rollups. For AI voice telemetry — ASR, TTS, LLM turn latencies — it gives you Prometheus-grade queries while staying in your transactional DB.

## What you'll build

A `voice_metrics` hypertable storing per-turn measurements, two continuous aggregates (1-minute and 1-hour rollups), and a Grafana panel that powers a real-time voice agent SLO dashboard.

## Schema

```sql
CREATE EXTENSION IF NOT EXISTS timescaledb;

CREATE TABLE voice_metrics (
  ts TIMESTAMPTZ NOT NULL,
  tenant_id UUID NOT NULL,
  agent_id UUID NOT NULL,
  call_id UUID NOT NULL,
  asr_ms INT,
  llm_ms INT,
  tts_ms INT,
  total_ms INT,
  barge_in BOOLEAN DEFAULT false,
  tokens_in INT,
  tokens_out INT
);

SELECT create_hypertable('voice_metrics', 'ts',
  chunk_time_interval => INTERVAL '1 day');

CREATE INDEX ON voice_metrics (tenant_id, ts DESC);
CREATE INDEX ON voice_metrics (agent_id, ts DESC);
```

## Architecture

```mermaid
flowchart LR
  AGENT[Voice agent turn] --> EMIT[Emit metric]
  EMIT --> HYP[(voice_metrics
hypertable)]
  HYP --> CAG1[1-min continuous agg]
  HYP --> CAG2[1-hour continuous agg]
  CAG1 --> GRAFANA[Grafana SLO panel]
  CAG2 --> ALERTS[Alertmanager]
```

## Step 1 — Continuous aggregates

```sql
CREATE MATERIALIZED VIEW voice_metrics_1min
WITH (timescaledb.continuous) AS
SELECT time_bucket('1 minute', ts) AS bucket,
       tenant_id, agent_id,
       avg(total_ms) AS avg_ms,
       percentile_cont(0.95) WITHIN GROUP (ORDER BY total_ms) AS p95_ms,
       count(*) AS turns,
       sum((barge_in)::int) AS barges
FROM voice_metrics
GROUP BY bucket, tenant_id, agent_id;

SELECT add_continuous_aggregate_policy('voice_metrics_1min',
  start_offset => INTERVAL '2 hours',
  end_offset   => INTERVAL '1 minute',
  schedule_interval => INTERVAL '30 seconds');
```

## Step 2 — Compression policy

```sql
ALTER TABLE voice_metrics SET (
  timescaledb.compress,
  timescaledb.compress_segmentby = 'tenant_id, agent_id',
  timescaledb.compress_orderby = 'ts DESC'
);

SELECT add_compression_policy('voice_metrics', INTERVAL '7 days');
```

Compressed chunks shrink by 10–30x, query speed actually increases.

## Step 3 — Retention policy

```sql
SELECT add_retention_policy('voice_metrics', INTERVAL '180 days');
```

Old chunks drop automatically — no manual cleanup, no DELETE bloat.

## Step 4 — Emit metrics from the agent

```ts
import { prisma } from "@/lib/db";

export async function recordTurn(m: {
  tenantId: string; agentId: string; callId: string;
  asrMs: number; llmMs: number; ttsMs: number;
  tokensIn: number; tokensOut: number; bargeIn: boolean;
}) {
  await prisma.$executeRaw`
    INSERT INTO voice_metrics (
      ts, tenant_id, agent_id, call_id,
      asr_ms, llm_ms, tts_ms, total_ms,
      tokens_in, tokens_out, barge_in
    ) VALUES (
      now(), ${m.tenantId}::uuid, ${m.agentId}::uuid, ${m.callId}::uuid,
      ${m.asrMs}, ${m.llmMs}, ${m.ttsMs}, ${m.asrMs + m.llmMs + m.ttsMs},
      ${m.tokensIn}, ${m.tokensOut}, ${m.bargeIn}
    )
  `;
}
```

## Step 5 — Query for dashboards

```sql
SELECT bucket, p95_ms, turns, barges
FROM voice_metrics_1min
WHERE tenant_id = $1
  AND bucket >= now() - interval '6 hours'
ORDER BY bucket;
```

Grafana hits this directly via the Postgres data source.

## Step 6 — Alert when p95 budget breaks

```yaml
# alertmanager / Grafana alert rule
expr: voice_metrics_p95_ms{agent="appointments"} > 1500
for:  5m
labels: { severity: page }
```

## Pitfalls

- **Chunk interval too small** — 1-hour chunks at 10k rps create millions of chunks. Stick to 1 day for typical voice loads.
- **Continuous agg without policy** — view exists but never refreshes. Add the policy.
- **Querying raw table for dashboards** — always hit the continuous aggregate; raw is for forensics.
- **Compression before retention** — order matters. Compress first, retain second.

## CallSphere production note

CallSphere's voice telemetry hypertable powers per-tenant SLO dashboards across **115+ DB tables** and **37 agents**. Healthcare's HIPAA bucket lives on a separate `healthcare_voice` Prisma schema with stricter retention; OneRoof aggregates per-property metrics under RLS; UrackIT mirrors counters into Supabase + ChromaDB. **90+ tools · 6 verticals**, p95 dashboard load <180 ms even at 6 months retention. Plans: $149/$499/$1,499 — 14-day trial, 22% affiliate.

## FAQ

**Q: TimescaleDB or vanilla partitioned Postgres?**
Continuous aggregates and compression are the wins. Below ~10M rows/day, vanilla works.

**Q: Does TimescaleDB break logical replication?**
Hypertables replicate fine if both sides have the extension installed.

**Q: Compression hurts ad-hoc queries?**
The opposite — compressed columns are faster to scan than uncompressed ones.

**Q: Can I use Tiger Data Cloud (managed)?**
Yes — same hypertable API, fully managed; pricing scales with data volume.

**Q: Continuous aggregates lag behind by how much?**
Refreshed every 30 sec by policy. Last minute is approximate, prior minutes are exact.

## Sources

- [Tiger Data — Hypertables intro](https://www.tigerdata.com/learn/when-to-consider-postgres-partitioning)
- [Cekura — Voice agent monitoring platforms 2026](https://www.cekura.ai/blogs/voice-agent-monitoring-platforms)
- [Hamming — Voice observability framework](https://hamming.ai/blog/voice-agent-observability-voice-observability)
- [Hamming — Voice agent evaluation metrics](https://hamming.ai/resources/voice-agent-evaluation-metrics-guide)

---

Source: https://callsphere.ai/blog/vw7h-postgres-timescaledb-ai-voice-metrics-2026
