DBRaven
Full ReviewModerate Readinessdraft

Architecture Review: Observability Platform

A metrics, logs, and traces ingestion and query platform built to absorb the telemetry output of a production system fleet: including the telemetry volume spikes that accompany the incidents the platform is meant to detect. ClickHouse stores metrics data with automatic time-based rollup via continuous materialized views; TimescaleDB provides complementary time-series storage for high-cardinality alert evaluation; Kafka buffers the ingestion stream against downstream write pressure, decoupling ingest acceptance rate from storage write throughput; Elasticsearch serves log full-text search and structured field filtering; Redis caches dashboard query results and active alert state for sub-100ms alert evaluation latency. The alert engine evaluates threshold and anomaly rules against pre-computed materialized views, not raw data, to bound alert evaluation cost independent of ingestion volume.

Evidence Confidence

Moderate

strong

Executive Summary

Observability Platform: moderate operational readiness (81% evidence confidence). 0 architectural strengths identified, 6 operational risks to manage. Primary concern: Disk I/O Saturation. Requires Advanced operational maturity.

Readiness Rationale

Overall moderate readiness across 8 dimensions. Limited: team maturity. Strong: migration, observability, failure recovery.

Key Concerns

  • !Disk I/O Saturation
  • !Hot Partition

Key Strengths

  • +Architecture is well-defined for the analytics pipeline problem profile

8

Assessments

3

Tradeoffs

6

Sections

11

Recommendations

Readiness Assessments

8

Architectural Tradeoffs

3

Recommendations

11
High

Monitor: Disk I/O Saturation

risk_monitoring

The storage device reaches its IOPS or throughput ceiling, causing all disk- dependent database operations to queue behind I/O requests, driving latency from sub-millisecond to hundreds of milliseconds and degrading all database operations simultaneously.

Affects 1 node. (Time-Series Metrics)

High

Monitor: Hot Partition

risk_monitoring

One partition (a database shard, a Kafka topic partition, a Redis hash slot) receives traffic so far above its peers that it saturates while the others sit idle. Aggregate capacity looks healthy, but the hot partition throttles or lags, and everything routed to it degrades. The cause is skew in how keys map to partitions, and the fix depends on whether the skew is spread across many keys or concentrated in one.

Affects 0 nodes

High

Implement: Monitor generic risk probe signals

observability

Seed 'Disk I/O Saturation Risk Probe' identifies 2 metrics relevant to disk_io_saturation.

Metrics to instrument: error_rate, p95_latency_ms

Moderate

Prometheus + Grafana stack with local time-series storage → Kafka-buffered ClickHouse ingestion with Redis-backed alert evaluation

migration_planning

Trigger: Prometheus storage limits reached at production metric volume; ClickHouse required for sub-second aggregate queries across multi-day windows that Prometheus cannot serve; need to retain metrics beyond Prometheus 15-day default retention without capacity-limited remote write targets; cross-service correlation queries not possible in PromQL. Migrate from 'Prometheus + Grafana stack with local time-series storage' to 'Kafka-buffered ClickHouse ingestion with Redis-backed alert evaluation'. Migrate dashboards domain by domain (infrastructure first, then application metrics) rather than all at once. Run Prometheus and ClickHouse in parallel for 30 days, validating that dashboard values match before switching alert evaluation to ClickHouse.

Prometheus metric naming conventions and label schemas must be preserved exactly in ClickHouse: a schema transformation at migration time breaks all existing Grafana dashboards; Alert rules expressed in PromQL must be rewritten for the new alert evaluation engine: the migration window requires running both systems in parallel and validating alert equivalence

Moderate

Log shipping directly to Elasticsearch without Kafka buffer → Kafka-buffered log ingestion with backpressure and sampling controls

migration_planning

Trigger: Elasticsearch indexing pressure causing log rejection (HTTP 429) back-pressuring into application services during incidents; log volume spikes during incidents causing Elasticsearch cluster instability; inability to replay historical logs when the indexing pipeline falls behind. Migrate from 'Log shipping directly to Elasticsearch without Kafka buffer' to 'Kafka-buffered log ingestion with backpressure and sampling controls'. Set Kafka log topic retention to 24 hours minimum. Deploy the Kafka-to-Elasticsearch consumer with auto-scaling enabled before switching log producers to write to Kafka. Validate consumer throughput at 10x normal volume with a load test before production cutover.

Introducing Kafka adds infrastructure complexity for the log shipping agents: every application must be updated to write to Kafka instead of directly to Elasticsearch; Kafka retention must be set to at least the Elasticsearch indexing catch-up time under worst-case incident volume: insufficient retention causes log loss if indexing falls behind more than the retention window

Moderate

Prepare runbook for: Burst Traffic Cold Cache Stampede

simulation_preparedness

Simulation demonstrates critical degradation of redis, postgresql

Without a runbook, recovery from this failure mode will be ad-hoc

burst-traffic-cold-cache-stampede
Moderate

Prepare runbook for: CQRS Projection Lag Expansion

simulation_preparedness

Simulation demonstrates critical degradation of postgresql, kafka

Without a runbook, recovery from this failure mode will be ad-hoc

cqrs-projection-lag-expansion
Moderate

Plan evolution: OLTP Analytics Queries → OLTP + OLAP Separation

evolution_planning

Evolution from Unified OLTP + Analytics on PostgreSQL → Separated OLTP (PostgreSQL) + OLAP (ClickHouse/Snowflake)

Migration complexity: medium. Rollback: always.

oltp-analytics-to-separated
Moderate

Plan evolution: Single Cache Layer → Distributed Cache

evolution_planning

Evolution from Single Redis Node / Sentinel Cluster → Distributed Redis Cluster (Consistent Hash Ring)

Migration complexity: medium. Rollback: complex.

single-cache-to-distributed
Low

Monitor threshold: Tier 1: Metric Cardinality Budget Exceeded

scaling_monitoring

Signal: ClickHouse part merge frequency increasing; dashboard queries timing out on metrics with high label cardinality; ClickHouse system.metrics showing active_parts count elevated; new metric instrumentation causing sudden storage growth disproportionate to fleet size; query_log showing metrics queries scanning full column segments without pruning

Bottleneck: Unbounded label cardinality generating millions of distinct time series that exceed ClickHouse part merge capacity and query planner pruning effectiveness. Evolution: Enforce a cardinality budget at ingestion: before a metric is accepted, evaluate the distinct value count of each label dimension against a per-dimension limit (e.g., max 100 distinct values for any single label key). Reject or rewrite metrics that exceed the budget: rewrite user_id labels to user_cohort or drop them entirely. Implement a cardinality analysis dashboard showing the top 10 highest-cardinality metric series sorted by storage cost. ClickHouse distributed table partitioning by metric name reduces the impact of a single high-cardinality metric on global query performance.

Low

Monitor threshold: Tier 2: Log Volume Spike Exceeding Consumer Throughput

scaling_monitoring

Signal: Kafka log topic consumer lag growing > 1 million messages during incident periods; Elasticsearch indexing throughput metrics showing queue buildup; incident post-mortems noting that relevant log records were not available in the search interface during the incident; log consumer memory pressure from unbounded batch accumulation

Bottleneck: Log Kafka consumer sized for normal throughput; unable to drain the spike volume produced during incident-driven log floods. Evolution: Size the log consumer for 10x normal throughput, not 1x: observability platform capacity must be planned for the incident scenario, not the steady state. Implement consumer autoscaling triggered by consumer lag metric: when Kafka consumer lag exceeds a threshold, add consumer instances automatically. Implement log sampling at the producer side for DEBUG and INFO level messages during identified spike periods : preserve all ERROR and WARN messages, sample INFO at 10%, sample DEBUG at 1%. This bounds the worst-case log volume without sacrificing diagnostic signal.

Scaling Pressure Signals

8

ClickHouse part merge frequency increasing; dashboard queries timing out on metrics with high label cardinality; ClickHouse system.metrics showing active_parts count elevated; new metric instrumentation causing sudden storage growth disproportionate to fleet size; query_log showing metrics queries scanning full column segments without pruning

Threshold

Tier 1: Metric Cardinality Budget Exceeded

Likely Bottleneck

Unbounded label cardinality generating millions of distinct time series that exceed ClickHouse part merge capacity and query planner pruning effectiveness

Recommended Evolution

Enforce a cardinality budget at ingestion: before a metric is accepted, evaluate the distinct value count of each label dimension against a per-dimension limit (e.g., max 100 distinct values for any single label key). Reject or rewrite metrics that exceed the budget: rewrite user_id labels to user_cohort or drop them entirely. Implement a cardinality analysis dashboard showing the top 10 highest-cardinality metric series sorted by storage cost. ClickHouse distributed table partitioning by metric name reduces the impact of a single high-cardinality metric on global query performance.

Kafka log topic consumer lag growing > 1 million messages during incident periods; Elasticsearch indexing throughput metrics showing queue buildup; incident post-mortems noting that relevant log records were not available in the search interface during the incident; log consumer memory pressure from unbounded batch accumulation

Threshold

Tier 2: Log Volume Spike Exceeding Consumer Throughput

Likely Bottleneck

Log Kafka consumer sized for normal throughput; unable to drain the spike volume produced during incident-driven log floods

Recommended Evolution

Size the log consumer for 10x normal throughput, not 1x: observability platform capacity must be planned for the incident scenario, not the steady state. Implement consumer autoscaling triggered by consumer lag metric: when Kafka consumer lag exceeds a threshold, add consumer instances automatically. Implement log sampling at the producer side for DEBUG and INFO level messages during identified spike periods : preserve all ERROR and WARN messages, sample INFO at 10%, sample DEBUG at 1%. This bounds the worst-case log volume without sacrificing diagnostic signal.

Evidence:elasticsearch-reindexing-pressurekafka-consumer-lag-cascade

Alert routing system receiving > 10,000 alert events per minute; on-call engineers reporting alert fatigue and inability to identify the root alert in notification floods; PagerDuty or equivalent showing duplicate alerts firing simultaneously for correlated failures; alert evaluation CPU dominating observability platform resource consumption

Threshold

Tier 3: Alert Evaluation Fanout Amplification

Likely Bottleneck

High-cardinality alert rules evaluating independently for every label combination, producing alert notification floods that are operationally equivalent to no alerting

Recommended Evolution

Introduce alert grouping at the evaluation layer: alerts on the same metric name within the same time window are grouped into a single notification with a count of affected series. Implement alert inhibition rules: if a datacenter-level alert fires, suppress region-level and service-level alerts that are downstream of the same failure. Move from per-series alert rules to aggregate alert rules: "more than 10% of service instances have error rate > 5%" is a single alert, not 500 individual alerts.

Evidence:elasticsearch-reindexing-pressurekafka-consumer-lag-cascade

Monthly storage growth rate for metrics and logs exceeding capacity plan; ClickHouse data volume > 10TB with no retention enforcement in place; Elasticsearch index size growing faster than the retention policy deletes old indices; cost reports showing observability storage as top-3 infrastructure cost item

Threshold

Tier 4: Storage Cost Exceeding Retention Budget

Likely Bottleneck

No tiered retention strategy: all data retained at full resolution indefinitely rather than rolled up and archived to lower-cost storage

Recommended Evolution

Implement a three-tier retention strategy: hot tier (raw data, last 7 days, full resolution, ClickHouse), warm tier (1-hour rollups, last 90 days, ClickHouse compressed), cold tier (daily rollups, 2+ years, S3 Parquet via ClickHouse external tables or Athena). Log retention follows a separate policy: raw logs retained 30 days in Elasticsearch, then archived to S3 with a query interface for compliance replay. Alert evaluation always runs against the hot tier.

ClickHouse part merge frequency increasing; dashboard queries timing out on metrics with high label cardinality; ClickHouse system.metrics showing active_parts count elevated; new metric instrumentation causing sudden storage growth disproportionate to fleet size; query_log showing metrics queries scanning full column segments without pruning

Threshold

Escalation trigger: Unbounded label cardinality generating millions of distinct time series that exceed ClickHouse part merge capacity and query planner pruning effectiveness

Likely Bottleneck

Tier 1: Metric Cardinality Budget Exceeded

Recommended Evolution

Monitor: error_rate, p95_latency_ms

Kafka log topic consumer lag growing > 1 million messages during incident periods; Elasticsearch indexing throughput metrics showing queue buildup; incident post-mortems noting that relevant log records were not available in the search interface during the incident; log consumer memory pressure from unbounded batch accumulation

Threshold

Escalation trigger: Log Kafka consumer sized for normal throughput; unable to drain the spike volume produced during incident-driven log floods

Likely Bottleneck

Tier 2: Log Volume Spike Exceeding Consumer Throughput

Recommended Evolution

Monitor: error_rate, p95_latency_ms

Alert routing system receiving > 10,000 alert events per minute; on-call engineers reporting alert fatigue and inability to identify the root alert in notification floods; PagerDuty or equivalent showing duplicate alerts firing simultaneously for correlated failures; alert evaluation CPU dominating observability platform resource consumption

Threshold

Escalation trigger: High-cardinality alert rules evaluating independently for every label combination, producing alert notification floods that are operationally equivalent to no alerting

Likely Bottleneck

Tier 3: Alert Evaluation Fanout Amplification

Recommended Evolution

Monitor: error_rate, p95_latency_ms

Monthly storage growth rate for metrics and logs exceeding capacity plan; ClickHouse data volume > 10TB with no retention enforcement in place; Elasticsearch index size growing faster than the retention policy deletes old indices; cost reports showing observability storage as top-3 infrastructure cost item

Threshold

Escalation trigger: No tiered retention strategy: all data retained at full resolution indefinitely rather than rolled up and archived to lower-cost storage

Likely Bottleneck

Tier 4: Storage Cost Exceeding Retention Budget

Recommended Evolution

Monitor: error_rate, p95_latency_ms

Migration Readiness

12

Migration Stages

3
Stage

Prometheus + Grafana stack with local time-series storage → Kafka-buffered ClickHouse ingestion with Redis-backed alert evaluation

info

Migration trigger: Prometheus storage limits reached at production metric volume; ClickHouse required for sub-second aggregate queries across multi-day windows that Prometheus cannot serve; need to retain metrics beyond Prometheus 15-day default retention without capacity-limited remote write targets; cross-service correlation queries not possible in PromQL

Stage

Log shipping directly to Elasticsearch without Kafka buffer → Kafka-buffered log ingestion with backpressure and sampling controls

info

Migration trigger: Elasticsearch indexing pressure causing log rejection (HTTP 429) back-pressuring into application services during incidents; log volume spikes during incidents causing Elasticsearch cluster instability; inability to replay historical logs when the indexing pipeline falls behind

Stage

Direct ClickHouse queries for alert evaluation on every alert tick → TimescaleDB continuous aggregates as pre-computed alert evaluation views

info

Migration trigger: Alert evaluation latency > 1s causing missed alert firing windows; ClickHouse CPU saturated by alert evaluation scans competing with dashboard queries; alert evaluation queries scanning full column segments without partition pruning due to high cardinality in alert rule label selectors

!

Risks

9
Risk

Prometheus metric naming conventions and label schemas must

warning

Prometheus metric naming conventions and label schemas must be preserved exactly in ClickHouse: a schema transformation at migration time breaks all existing Grafana dashboards

Risk

Alert rules expressed in PromQL must be rewritten for the ne

warning

Alert rules expressed in PromQL must be rewritten for the new alert evaluation engine: the migration window requires running both systems in parallel and validating alert equivalence

Risk

Introducing Kafka adds infrastructure complexity for the log

warning

Introducing Kafka adds infrastructure complexity for the log shipping agents: every application must be updated to write to Kafka instead of directly to Elasticsearch

Risk

Kafka retention must be set to at least the Elasticsearch in

warning

Kafka retention must be set to at least the Elasticsearch indexing catch-up time under worst-case incident volume: insufficient retention causes log loss if indexing falls behind more than the retention window

Risk

Continuous aggregate refresh interval determines the minimum

warning

Continuous aggregate refresh interval determines the minimum alert detection latency: a 1-minute refresh interval means alerts cannot fire on sub-minute anomalies

Risk

TimescaleDB continuous aggregate must be defined for every m

warning

TimescaleDB continuous aggregate must be defined for every metric queried by alert rules: adding new alert rules may require adding new continuous aggregates

Risk

Projection lag creates a read-after-write window where users

critical

Projection lag creates a read-after-write window where users see stale data after their own writes. Mitigation: Route immediate post-write reads to the write store (session-scoped write token); accept eventual consistency only for non-user-initiated reads

direct-db-to-cqrs

Risk

Projection rebuild after schema change can take hours or day

critical

Projection rebuild after schema change can take hours or days on large datasets. Mitigation: Design blue/green projection deployment: build new projection in parallel before switching traffic; test rebuild time in staging

direct-db-to-cqrs

Risk

Cross-service workflows that previously used database transa

critical

Cross-service workflows that previously used database transactions now require Saga orchestration. Mitigation: Design idempotent event handlers; implement compensating transactions for every multi-step workflow; test failure injection in staging

modular-monolith-to-event-driven

Review Sections

6

Referenced Intelligence

clickhouseelasticsearchkafkaredistimescaledbburst-traffic-cold-cache-stampedecqrs-projection-lag-expansiondistributed-cache-invalidation-failureelasticsearch-reindexing-pressureevent-replay-storm-recoverykafka-consumer-lag-cascadepartition-hotspot-amplificationredis-cache-collapse-stampederetry-storm-amplificationdirect-db-to-cqrsmodular-monolith-to-event-drivenoltp-analytics-to-separatedrabbitmq-to-kafkasingle-cache-to-distributedsingle-region-to-multi-regionarchitecture-evolutionauditabilitycache-invalidationcap-theoremconsistency-modelscqrs-operationalevent-sourcingkafka-consumer-lagoltp-vs-olappartition-hotspotsqueue-backlogreplication-lagsearch-systems