Observability

Comprehensive visibility into every query with non-blocking event publishing, batching, and hot data detection.

Overview

ScryData's observability system captures rich metadata for every query flowing through the proxy:

Query Execution
      ↓
Extract Metadata (query, timing, success/failure)
      ↓
Create QueryEvent
      ↓
Send to EventBatcher (async, non-blocking)
      ↓
Batch accumulates events
      ↓
Flush on size (100 events) OR time (1000ms)
      ↓
EventPublisher publishes batch
                            

Key Properties

  • Non-blocking: Events published asynchronously, never delay queries
  • Best-effort: If event queue full, oldest events dropped to protect memory
  • Batched: Events aggregated for efficient network usage
  • Flexible: Pluggable publishers (debug, HTTP)

Query Events

Every query generates an event containing:

Field Description
event_id Unique event ID (UUID v4)
timestamp Event timestamp (UTC)
query Query text (raw or anonymized)
normalized_query Query with placeholders (if anonymized)
value_fingerprints Blake3 fingerprints of literal values
duration Query execution duration
rows Number of rows affected/returned
success Whether query succeeded
error Error message (if failed)
database Database name
connection_id Connection ID for tracing

Example Event (Anonymized)

{
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2025-12-06T10:00:00.123Z",
  "query": "SELECT * FROM users WHERE id = ?",
  "normalized_query": "SELECT * FROM users WHERE id = ?",
  "value_fingerprints": ["blake3:abc123def456..."],
  "duration_ms": 1.23,
  "rows": 1,
  "success": true,
  "database": "production",
  "connection_id": "conn-123"
}

Event Batching

Events are batched to reduce network overhead:

Parameter Default Description
batch_size 100 events Flush when batch reaches this size
flush_interval_ms 1000ms Flush every N milliseconds
max_queue_size 10000 events Max events in channel before dropping oldest

Memory Safety: The channel is bounded with ring buffer semantics. New events replace oldest events if full, preventing unbounded memory growth. Queries never block on event publishing.

Memory Usage: ~100 bytes per event → 10,000 events ≈ 1MB

Publishers

DebugLoggerPublisher

Logs events as JSON to console. Use for development and debugging.

[publisher]
publisher_type = "debug"

HttpPublisher

Publishes batches to remote HTTP endpoint using FlexBuffers serialization (50% smaller than JSON).

[publisher]
publisher_type = "http"
http_endpoint = "https://analytics.example.com/events"
http_timeout_ms = 500
http_max_retries = 2
http_api_key = "sk-..."
http_compression = true

Features:

  • Retries with exponential backoff on failure
  • Optional gzip compression (default: enabled)
  • API key authentication
  • Monotonic batch sequence number for ordering

FlexBuffers Serialization

ScryData uses FlexBuffers for efficient binary serialization:

~50KB
JSON (100 events)
~25KB
FlexBuffers
~8KB
FlexBuffers + gzip
84%
Network savings

Benefits:

  • Schema-less: No code generation required
  • Fast: Zero-copy deserialization
  • Compact: 50% smaller than JSON
  • Cross-platform: FlatBuffers ecosystem support

Hot Data Detection

ScryData tracks frequently accessed value fingerprints using Count-Min Sketch + Top-K heap:

curl http://localhost:9090/debug/hot_data
{
  "top_k": [
    {
      "fingerprint": "blake3:a1b2c3d4e5f6...",
      "access_count": 15234
    },
    {
      "fingerprint": "blake3:f6e5d4c3b2a1...",
      "access_count": 8901
    }
  ]
}

Use Cases:

  • Cache Optimization: Cache hot fingerprint results
  • Anomaly Detection: Sudden spike in specific fingerprint access
  • Performance Tuning: Optimize queries accessing hot data
  • Security: Detect unusual access patterns (credential stuffing)

Prometheus Metrics

# Total queries processed
scry_queries_total 10000

# Query latency percentiles
scry_query_latency_seconds{quantile="0.5"} 0.000123
scry_query_latency_seconds{quantile="0.99"} 0.000456

# Pool connections
scry_pool_connections_total 15
scry_pool_connections_available 8
scry_pool_utilization 0.46

# Circuit breaker state
scry_circuit_breaker_state 0

# Error rate
scry_query_error_rate 0.001

Get Complete Visibility Into Your Queries

ScryData gives you deep observability without impacting query latency.

Request Early Access