Skip to main content

Documentation

Realtime, WebSocket & Object Storage

WebSocket/SSE architecture and S3-compatible object storage.

8. Realtime & WebSocket

Current-state note (2026-08-18)

Today's realtime fan-out is in-process (tokio::broadcast), scoped to a single Stackhouse pod — there's no Redis PubSub cross-pod relay in the codebase yet. The Redis-PubSub design below is the proposed fix for running multiple pods at scale, not something already running.

WebSocket Architecture at Scale

Rendering diagram…

Key insight: Redis PubSub decouples pods. Any pod can receive a write, all clients on all pods get notified.

SSE vs WebSocket Routing

Rendering diagram…

Provider WebSocket Support

FeatureAWSGCPHostingerHetznerHeroku
WebSocket at LB✅ ALB✅ (60s timeout ⚠️)
Sticky sessions❌ (dyno routing)
Max WS connectionsUnlimitedUnlimited~10k~10k~25k
WS timeout (max)No limitNo limit60s ⚠️No limit55s ⚠️

⚠️ Heroku and some Hostinger plans have aggressive idle timeouts. Requires ping/pong every 50s.


9. Storage (File/Object)

Storage Architecture

Rendering diagram…

Upload flow: Client → Multipart POST /v1/storage/object/bucket/path → Validation (size, MIME, path) → Write to object storage backend → Update PostgreSQL metadata → Return { id, path, size, url }

Download flow: Client → GET /v1/storage/object/bucket/path → Check auth (public bucket = no auth required) → Serve file bytes with correct Content-Type, OR generate pre-signed URL (redirect to S3/GCS directly)

Image transforms (planned): On-demand resize via /object/bucket/img.jpg?w=200&h=200 → served from CDN after first transform → cached on disk (disk caching + CDN headers)

Object Storage Comparison

FeatureAWS S3GCSCloudflare R2MinIO (Hetzner)Hostinger
S3-compatible APIPartial
Free egress✅ (zero egress)✅ (internal)
Global CDNCloudFrontCloud CDN✅ included
Storage cost/GB$0.023$0.020$0.015$0.004~$0.01
Egress cost/GB$0.09$0.12$0$0 (internal)~$0.05
Max object size5TB5TB5TBUnlimited~5GB
Versioning
Lifecycle policies