Skip to content

Hosting & Data Plan

Document type: Engineering Plan — Hosting & Data Status: Approved Last updated: 2026-05-24

This page captures the decisions the platform needs to start building: where code runs, where data lives, what messaging/queue layer we use, and what language the backend is written in. It supersedes section 8 of the Kick-off Plan.

Note (Aug 2026): infrastructure has moved from Hetzner to DigitalOcean to consolidate billing and remove SRE burden via managed data services. The platform now exposes two API surfaces from day 1core.kayasync.com (internal clients) and api.kayasync.com (external customers). Compute runs on DO App Platform (core + api + ai-sidecar) + a DO Droplet (dispatch + location + NATS), with DO Managed Postgres Production (auto-failover) + Managed Redis. Cloudflare stays as the free edge, and R2 stays for object storage (zero egress wins vs DO Spaces). MVP tier lands at ~$365/mo all-in — DO subtotal ~$221 + observability/error/security/secrets stack ~$144. See System Architecture for the canonical topology, API surface, and full cost breakdown. This page's Cloudflare free-tier rationale still stands; the specific box counts and Hetzner references in "Recommended architecture" § 2 and the Phasing table below are superseded.


TL;DR

  • Cloudflare's free tier alone is not enough to run the platform end-to-end. It is enough for the marketing site, the wiki, and the public edge (DNS, TLS, DDoS, R2 media).
  • The platform runs on DigitalOcean at MVP: DO App Platform for core, api, and the AI sidecar; a DO Droplet (s-2vcpu-4gb) for location-svc + dispatch-svc + NATS + Caddy; DO Managed Postgres Production (auto-failover) + Managed Redis 2 GB. Cloudflare stays as the free edge.
  • Backend languages: TypeScript on Hono for core + api HTTP surfaces, Go for the WSS location + dispatch services, Python (FastAPI) for the AI/ML sidecar only.
  • Total cost at MVP: ~$371/mo all-in (~$227 DO subtotal + ~$144 observability / error / edge-security / secrets stack) + per-txn SMS and mobile-money fees. See System Architecture → Cost model for the line-by-line breakdown and the Stage 2/3/4 trajectory.

Why not "everything on Cloudflare free"

Three load-bearing reasons:

  1. Free Workers is 100,000 requests/day total. Telemetry heartbeats alone exhaust this in minutes — see Operator Journey §5.1. At 1 heartbeat / 30 s × 100 active operators × 16 h/day = ~192,000 req/day. Pilot scale is already over the cap.
  2. Cloudflare Queues require the Workers Paid plan ($5/mo minimum). There is no free Queues tier. The platform is explicitly event-driven — see Governing Assumptions: "Event-driven governance — each meaningful action must generate an event". A real queue is non-negotiable.
  3. Cloudflare has no Redis, no MQTT, no Kafka. The closest free analogues are KV (eventually consistent, 1K writes/day on free) and Durable Objects (paid plan only). The free tier cannot host the messaging/queue layer the platform's state machine needs.

Adjacent constraints that matter even on paid Cloudflare:

ServiceFree tierWhy it bites us
Workers (free)100K req/dayTelemetry exhausts this
Workers Logs (free)200K events/day, 3-day retentionNot enough for an event-sourced audit log
D1 (free)5 GB, 5M reads/day, 100K writes/dayAudit + telemetry + events exceed it fast
R2 (free)10 GB, 1M Class-A, 10M Class-B/mo, zero egressAt ~3 MB/scan video, free tier = ~3,300 scans total — one pilot week
Workers AI (free)10K neurons/day sharedA single Llama-3.2-vision OCR burns 2,500–5,000 neurons → 2–4 OCRs/day
StreamNo free tierNot used — R2 alone is the right home for raw video
Zero Trust / AccessFree up to 50 usersFine for internal tools, not for thousands of operators

What does stay free on Cloudflare at meaningful scale:

  • DNS / CDN / TLS / DDoS — unlimited, free
  • Workers + Pages for static-shape sites (marketing, wiki, admin UI)
  • R2 for media (zero egress is the real win vs S3 at $0.09/GB)
  • Email Routing (inbound team email, free)
  • Turnstile (CAPTCHA, free)
  • Web Analytics (cookieless, free)

Three layers, three hosts.

1. Edge / public surface — Cloudflare (free everything)

SurfaceStackStatus
kayasync.com, test.kayasync.comAstro Worker + static assets✅ Live
wiki.kayasync.comVitePress + password-gate Worker✅ Live
cdn.kayasync.comR2 bucket, public read for scan media (egress-free)⬜ Pending
app.kayasync.com, admin.kayasync.comNext.js 15 (App Router) + React 19, single Turborepo app with RBAC-scoped routing⬜ Pending

Edge services we keep free: DNS, TLS, DDoS, Turnstile, Web Analytics, Email Routing.

2. Backend application + data — DigitalOcean (App Platform + Droplet + Managed Postgres/Redis) [SUPERSEDED — see System Architecture]

Specs: 2 vCPU, 4 GB RAM, 40 GB NVMe, EU data centre, ISO 27001.

Stack — the physical shape has evolved to 5 apps across App Platform + a Droplet. See System Architecture § Core services (logical) for the canonical mapping. Historical single-monolith stack was:

ComponentRoleNotes
Hono (TypeScript) — now split into core.kayasync.com + api.kayasync.com on App PlatformBackend HTTP APIsTwo surfaces from MVP: core for internal clients (admin/mobile/client), api for third-party customers
Go — location-svc + dispatch-svc on the dispatch dropletReal-time WSS + geospatial matchingBehind ws.kayasync.com — separated from core because Hono/Node is the wrong runtime for high-concurrency WSS
Postgres — now DO Managed Production (auto-failover)Event store + transactional state + audit logSingle source of truth; TimescaleDB extension for location-history hypertables
Redis — now DO Managed Basic 2 GBGEO index + rate limits + sessionsManaged, no self-host burden
NATS JetStream — co-located on the dispatch dropletEvent bus / pub-sub~50 MB RAM; Kafka / Redpanda deferred to Stage 3
Python FastAPI (ai-sidecar) on App Platform ProOCR + heavy AI sidecarPaddleOCR for phone-number extraction, OpenCV for video frames
Caddy on the dispatch dropletReverse proxy + auto-TLS for ws.kayasync.comSingle binary, no manual cert renewal

Capacity headroom: the current tier (see Cost model) is comfortable up to ~1,000 active operators.

Backups: nightly pg_dump → R2 bucket, 30-day retention (belt-and-braces on top of DO Managed Postgres's automated backups + 7-day PITR).

Failover: DO Managed Postgres Production already includes an auto-failover standby node in the same region. Add a second dispatch droplet + DO Load Balancer at Stage 2 (see architecture doc's Stage 2 upgrade list).

3. Mobile app — operator client

  • React Native + TensorFlow Lite for on-device fingerprint / replay detection
  • All capture flows work offline per Feature Inventory §M9; sync via background queue
  • FCM for push (unlimited free), Whisper via Workers AI for voice confirmation (well under 10K neurons/day for short clips)

Capability → service mapping

Comprehensive map for every cross-cutting need in Feature Inventory. "Free?" assumes MVP / first-pilot scale.

CapabilityRecommended serviceFree at MVP?
Marketing site (live)Cloudflare Workers + static assets
Internal wiki (live)Cloudflare Pages + Worker password gate
12 backend logical services → 5 physical appsDO App Platform (core, api, ai-sidecar) + DO Droplet (location-svc, dispatch-svc, NATS, Caddy) — see architecture doc~$227/mo DO subtotal
Postgres (event store, txn state, multi-tenant)DO Managed Postgres Production (auto-failover) + TimescaleDB extension$120/mo
Redis (rate limit, session, dedupe, GEO index)DO Managed Redis Basic 2 GB$30/mo
Message queue / event busNATS self-hosted (Postgres LISTEN/NOTIFY for the very first cut)
Telemetry heartbeat ingestionHono /telemetry endpoint, batched, into NATS
Object storage (video evidence, SOD photos, agreement videos)Cloudflare R2✅ <10 GB, then $0.015/GB-mo
Video AI integrity (fingerprint, replay, tamper)On-device TensorFlow Lite + server-side Python sidecar
OCR (designee phone number)PaddleOCR on the Python sidecar; fall back to Workers AI vision for low-confidence
Speech-to-text (voice confirmations)Cloudflare Workers AI Whisper
Text-to-speech (low-literacy prompts)Pre-record Prompt Vocabulary as MP3s in R2
Authentication (operator phone+OTP, partner SSO)Hono + JWT + bcrypt against Postgres; SMS OTP via Africa's Talking✅ code; SMS paid per msg
Push notificationsFirebase Cloud Messaging (unlimited free)
Transactional emailResend (already wired, 3,000/mo free)
Mobile money payoutsFlutterwave (per-txn fees accepted)n/a
Admin / supervisor dashboardSingle Next.js 15 app behind Cloudflare Access (free ≤ 50 users)
Enterprise client portal (M12)Same app, different RBAC scope
Regulator / partner exports (M10, M13)Postgres view + on-demand CSV/JSON dump
Observability (logs, metrics, traces)Grafana Cloud free (10K series, 50 GB logs, 14d) OR self-hosted Grafana + Loki + Prometheus
Error trackingSentry free (5K errors/mo) or self-hosted GlitchTip
Background / scheduled jobsHono cron loop polling NATS / Postgres

Backend language

Primary: TypeScript on Hono

  • Runs identically on Cloudflare Workers, Node, Bun, and Deno — strategic optionality for free. Move a handler from Workers to a DO App Platform app (or back) without rewriting.
  • Light, modern, Zod-friendly, OpenAPI-ready
  • The team is already deep in TS (Astro website, auth-worker) — no language switch needed
  • Shared types between mobile (React Native + TS) and backend cut a whole class of bugs

Secondary: Python (FastAPI)

Only for the AI/ML sidecar — OCR (PaddleOCR), video frame analysis (OpenCV), fingerprint extraction. Python's CV/ML ecosystem is not negotiable here. Keep the sidecar small and behind an internal HTTP endpoint.

Future option: Go

If the telemetry ingestor becomes a bottleneck, Go's goroutines + GC profile fit high-fanout streaming better than Node. Don't pre-optimise — only switch when traces show it's needed.

  • Rust — wrong cost/benefit for a small team's MVP; revisit if a specific service becomes perf-critical
  • Elixir / Phoenix — technically perfect for the real-time dispatcher fanout, but hiring + ecosystem are too thin for a Ghana-based team at MVP. Re-evaluate at 10+ engineers.
  • Python as primary — would slow iteration vs TS and force two languages on the frontend anyway

Phasing

Post-migration to DigitalOcean, the phasing model is documented canonically in System Architecture → Cost model → Trajectory across stages. Summary:

StageWhenAll-in / moWhat's added
MVP recommendedSep 2026 – Mar 2027~$371DO App Platform (core + api + ai-sidecar) + Droplet (location-svc + dispatch-svc + NATS) + Managed Postgres Production + Managed Redis 2 GB + Grafana Cloud Pro + Sentry Team + Cloudflare Pro + 1Password Teams
Stage 2 — controlled pilotApr – Aug 2027~$550Add HA on core (2 instances), second dispatch droplet + DO LB, upgrade Postgres to next tier
Stage 3 — regional scaleSep 2027 – 2028~$1,500DOKS (K8s), Redpanda Cloud, second region, dedicated observability stack
Stage 4 — Uber-scale2029+10K+Multi-region active-active, custom matching engine, dedicated SRE team

Open questions / decisions still to make

  1. Jurisdiction. DigitalOcean's nearest regions to Ghana are FRA1 (EU) and BLR1/SGP1. If Ghana data-residency rules require West-African hosting, evaluate AWS af-south-1 or a regional partner. Legal to confirm with Enyonam.
  2. Pilot scale. Concrete numbers from NKA: operators in pilot 1, scans/operator/day, corridors. Re-check R2 / Postgres / dispatch droplet capacity projections once known.
  3. CF Access seats. Free tier caps at 50 users. When ops-team headcount crosses ~40 (Stage 2), decide between CF Access paid (~$3/user/mo) or self-hosted Zero Trust proxy.

Repo shape (for execution)

When Phase 1 starts, the new monorepo kayasync-platform follows Turborepo per Kick-off Plan §2:

kayasync-platform/
├── apps/
│   ├── api/             # Hono backend
│   ├── admin/           # Internal dispatch/supervisor UI
│   ├── client/          # Enterprise client portal
│   └── mobile/          # React Native operator app
├── services/
│   └── ai-sidecar/      # Python FastAPI (OCR + video AI)
├── packages/
│   └── shared-types/    # Zod schemas shared with mobile + admin
└── infra/
    ├── docker-compose.yml
    ├── Caddyfile
    └── backup/

Sources

Cloudflare: Workers pricing · Workers limits · R2 pricing · D1 pricing · KV pricing · Workers AI pricing · Vectorize pricing · Stream pricing · Zero Trust · Email Routing limits

Alternatives: Hetzner Cloud · Neon Postgres · Supabase · Upstash · Fly.io · Render · Firebase / FCM · Flutterwave Ghana · Africa's Talking Ghana

Kaya Sync Internal Documentation