QuestDB — Time-Series Data Fabric
Platform 7 of 12·OS Layer 7 (Memory & Data Layer)·Required in all deployment modes
Scope of this page. Reference material for the QuestDB platform: what it is, what it is normally used for, and how and why Synedrix OS uses it. It is descriptive, not normative — where this page and a canonical spec in
docs/os/disagree, the canonical spec wins. Platform responsibilities are set by Tech Stack §6; the metrics that land here are defined by Observability Metrics Spec.
What QuestDB is
QuestDB’s documentation describes it as “an open source time-series database engineered for low latency”, built on “a column-oriented, time-partitioned storage engine with memory-mapped files and vectorized (SIMD) execution”. The project site’s own framing is “the open-source time-series database for demanding workloads”.
It is a SQL database, not a bespoke query language. What makes it a time-series database is that one column is privileged as the time axis, and the storage layout and the SQL dialect are both built around that column.
| Concept | Official definition |
|---|---|
| Designated timestamp | “Every table in QuestDB should have a designated timestamp. This column defines the time axis for your data and unlocks QuestDB’s core time-series capabilities.” |
| Partition | “QuestDB partitions tables by time intervals, storing each interval’s data in a separate directory.” Units are HOUR, DAY, WEEK, MONTH, YEAR, or NONE. |
| Write-ahead log (WAL) | “Write-Ahead Log (WAL) records all changes before applying them to storage.” It is “enabled by default and recommended for all tables”, and requires a partitioned table. |
SAMPLE BY | “aggregates time-series data into time-based groups (hourly, daily, etc.) and applies aggregate functions to each group” — “QuestDB’s primary tool for downsampling and summarizing large datasets”. |
LATEST ON | “Retrieves the latest entry by timestamp for a given key or combination of keys, for scenarios where multiple time series are stored in the same table.” |
ASOF JOIN | “ASOF JOIN matches each row in a time-series table with the most recent row in another time-series table whose timestamp is at or before the left row’s timestamp.” |
| Materialized view | “a special QuestDB table that stores the pre-computed results of a query”, which “persist their data to disk, making them particularly efficient for expensive aggregate queries that are run frequently”. They “require a SAMPLE BY or time-based GROUP BY query”. |
| TTL | Partition-level retention: “TTL drops partitions based on the partition’s time range, not individual row timestamps.” |
The designated timestamp is the load-bearing concept. QuestDB’s documentation lists SAMPLE BY, LATEST ON, ASOF JOIN, WINDOW JOIN, interval scans, partitioning, TTL, deduplication, materialized views, tiered storage and replication as features that all depend on it. A table without one is limited to a single partition and forfeits most of the engine.
Partitioning is what turns that into performance and retention behaviour. “The SQL optimizer skips partitions outside your query’s time range”, “Out-of-order data only rewrites affected partitions, not the entire table”, and “Different partitions can be written and read simultaneously without contention”. Retention is a directory operation rather than a scan: “Drop old data instantly with DROP PARTITION — no expensive DELETE operations”, with TTL documented as “Automatic partition cleanup by age”.
Ingestion and query paths
QuestDB deliberately separates the write path from the read path, and the protocols are not interchangeable. This matters here because throughput is the reason QuestDB is in the stack at all.
| Path | Transport and default port | What the documentation says it is for |
|---|---|---|
| QWP ingress | WebSocket, /write/v4 or /api/v4/write on the HTTP port | “QuestDB’s columnar binary protocol for high-throughput data ingestion over WebSocket.” Column-major framing lets the server decompress and commit each column independently. Optional store-and-forward persists unacknowledged segments as memory-mapped files so they survive a sender restart. |
| QWP egress | WebSocket | “Streaming SQL query results.” |
| ILP over HTTP | HTTP, port 9000 | InfluxDB Line Protocol — ingestion only. “The HTTP(s) transport is recommended for most use cases. It provides feedback on errors, automatically retries failed requests, and is easier to configure.” |
| ILP over TCP | TCP, port 9009 | Ingestion only, “slightly lower overhead than HTTP” at high throughput, but with “limited error feedback, no automatic retries, and requires manual handling of connection failures”. |
| PGWire | TCP, port 8812 | “the recommended way to query data from QuestDB, as you can use existing PostgreSQL clients and tools”. It “also supports INSERT statements for lower-volume data ingestion. For high-throughput ingestion, use the QuestDB clients instead.” |
| REST API and Web Console | HTTP, port 9000 | Ad-hoc SQL, CSV import, and the operator console. |
Two constraints follow directly from that table. PGWire is a query protocol that happens to accept inserts — it is not the bulk write path. And ILP is positioned by QuestDB as a compatibility protocol, aimed at migrations from InfluxDB, Telegraf, and existing Kafka or Flink pipelines already emitting line protocol; the documentation states that “New deployments should prefer the QuestDB Wire Protocol (QWP)”. PGWire also has documented limits worth knowing before treating QuestDB as a drop-in Postgres: no SSL, no COPY file upload, no DELETE, no BLOB transfer, and forward-only cursors.
What QuestDB is normally used for
The workloads QuestDB’s own site leads with are high-cardinality, high-frequency measurement streams where the questions asked are almost always time-bounded:
- Capital markets — tick data storage, pre- and post-trade analytics, market surveillance, order book replay, pricing algorithm analysis.
- Aerospace — real-time monitoring of in-flight systems and predictive maintenance over billions of sensor points per day.
- Energy infrastructure — SCADA and grid telemetry ingestion, smart grid decisioning, sensor stream monitoring.
- Machine and fleet telemetry — robotics telemetry and fleet observability.
- Financial services operations — retail banking and fraud detection.
The common thread is that QuestDB owns measurements over time: many small records arriving continuously, queried as windows, rollups and trends rather than as individual rows. It is not a general-purpose transactional database, and the write and read patterns it is optimised for are not the patterns a business entity store needs.
How Synedrix OS uses it
QuestDB is the temporal data layer of Synedrix OS and sits at Layer 7 (Memory & Data Layer) of the twelve-layer taxonomy, alongside Supabase, Redis, Neo4j and Qdrant. Layer 7 owns persistence of business state and contextual knowledge; QuestDB owns the slice of that which is indexed by time. It is required in all three deployment modes described in the Deployment Model Spec.
flowchart LR
n1([QuestDB]):::term
subgraph What it owns
n2[High-volume time-series records]:::agent
n3[Materialised temporal aggregations]:::agent
n4[Trend and seasonality query support]:::agent
n5[Historical event windows]:::agent
n6[Agent execution durations]:::agent
n7[Token and cost over time]:::agent
n8[Tool latency and reliability]:::agent
end
n1 --> n2
subgraph What it does not own
n9[Threshold breaches alert routing dashboards]:::warn
n10[Grafana]:::term
n9 --> n10
n11[Workflow and outcome lineage agent influence networks]:::warn
n12[Neo4j]:::term
n11 --> n12
n13[Semantic retrieval similarity search pattern recall]:::warn
n14[Qdrant]:::term
n13 --> n14
n15[Hot state idempotency keys rate-limit counters heartbeats]:::warn
n16[Redis]:::term
n15 --> n16
end
n1 --> n9
subgraph Why QuestDB
n17[It is a time-series engine not a general database asked to behave like one]:::term
n18[SQL so the temporal layer is not a silo]:::term
n19[Materialized views make derived metrics a declaration not a job]:::term
n20[Retention is expressible at the table]:::term
n21[It self-hosts as one container]:::term
end
n1 --> n17
What it owns
Per Tech Stack §6, QuestDB owns:
- High-volume time-series records
- Materialised temporal aggregations
- Trend and seasonality query support
- Historical event windows
In the stack’s Layered Truth Summary, QuestDB is assigned the Temporal truth class. That is the whole of its mandate: it is authoritative for how a measured value moved over time, and for nothing else.
Concretely, the OS signals that are time-series and therefore land here include:
- Agent execution durations — invocation latency distributions per agent and per workflow.
- Token and cost over time —
total_tokensandtotal_cost_usdfrom Observability Metrics Spec §7.3, rolled into thecost_drift_pctseries against itsbaseline_cost_window_daysbaseline slice. - Tool latency and reliability — the
p95_latency_msandtool_success_ratewindows defined in §7.7, aggregated pertool_nameandtool_version. - Event volumes — emission rates for the lifecycle events in the Event Taxonomy Standard, whose §1 names QuestDB explicitly as the temporal consumer of the event stream (“Events feed the observability layer — Langfuse (LLM traces), QuestDB (temporal), Neo4j (lineage graph), PostHog (behavioral)”).
- Quality trends — retrieval quality trend derived from
retrieval_f1_at_k(§7.1), groundedness andhallucination_probabilityrates (§7.2),semantic_validity_score(§7.4), and multi-turncoherence_score(§7.6). - Trust and SLO measurements —
trust_score_30d_avgandtrust_trend_30d(§7.10), and the rolling windows behind the SLO thresholds in §15.
The metrics spec is explicit about the split. Its §14 assigns invocation starts and terminal outcomes (agent_invocations, agent_invocation_outcomes) plus tool_invocations, evaluation_results, response_reviews, conversation_metrics, and guardrail_metrics to Supabase as audit-grade relational records, and assigns to QuestDB the “rolling trend series derived from the tables above”, with the instruction that these “MUST NOT be recomputed ad hoc from Supabase for dashboard use”.
That instruction is what SAMPLE BY and materialized views exist to satisfy. A seven-day rolling retrieval_f1_at_k average, a sixty-minute tool_success_rate window, a one-hour hallucination_flag rate, a thirty-day trust trend — each is a SAMPLE BY bucket over a designated timestamp, and each is a candidate for a materialized view that refreshes incrementally as new rows arrive rather than being recomputed per dashboard load. Seasonality questions (“does cost drift track time of day or day of week?”) are the same construct with ALIGN TO CALENDAR and a timezone. LATEST ON gives the current value per agent or per tool without a scan, and ASOF JOIN is how a measurement series is aligned against a differently-timed series — for example attaching the model version or policy configuration in force at the moment a metric was recorded.
Retention is a governance concern as much as a storage one. PARTITION BY plus TTL expresses a retention policy declaratively at the table, and drops it by partition rather than by row scan, which keeps historical event windows bounded without a deletion job.
What it does not own
The non-overlap is the point of the stack’s design. Every store in Layer 7 and Layer 10 holds one kind of truth, and a value is written to exactly one of them as its system of record.
| Concern | Owner | Why not QuestDB |
|---|---|---|
| Business entities, workflow state, approvals, audit trails, agent definitions | Supabase PG17 (Layer 7) | Canonical relational truth. These are audit-grade records needing transactional writes and relational joins to agent, workflow and conversation identifiers. |
| LLM and agent trace spans, prompt versions, per-call token and cost attribution | Langfuse (Layer 10) | Canonical LLM-engineering platform. Metric events carry the same trace_id so a flagged aggregate in QuestDB can be traced back to the exact LLM call. |
| Threshold breaches, alert routing, dashboards | Grafana (Layer 10) | Grafana is the operational-monitoring surface. It visualises QuestDB; QuestDB remains the system of record. |
| Workflow and outcome lineage, agent influence networks | Neo4j (Layer 7) | Graph truth. Relationship traversal, not time buckets. |
| Semantic retrieval, similarity search, pattern recall | Qdrant (Layer 7) | Semantic truth. Vector similarity, not temporal ordering. |
| Hot state, idempotency keys, rate-limit counters, heartbeats | Redis (Layer 7) | Ephemeral truth. In-flight coordination that is not retained. |
Two boundaries deserve stating plainly, because they are the ones most easily collapsed:
- QuestDB against Supabase. Supabase holds the record of what happened — one row per invocation, joinable and auditable. QuestDB holds the record of how it trended — the derived series over those rows. The same number may appear in both, but only one of them is the system of record for a given question, and dashboards read the trend from QuestDB.
- QuestDB against Langfuse. Langfuse holds the individual trace, in full fidelity, for debugging a single call. QuestDB holds the aggregate over many calls, for detecting that something changed. Correlation between them is by
trace_id, not by duplication.
Neither store is a substitute for the other, and the metrics spec is unambiguous that events are the single normalized ingestion path: they “MUST be emitted regardless of which platform ultimately persists the derived value”, with “platform-specific write paths … downstream consumers, not sources”. QuestDB is therefore fed from the event bus, not written to directly by agents.
How it is operated
QuestDB ships as a single official Docker image, questdb/questdb, with a documented port layout that maps directly onto the ingestion and query split above: 9000 for the REST API and Web Console, 9009 for InfluxDB line protocol, 8812 for the Postgres wire protocol, and 9003 for the min health server. Persistence is a single volume mount at /var/lib/questdb, which “will have all data ingested to QuestDB, server logs and configuration”, and which allows a version upgrade while retaining existing data and configuration.
The self-hosted reference stack in synedrix-os-stack-self-hosted runs QuestDB as the questdb-core service on the synedrix_core Docker network with all four ports published, a questdb_core_data volume at /var/lib/questdb, a health check against :9003/status, and raised file descriptor limits — QuestDB is IO-intensive and memory-maps its column files. Port 9000 is taken by QuestDB across the whole stack, which is why the Langfuse and observability compose files remap their own services off it.
WAL is enabled by default and is a prerequisite for concurrent writes, efficient out-of-order merge of late-arriving data, deduplication, and replication. Since the OS ingests from an event bus where late and duplicate delivery are expected, WAL plus partitioning plus deduplication on the designated timestamp is the configuration that matches the event taxonomy’s delivery assumptions rather than fighting them.
The temporal memory tier
QuestDB backs the temporal tier in the Memory Fabric Spec, unchanged in substance from the temporal-memory role it already held: time-series measurements and their aggregations, consumed by the intelligence agents.
The memory control plane adds one consumer. Fabric-level observability — memory growth rate, records by tier, staleness ratio, consolidation lag — is aggregated here from the memory.* event stream (Observability Metrics Spec §7.11). These are measurements about the memory fabric rather than memory records themselves, which is why they land in the temporal tier rather than becoming a tier of their own.
There is one lifecycle interaction worth knowing. When an operational-class record’s retention window closes, it may be aggregated into a temporal summary before removal, so the shape of a history survives the deletion of its detail. That is a decay path, not an erasure path: erasure is the approval-gated route described in the memory spec §8.4, and it leaves a tombstone.
Why QuestDB
- It is a time-series engine, not a general database asked to behave like one. Layer 7 already has a relational system of record. What it did not have was something that could absorb continuous measurement at rate and answer window queries in milliseconds. Column-oriented, time-partitioned storage with SIMD execution is that, and nothing in the rest of the stack duplicates it.
- SQL, so the temporal layer is not a silo.
SAMPLE BY,LATEST ONandASOF JOINare extensions to SQL rather than a separate query language, and PGWire means existing Postgres clients and tooling reach it unchanged. The cost of adding a specialist store is kept to learning four operators. - Materialized views make derived metrics a declaration, not a job. The metrics spec forbids recomputing trend series ad hoc from Supabase. A materialized view over a
SAMPLE BYquery, refreshing incrementally as the base table grows, is that rule implemented in the database rather than in a scheduled workflow that can silently fail. - Retention is expressible at the table.
PARTITION BYplusTTLbounds historical event windows by policy, and drops them as directory operations rather than mass deletes — which is what makes “keep the last 90 days of every agent metric” an affordable default. - It self-hosts as one container. A single image, a single data volume, no external dependency, no phone-home. That is what Modes 2 and 3 require, and it is consistent with Principle 11 (Open by default, sovereign by design) in the Core Principles.
Deployment and licensing
Self-hosting. Documented deployment paths are Docker, Kubernetes, systemd, and cloud-provider guides for AWS, Azure, GCP, Digital Ocean and Hetzner. The Docker path is the one the Synedrix OS self-hosted stack uses.
Licence — verified. QuestDB’s core repository, questdb/questdb, carries LICENSE.txt containing the Apache License, Version 2.0, and GitHub reports the repository licence as Apache-2.0. Tech Stack and the Deployment Model Spec both record QuestDB as Apache 2.0, and both are accurate as licensed today. No correction is required, and unlike n8n there is no restriction on commercial use or on providing the software to others.
Editions. QuestDB is sold in two editions. QuestDB Enterprise “offers the entire feature set of QuestDB open source, with premium additions” and requires “an active license”. The open-source core is complete for the workload described on this page; the Enterprise additions documented in the quick-start are replication, storage policies (automated conversion of older partitions to Parquet on a schedule, then eventual drop), and ZFS compression, alongside high availability, advanced security, RBAC, automated backups, and multi-tier object storage integration.
Normative trend DDL
The OS-owned QuestDB table and materialized-view naming for rolling observability trends are defined in Synedrix OS Observability Metrics Spec §14a (metrics_samples, mv_<metric_name>_<window>). This platform page remains descriptive for QuestDB capabilities; that section is normative for Synedrix OS schema.
Open item. The licence claim is correct, but the availability boundary is worth an explicit decision. QuestDB’s documentation states plainly that “Replication is Enterprise only.” Synedrix OS marks QuestDB as required in all three deployment modes, including air-gapped Mode 3, and the Apache 2.0 core therefore offers no built-in high availability or disaster recovery for the temporal layer — a single-node QuestDB is a single point of failure for every trend series, SLO window and materialized view described above. Options are to accept single-node operation with backup-and-restore for temporal data, to treat temporal data as reconstructible from Supabase and the event bus after a loss, or to licence Enterprise. This page does not resolve it, and does not change the canonical stack document.
Official documentation
- QuestDB documentation home
- Designated timestamp
- Partitions
- Write-ahead log
- TTL
- Materialized views
SAMPLE BY·LATEST ON·ASOF JOIN- Wire protocols overview — QWP ingress and egress
- InfluxDB Line Protocol overview — HTTP and TCP transports
- PGWire overview
- Docker deployment — image, ports, volumes
- Database replication — Enterprise only
- Enterprise quick start
questdb/questdbLICENSE.txt— Apache License 2.0
Related Synedrix OS documents
- Memory Fabric Spec — The
temporaltier and the decay path that aggregates before removal. - Synedrix OS Tech Stack — normative platform responsibilities; §6 covers QuestDB, and the Layered Truth Summary assigns it the Temporal truth class.
- Observability Metrics Spec — the canonical metric families and events that become time-series here; §14 sets the QuestDB / Supabase / Langfuse / Grafana storage split and §15 the SLO windows.
- Layer Taxonomy Table — Layer 7 definition and platform mapping.
- Event Taxonomy Standard — the event envelope and lifecycle events feeding the temporal layer.
- Outcome Spec — the Outcome Envelope whose measurements are aggregated over time.
- Core Principles — Principle 11 (Open by default, sovereign by design), which the licence position supports.
- Deployment Model Spec — QuestDB’s presence and licence in all three deployment modes.
Synedrix OS · Platform reference · QuestDB