Documentation
Provider Breakdown, Cost Analysis & GCP Reference
AWS, GCP, Hetzner, Hostinger, Heroku comparison, cost tables, and GKE manifests.
15. Provider-by-Provider Breakdown
AWS Architecture
Region: us-east-1 (primary) + us-west-2 (DR)
Networking: VPC 10.0.0.0/16 · Public subnets 10.0.1.0/24, 10.0.2.0/24 (ALB, NAT Gateway) · Private subnets 10.0.10.0/24, 10.0.11.0/24 (EKS nodes, RDS, ElastiCache) · no direct internet access to private subnets
Compute: EKS (Elastic Kubernetes Service) — node group 3-10× m6i.xlarge (4vCPU/16GB) at $0.192/hr each · 50% spot instances (saves ~70%) with fallback · Fargate for burst workloads (AI jobs)
Database: RDS PostgreSQL 16 — db.r6g.xlarge (4vCPU/32GB) at $0.48/hr · Multi-AZ synchronous standby (30s failover) · 2× read replicas (db.r6g.large) · 500GB gp3 SSD with auto-scaling · automated backups with 35-day PITR
Cache: ElastiCache Redis 7 — cache.r6g.large (2vCPU/13GB) at $0.166/hr · cluster mode with 3 shards × 2 replicas
Storage: S3 — standard $0.023/GB/month · egress $0.09/GB (expensive!) · CloudFront CDN for public assets
Load Balancer: ALB — $0.008/LCU/hour + $0.016/hour base · path-based routing · WebSocket support (upgrade headers pass-through)
Secrets: AWS Secrets Manager + KMS · Logs: CloudWatch Logs ($0.50/GB ingested) · Metrics: CloudWatch + Prometheus on EKS · CI/CD: CodePipeline + ECR
GCP Architecture
Region: us-central1 (primary) + us-east1 (DR)
Networking: VPC custom mode, global · subnets us-central1 10.10.0.0/20 · Private Google Access enabled · Cloud NAT for outbound · VPC Service Controls (data exfil prevention)
Compute: GKE Autopilot (recommended) or Standard — Autopilot pays per pod (CPU+Memory), no node management · Standard: 3-10× e2-standard-4 (4vCPU/16GB) at $0.134/hr · Spot VMs: 60-80% discount with preemption handling
Database: Cloud SQL for PostgreSQL 16 — db-custom-4-26624 (4vCPU/26GB) at ~$300/month · HA synchronous replica with auto-failover · 2× read replicas in same region · built-in connection proxy (no separate PgBouncer needed) · 500GB SSD with auto-increase · automated backups with 7-day PITR
Cache: Memorystore for Redis — 5GB standard tier at ~$150/month · high availability mode (with replica)
Storage: GCS — standard $0.020/GB/month · egress $0.12/GB (between regions) · Cloud CDN for public assets
Load Balancer: Cloud Load Balancing (Global HTTP(S)) — ~$0.025/million requests · global anycast (best-in-class routing) · integrated with Cloud Armor WAF
Security: Cloud Armor (WAF) — $5/policy + $0.75/million req · Secrets: Secret Manager ($0.06/10k access) · Logs: Cloud Logging (first 50GB/month free) · CI/CD: Cloud Build + Artifact Registry
Hetzner Architecture
Location: Nuremberg (EU) + Hillsboro (US)
Compute: Hetzner Cloud + k3s (lightweight Kubernetes) — 3× CPX31 nodes (4vCPU/8GB) at €12.20/month each, or 3× CCX23 (4vCPU/16GB dedicated) at €50.40/month each · k3s (not full K8s), simpler and great for small clusters
Database: Managed PostgreSQL (Hetzner DB) — 4GB/2vCPU at ~€20/month (very affordable), or self-managed on dedicated CPX51 (8vCPU/32GB) at €85/mo · no built-in PITR (manual WAL archiving needed) · no read replicas in managed offering
Cache: Redis on separate VM — CPX21 (3vCPU/4GB) at €9.90/month, self-managed (install, configure, monitor yourself)
Storage: Hetzner Object Storage — S3-compatible API ✅ · €0.0119/GB/month (much cheaper than AWS S3) · free egress within Hetzner network
Load Balancer: Hetzner Load Balancer — LB11 €5.39/month (5 targets, 20M requests) · WebSocket support ✅
Firewall: Hetzner Cloud Firewall (free) · CDN: Cloudflare (free tier works fine) · WAF: Cloudflare WAF ($20/month Pro plan) · Secrets: self-managed Vault or env vars in k3s secrets · Logs: self-hosted Grafana + Loki + Promtail · Metrics: self-hosted Prometheus + Grafana
⚠️ Trade-offs
No managed Kubernetes (k3s is DIY) No auto-scaling out of box Limited DR options EU-based primarily (latency for US users) More DevOps effort required
✅ Strengths
Cheapest compute by far (70% cheaper than AWS/GCP) Predictable pricing (no surprise bills) Great for EU GDPR compliance Dedicated servers available (no noisy neighbors)
Hostinger Architecture
Warning
Compute: VPS plans — KVM 8: 8vCPU/32GB at $9.99/month (shared, not dedicated) · no Kubernetes support · Docker possible, but no orchestration
Database: MySQL only (no PostgreSQL in managed offering) ❌ · can self-install PostgreSQL on VPS · no PITR, no read replicas, no auto-failover
Storage: limited local disk storage · no S3-compatible object storage
Networking: shared IPv4 on cheaper plans · 1Gbps uplink · no VPC / private networking
Verdict for Stackhouse: ✅ good for dev environment, demo, personal projects · ✅ good for landing page, static site · ❌ bad for production Stackhouse serving 100k users
Alternative use: Hostinger for frontend (Next.js dashboard) while backend runs on GCP/Hetzner.
Heroku Architecture
Heroku is PaaS (Platform as a Service) — managed deployment, owned by Salesforce. Great DX, limited customization.
Compute: Dynos — Standard-2X (1vCPU/1GB) $50/month/dyno · Performance-M (2vCPU/2.5GB) $250/month/dyno · for 100k users need ~13 Performance-M dynos = $3,250/month · autoscaling ✅ (Heroku Autoscale add-on, $10/month)
Database: Heroku Postgres — Standard-7 (4vCPU/7.5GB) $175/month · Standard-15 (4vCPU/15GB) $350/month · Premium-0 (4vCPU/15GB + follower) $400/month · PITR ✅ 4 days on Standard+ · max connections 120 (Standard-7), 500 (Premium)
Cache: Heroku Data for Redis — Premium-0 (100MB) $30/month · Premium-1 (1GB) $75/month · Premium-3 (5GB) $250/month
Networking: Heroku Router handles load balancing (included) · Private Spaces $1,700/month (VPC-like isolation) · no custom TCP/IP configuration
Storage: no native file storage (use AWS S3 add-on) · Cloudinary/Backblaze as add-ons
Logging: Logplex → add-ons (Papertrail $7/month, Datadog) · Metrics: AppSignal add-on (~$19/month)
✅ Strengths
Easiest deployment (git push heroku main) No infrastructure management Fast prototyping and MVP launch Excellent add-on ecosystem
❌ Weaknesses
Very expensive at scale ($3k+/month for 100k users) 55-second WebSocket timeout (pings needed) No sticky sessions (WebSocket reliability issues) Ephemeral filesystem (no local file persistence) Less control over infrastructure
16. Cost Comparison at 100k Users
Monthly Cost Breakdown
Configuration basis: 13 API pods (4vCPU/16GB nodes) · 1 PostgreSQL primary + 2 read replicas (4vCPU/32GB) · 1 Redis cluster (5GB) · 100GB object storage + 500GB egress · load balancer · monitoring, logging, backups
| Component | AWS (us-e-1) | GCP (us-cen) | Hetzner (EU) | Heroku |
|---|---|---|---|---|
| Compute (pods) | $430 | $380 | $120 | $3,250 |
| PostgreSQL Primary | $350 | $300 | $85 | $400 |
| PostgreSQL Replicas | $200 | $150 | $120 (self) | Included |
| PgBouncer | $50 | $0 (built-in) | $10 | N/A |
| Redis | $120 | $150 | $30 | $250 |
| Load Balancer | $40 | $30 | $15 | Included |
| Object Storage | $90 | $80 | $20 | $60 (S3) |
| Egress | $45 | $60 | $0 | $25 |
| WAF/DDoS | $50 | $35 | $0 (CF free) | $0 |
| Cloudflare Pro | $20 | $20 | $20 | $20 |
| Monitoring | $80 | $50 | $20 (self) | $75 |
| Backups/Storage | $30 | $20 | $15 | Included |
| Secrets Manager | $10 | $5 | $0 (self) | $0 |
| CI/CD | $20 | $15 | $0 (GitHub) | $0 |
| Support Plan | $0-$100 | $0 | $0 | $0 |
| Total/month | ~$1,535 | ~$1,295 | ~$455 | ~$4,080 |
| Total/year | ~$18,420 | ~$15,540 | ~$5,460 | ~$48,960 |
Hostinger: Not comparable — insufficient for this use case. Estimated ~$200/month but requires significant additional services.
Notes:
- AWS: Spot instances can reduce compute by 60% → ~$1,200/month
- GCP: Sustained use discounts apply automatically — already reflected
- Hetzner: Requires more DevOps time (factor in ~$500-1000/month engineering)
- Heroku: Prices increase linearly with users — very expensive at scale
Cost Efficiency per User
Monthly cost / 100,000 users:
| Provider | Cost | Per user/month |
|---|---|---|
| AWS | $1,535 / 100,000 | $0.015 |
| GCP | $1,295 / 100,000 | $0.013 ← best managed cloud |
| Hetzner | $455 / 100,000 | $0.0046 ← cheapest total |
| Heroku | $4,080 / 100,000 | $0.041 ← most expensive |
Engineering cost consideration: Hetzner requires 5+ additional engineering hours/month vs GCP. At $100/hr, that's $500 extra → Hetzner's real cost is ≈$955/month, still 26% cheaper than GCP, but the gap narrows significantly.
17. Decision Matrix
Score: 1 (poor) to 5 (excellent)
| Criterion | AWS | GCP | Hetzner | Hostinger | Heroku | Weight |
|---|---|---|---|---|---|---|
| Cost efficiency | 3 | 4 | 5 | 4 | 1 | 20% |
| PostgreSQL maturity | 5 | 5 | 3 | 1 | 4 | 15% |
| Kubernetes support | 5 | 5 | 3 | 1 | 2 | 15% |
| Auto-scaling ease | 5 | 5 | 2 | 1 | 4 | 10% |
| Global availability | 5 | 5 | 3 | 2 | 3 | 10% |
| WebSocket support | 5 | 5 | 5 | 3 | 3 | 8% |
| Managed services depth | 5 | 5 | 2 | 2 | 4 | 8% |
| Security features | 5 | 5 | 3 | 2 | 3 | 7% |
| Developer experience | 4 | 4 | 3 | 4 | 5 | 5% |
| Disaster recovery | 5 | 5 | 2 | 1 | 4 | 2% |
| Weighted score | 4.6 | 4.8 | 3.1 | 1.9 | 2.8 | |
| Recommendation | ✅ Good | ⭐ Best | ✅$ Budget | ❌ Dev only | ❌ Staging |
⭐ = Best overall (GCP) · ✅ = Good choice (AWS) · ✅$ = Best if budget-constrained + DevOps capacity (Hetzner) · ❌ = Not recommended for production at scale
Use Case Recommendations
| If you are… | Choose |
|---|---|
| Startup, tight budget, EU users, DevOps-capable team | Hetzner + Cloudflare |
| Startup, scaling fast, want managed, global reach | GCP (best all-around) |
| Enterprise, AWS already in stack, need compliance (SOC2, HIPAA) | AWS |
| Just getting started, need to ship fast, <5k users | Heroku (then migrate) |
| Personal project, portfolio, demos | Hostinger / Railway / Fly.io |
| EU data residency required, GDPR priority | Hetzner (Nuremberg DC) |
18. Recommended Architecture: GCP
Full GCP Production Architecture
Stackhouse @ 100k Users.
Supporting services: Secret Manager (JWT secret, DB passwords, API keys) · Cloud Monitoring (metrics dashboards + alerting) · Cloud Logging (centralized logs, 50GB free/month) · Artifact Registry (Docker images) · Cloud Build (CI/CD pipeline) · Cloud Scheduler (backup jobs, cleanup tasks)
19. Kubernetes Manifests (GKE)
Deployment
# stackhouse-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: stackhouse-api
namespace: stackhouse
labels:
app: stackhouse-api
version: "1.0.0"
spec:
replicas: 3
selector:
matchLabels:
app: stackhouse-api
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # Zero downtime deployments
template:
metadata:
labels:
app: stackhouse-api
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "3000"
prometheus.io/path: "/v1/stats"
spec:
serviceAccountName: stackhouse-sa
terminationGracePeriodSeconds: 30
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: stackhouse-api
containers:
- name: stackhouse
image: us-central1-docker.pkg.dev/PROJECT/stackhouse/api:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
env:
- name: STACKHOUSE_PORT
value: "3000"
- name: STACKHOUSE_HOST
value: "0.0.0.0"
- name: STACKHOUSE_URL
valueFrom:
secretKeyRef:
name: stackhouse-secrets
key: database-url
- name: STACKHOUSE_JWT_SECRET
valueFrom:
secretKeyRef:
name: stackhouse-secrets
key: jwt-secret
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: stackhouse-secrets
key: redis-url
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "2000m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"] # Drain requests
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
- name: cloud-sql-proxy # Sidecar for DB
image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:latest
args:
- "--structured-logs"
- "--port=5432"
- "PROJECT:us-central1:stackhouse-pg"
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"
---
apiVersion: v1
kind: Service
metadata:
name: stackhouse-api
namespace: stackhouse
spec:
selector:
app: stackhouse-api
ports:
- port: 80
targetPort: 3000
protocol: TCP
type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: stackhouse-api-hpa
namespace: stackhouse
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: stackhouse-api
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 3
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 600 # Wait 10 min before scaling down
policies:
- type: Pods
value: 1
periodSeconds: 120
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: stackhouse-api-pdb
namespace: stackhouse
spec:
minAvailable: 2 # Always keep 2 pods up
selector:
matchLabels:
app: stackhouse-api
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: stackhouse-netpol
namespace: stackhouse
spec:
podSelector:
matchLabels:
app: stackhouse-api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- port: 3000
egress:
- to:
- podSelector:
matchLabels:
app: stackhouse-api # Allow pod-to-pod (same app)
- ports:
- port: 5432 # PostgreSQL (via Cloud SQL Proxy)
- port: 6379 # Redis
- port: 6333 # Qdrant REST API
- port: 6334 # Qdrant gRPC API
- port: 443 # External HTTPS (OpenAI, etc.)
- port: 53 # DNSPgBouncer ConfigMap
# pgbouncer-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: pgbouncer-config
namespace: stackhouse
data:
pgbouncer.ini: |
[databases]
stackhouse = host=127.0.0.1 port=5432 dbname=stackhouse
[pgbouncer]
listen_port = 6432
listen_addr = 0.0.0.0
auth_type = md5
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 50
reserve_pool_size = 10
reserve_pool_timeout = 3
server_lifetime = 3600
server_idle_timeout = 600
log_connections = 0
log_disconnections = 0
stats_period = 6020. Environment Variables & Secrets
Complete Environment Reference
# ================================================
# STACKHOUSE PRODUCTION ENVIRONMENT VARIABLES
# Store in GCP Secret Manager / AWS Secrets Manager
# NEVER commit to git
# ================================================
# Server
STACKHOUSE_PORT=3000
STACKHOUSE_HOST=0.0.0.0
STACKHOUSE_LOG_DIR=/var/log/stackhouse
# Database (via Cloud SQL Proxy or direct)
STACKHOUSE_URL=postgres://stackhouse_user:PASSWORD@127.0.0.1:5432/stackhouse
# Authentication
STACKHOUSE_JWT_SECRET=<256-bit random hex, generated at deploy>
# Generate: openssl rand -hex 32
# Redis
REDIS_URL=redis://:PASSWORD@10.0.0.5:6379/0
# Qdrant (Vector Database)
QDRANT_URL=http://qdrant.stackhouse.svc.cluster.local:6333
# Object Storage
GCS_BUCKET=stackhouse-storage-prod
GCS_PROJECT=your-gcp-project
# OR for AWS S3:
AWS_S3_BUCKET=stackhouse-storage-prod
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=<key>
AWS_SECRET_ACCESS_KEY=<secret>
# AI Services (all optional)
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=AIza...
COHERE_API_KEY=...
# OAuth Providers
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxx
GITHUB_CLIENT_ID=xxx
GITHUB_CLIENT_SECRET=xxx
# CAPTCHA
HCAPTCHA_SECRET=xxx
RECAPTCHA_SECRET_KEY=xxx
TURNSTILE_SECRET_KEY=xxx
# Twilio (phone OTP)
TWILIO_ACCOUNT_SID=xxx
TWILIO_AUTH_TOKEN=xxx
TWILIO_PHONE_NUMBER=+1xxx
# Monitoring
SENTRY_DSN=https://xxx@o0.ingest.sentry.io/0
DATADOG_API_KEY=xxx
# Feature flags
STACKHOUSE_ENABLE_FUNCTIONS=true
STACKHOUSE_ENABLE_AI_ENDPOINTS=true
STACKHOUSE_ENABLE_REALTIME=true
STACKHOUSE_MAX_FILE_SIZE_MB=100
STACKHOUSE_RATE_LIMIT_RPS=100Summary Comparison Table
| Feature | AWS | GCP ⭐ | Hetzner | Hostinger | Heroku |
|---|---|---|---|---|---|
| Monthly cost @100k | ~$1,535 | ~$1,295 | ~$455 | N/A | ~$4,080 |
| PostgreSQL managed | RDS ✅ | Cloud SQL ✅ | Self-mgd ⚠️ | MySQL only ❌ | Heroku PG ✅ |
| Kubernetes | EKS ✅ | GKE ✅ | k3s ⚠️ | ❌ | ❌ |
| Auto-scaling | ✅ | ✅ | Manual ⚠️ | ❌ | ✅ (add-on) |
| Global CDN | CloudFront | Cloud CDN | Cloudflare | Cloudflare | Cloudflare |
| WAF | AWS WAF | Cloud Armor | CF Free | CF Free | CF Free |
| WebSocket support | ✅ | ✅ | ✅ | ✅ (limited) | ⚠️ (55s TO) |
| Object storage | S3 ✅ | GCS ✅ | Hetzner S3 ✅ | ❌ self | Need S3 add-on |
| Redis managed | ElastiCache | Memorystore | Self ⚠️ | Self ⚠️ | Heroku Redis |
| PITR (DB backups) | 35 days ✅ | 7 days ✅ | Manual ⚠️ | ❌ | 4 days ✅ |
| Read replicas | ✅ | ✅ | Self ⚠️ | ❌ | ✅ (Premium) |
| Multi-zone HA | Multi-AZ ✅ | Multi-zone ✅ | Manual ⚠️ | ❌ | ✅ |
| VPC / Private network | ✅ | ✅ | ✅ | ❌ | Private Sp. |
| Secrets management | Secrets Mgr | Secret Mgr | Self/Vault | ❌ | Config Vars |
| DevOps complexity | Medium | Medium | High | Low (limited) | Low |
| Compliance (SOC2) | ✅ | ✅ | ⚠️ manual | ❌ | ✅ |
| GDPR data residency | EU regions ✅ | EU regions ✅ | Nuremberg ✅ | EU ✅ | US only ⚠️ |
| Overall rating | 4.6/5 | 4.8/5 ⭐ | 3.1/5 | 1.9/5 | 2.8/5 |
Final recommendation:
- 🥇 Production (funded startup/enterprise): GCP — best managed services, GKE is easiest Kubernetes, Cloud SQL is excellent
- 🥈 Production (bootstrapped, EU market): Hetzner + Cloudflare — 65% cheaper, requires more DevOps skill, great EU GDPR story
- 🥉 Production (AWS-first company): AWS — slightly more expensive but massive ecosystem and compliance tooling
- 🚫 Avoid for Stackhouse production: Heroku (too expensive), Hostinger (too limited)
Document version: 1.0 — March 2026 Stackhouse targeting 100,000 users with Rust middleware + PostgreSQL backend Architecture designed for horizontal scalability to 1M+ users without re-architecture