Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/helicone/helicone/llms.txt

Use this file to discover all available pages before exploring further.

System Overview

Helicone is built as a modular, scalable system with six core components:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      User / Browser                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β”‚ HTTPS
             β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Web (Next.js)                          β”‚
β”‚  β€’ Dashboard UI                                           β”‚
β”‚  β€’ Request visualization                                  β”‚
β”‚  β€’ Analytics and reports                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚                              β”‚
             β”‚ API Calls                    β”‚ Auth
             β”‚                              β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Jawn (Express + Tsoa)                  β”‚
β”‚  β€’ REST API server                                        β”‚
β”‚  β€’ Request logging                                        β”‚
β”‚  β€’ Prompt management                                      β”‚
β”‚  β€’ User/org management                                    β”‚
β””β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  β”‚        β”‚        β”‚        β”‚        β”‚
  β”‚        β”‚        β”‚        β”‚        └─────────┐
  β”‚        β”‚        β”‚        β”‚                  β”‚
β”Œβ”€β–Όβ”€β”€β”€β”€β” β”Œβ–Όβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚Workerβ”‚ β”‚PostgreSQLβ”‚ β”‚ ClickHouse β”‚ β”‚     MinIO     β”‚
β”‚      β”‚ β”‚          β”‚ β”‚            β”‚ β”‚  (S3 Storage) β”‚
β”‚Proxy β”‚ β”‚ App DB   β”‚ β”‚Analytics DBβ”‚ β”‚               β”‚
β”‚      β”‚ β”‚          β”‚ β”‚            β”‚ β”‚               β”‚
β””β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
   β”‚
   β”‚ Proxied requests
   β”‚
β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              LLM Providers (OpenAI, etc.)               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Components

Web (Next.js)

Technology: Next.js 14, React, TailwindCSS Purpose: Frontend dashboard for visualizing and managing your LLM observability data. Key Features:
  • Request logs and trace visualization
  • Cost and latency analytics
  • Prompt management UI
  • Session and agent tracing
  • User and organization management
  • Evaluation and scoring interfaces
Configuration:
# Environment variables
NEXT_PUBLIC_HELICONE_JAWN_SERVICE=http://localhost:8585
BETTER_AUTH_SECRET=your-secret-key
DATABASE_URL=postgresql://...
Default Port: 3000

Jawn (Backend API)

Technology: Node.js, Express, TypeScript, Tsoa (OpenAPI) Purpose: Main backend API server that handles all business logic and data operations. Responsibilities:
  • REST API endpoints for the web dashboard
  • Request and response logging
  • Prompt versioning and deployment
  • User authentication and authorization
  • Analytics aggregation
  • Webhook management
  • Dataset creation and management
Configuration:
# Core settings
PORT=8585
NODE_ENV=production

# Databases
SUPABASE_DATABASE_URL=postgresql://...
CLICKHOUSE_HOST=http://clickhouse:8123

# Object storage
S3_ENDPOINT=http://minio:9000
S3_BUCKET_NAME=request-response-storage
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin

# Auth
BETTER_AUTH_SECRET=your-secret-key
Default Port: 8585 Key Endpoints:
  • /v1/request/* - Request logging and retrieval
  • /v1/prompt/* - Prompt management
  • /v1/user/* - User and organization management
  • /v1/analytics/* - Analytics queries

Worker (Cloudflare Workers / Node.js)

Technology: TypeScript, running on Node.js (self-hosted) or Cloudflare Workers (cloud) Purpose: High-performance proxy that intercepts LLM requests, logs them, and forwards to providers. Worker Types:
  1. OpenAI Proxy (Port 8787)
    • Proxies requests to OpenAI API
    • Logs requests to ClickHouse
    • Stores bodies in MinIO
  2. Anthropic Proxy (Port 8790)
    • Proxies requests to Anthropic API
    • Handles streaming responses
  3. Gateway API (Port 8789)
    • Unified gateway for multiple providers
    • Intelligent routing and fallbacks
  4. Helicone API (Port 8788)
    • Internal API worker
    • Async logging endpoints
Configuration:
WORKER_TYPE=OPENAI_PROXY
WORKER_PORT=8787
CLICKHOUSE_HOST=http://clickhouse:8123
VALHALLA_URL=http://jawn:8585
S3_ENDPOINT=http://minio:9000

PostgreSQL (Application Database)

Technology: PostgreSQL 17 Purpose: Stores application data including users, organizations, API keys, prompts, and metadata. Key Tables:
  • auth.users - User accounts
  • public.organization - Organizations
  • public.helicone_api_keys - API keys
  • public.prompts - Prompt versions
  • public.request - Request metadata (references ClickHouse)
  • public.properties - Custom properties
  • public.feedback - User feedback and ratings
Configuration:
POSTGRES_HOST=db
POSTGRES_PORT=5432
POSTGRES_DB=helicone_test
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
Default Port: 5432 (mapped to 54388 in docker-compose)

ClickHouse (Analytics Database)

Technology: ClickHouse 24.3 Purpose: High-performance columnar database for storing and analyzing request logs at scale. Key Tables:
  • default.request_response_versioned - Main request/response log
  • default.request_response_rmt - Replicated table for HA
  • default.properties_v2 - Request properties
  • default.score_value - Evaluation scores
  • default.cache_hits - Cache performance data
Why ClickHouse?
  • Handles billions of rows efficiently
  • Fast aggregations for analytics
  • Excellent compression (10x+ vs PostgreSQL)
  • Optimized for time-series data
Configuration:
CLICKHOUSE_HOST=http://clickhouse:8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=
Default Ports:
  • HTTP: 8123 (mapped to 18123)
  • Native: 9000 (mapped to 19000)

MinIO (Object Storage)

Technology: MinIO (S3-compatible) Purpose: Stores large request and response bodies separately from metadata. Buckets:
  • request-response-storage - Full request/response bodies
  • prompt-body-storage - Prompt templates and versions
  • hql-store - HQL query results
Why Separate Storage?
  • Request/response bodies can be very large (images, documents, etc.)
  • Storing in database would bloat tables and slow queries
  • S3-compatible storage is cheap and scalable
  • Bodies are referenced by ID in ClickHouse
Configuration:
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
S3_ENDPOINT=http://minio:9000
S3_BUCKET_NAME=request-response-storage
Default Ports:
  • API: 9000
  • Console: 9001

Request Flow

1. Proxied Request Flow

When an LLM request goes through Helicone’s proxy:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Client  β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
     β”‚ 1. Request with Helicone headers
     β”‚    POST http://localhost:8787/v1/chat/completions
     β”‚    Headers: Helicone-Auth, Helicone-Property-*, etc.
     β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Worker (OpenAI Proxy)                              β”‚
β”‚  1. Validate API key (check PostgreSQL via Jawn)    β”‚
β”‚  2. Extract metadata and properties                 β”‚
β”‚  3. Forward to OpenAI                               β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”˜
     β”‚                 β”‚                            β”‚
     β”‚ 4. Log request  β”‚ 5. Store body             β”‚ 3. Forward
     β”‚                 β”‚                            β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚  ClickHouse   β”‚ β”‚   MinIO   β”‚            β”‚   OpenAI     β”‚
β”‚  (metadata)   β”‚ β”‚  (bodies) β”‚            β”‚     API      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                                    β”‚
                                                    β”‚ 6. Response
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”
β”‚  Worker                                              β”‚
β”‚  7. Log response metadata to ClickHouse              β”‚
β”‚  8. Store response body to MinIO                     β”‚
β”‚  9. Return response to client                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Dashboard Query Flow

When viewing requests in the dashboard:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Browser  β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
     β”‚ 1. GET /requests?page=1
     β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Web (Next.js)                            β”‚
β”‚  2. Server-side render or API call        β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 3. GET /v1/request/query
     β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Jawn API                                  β”‚
β”‚  4. Build ClickHouse query                 β”‚
β”‚  5. Execute query                          β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                   β”‚
     β”‚ 6. Query metadata β”‚ 7. Fetch bodies (if needed)
     β”‚                   β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚  ClickHouse   β”‚   β”‚   MinIO   β”‚
β”‚               β”‚   β”‚           β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
     β”‚                   β”‚
     β”‚ 8. Return data    β”‚
     β”‚                   β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Jawn API                           β”‚
β”‚  9. Combine metadata + bodies       β”‚
β”‚  10. Return JSON response           β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Web                                  β”‚
β”‚  11. Render in UI                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Storage Strategy

What Goes Where?

Data TypeStorageReason
User accountsPostgreSQLRelational, requires ACID
API keysPostgreSQLNeeds auth lookups
Prompt versionsPostgreSQLSmall, relational
Request metadataClickHouseFast analytics, billions of rows
Request/response bodiesMinIOLarge blobs, cheap storage
PropertiesClickHouseTime-series, analytics
Scores/evaluationsClickHouseTime-series, analytics

Data Retention

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PostgreSQL (Keep Forever)                           β”‚
β”‚ β€’ User accounts                                     β”‚
β”‚ β€’ Organizations                                     β”‚
β”‚ β€’ API keys                                          β”‚
β”‚ β€’ Prompt templates                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ClickHouse (Configurable Retention)                 β”‚
β”‚ β€’ Request logs: 90 days default                     β”‚
β”‚ β€’ Can configure TTL per table                       β”‚
β”‚ β€’ Aggregations stored longer                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ MinIO (Lifecycle Policies)                          β”‚
β”‚ β€’ Request bodies: 90 days default                   β”‚
β”‚ β€’ Transition to cold storage after 30 days          β”‚
β”‚ β€’ Configurable per bucket                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

High Availability Architecture

For production deployments:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Load Balancer / Ingress                 β”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
      β”‚                                        β”‚
β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”                           β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
β”‚  Web (1)  β”‚                           β”‚  Jawn (1) β”‚
β”‚  Web (2)  │◄───────────────────────────  Jawn (2) β”‚
β”‚  Web (3)  β”‚    Session Sharing         β”‚  Jawn (3) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                              β”‚
               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
               β”‚                              β”‚            β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”
        β”‚  PostgreSQL   β”‚            β”‚  ClickHouse  β”‚ β”‚ MinIO  β”‚
        β”‚               β”‚            β”‚              β”‚ β”‚        β”‚
        β”‚ Primary + 2   β”‚            β”‚ 3-node       β”‚ β”‚4-node  β”‚
        β”‚ Read Replicas β”‚            β”‚ cluster      β”‚ β”‚cluster β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Security Architecture

Authentication Flow

  1. User Authentication (Better Auth)
    • Email/password via PostgreSQL
    • Session tokens stored in cookies
    • OAuth providers (Google, GitHub)
  2. API Key Authentication
    • API keys stored in PostgreSQL
    • Validated on each proxy request
    • Scoped to organizations
  3. Service-to-Service
    • Internal services trust each other
    • Network isolation in production
    • Service accounts for workers

Data Security

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Encryption at Rest                                  β”‚
β”‚  β€’ PostgreSQL: Encrypted volumes                     β”‚
β”‚  β€’ ClickHouse: Encrypted volumes                     β”‚
β”‚  β€’ MinIO: SSE (Server-Side Encryption)               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Encryption in Transit                               β”‚
β”‚  β€’ TLS 1.3 for all external traffic                  β”‚
β”‚  β€’ Internal: Can use mTLS in production              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Access Control                                      β”‚
β”‚  β€’ Row-level security in PostgreSQL                  β”‚
β”‚  β€’ Organization-scoped queries                       β”‚
β”‚  β€’ API key permissions                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Scalability

Horizontal Scaling

Stateless Services (can scale infinitely):
  • Web: Add more replicas behind load balancer
  • Jawn: Add more replicas behind load balancer
  • Workers: Add more worker instances
Stateful Services (require clustering):
  • PostgreSQL: Primary + read replicas
  • ClickHouse: Sharded cluster with replication
  • MinIO: Distributed mode with erasure coding

Vertical Scaling

Recommended resource allocation:
ServiceCPUMemoryStorage
Web0.5-1 core1-2GBMinimal
Jawn1-2 cores2-4GBMinimal
Worker0.5-1 core512MB-1GBMinimal
PostgreSQL2-4 cores4-8GB100GB+
ClickHouse4-8 cores8-16GB500GB+
MinIO1-2 cores2-4GB1TB+

Monitoring

Health Checks

All services expose health endpoints:
# Web
curl http://localhost:3000/api/health

# Jawn
curl http://localhost:8585/v1/public/healthcheck

# ClickHouse
curl http://localhost:8123/ping

# PostgreSQL
pg_isready -h localhost -p 5432

# MinIO
curl http://localhost:9000/minio/health/live

Metrics

Exposed Prometheus metrics:
  • HTTP request latency (p50, p95, p99)
  • Request volume per endpoint
  • Error rates
  • Database connection pool stats
  • Queue depths
  • Cache hit rates

Next Steps

Docker Deployment

Deploy with Docker Compose

Kubernetes

Production deployment with Helm