Architecture & SLOs
How VikingBI handles real Shopify shops with hundreds of thousands of orders — without falling over.
Stack
- Frontend & API: TanStack Start on Cloudflare Workers (edge SSR + server functions).
- Database: Managed Postgres with row-level security; one row per tenant on every fact table.
- Ingest: Shopify webhooks → signed HTTP route → Postgres; bulk-history sync jobs run as background tasks with idempotent upserts.
- Auth: Supabase Auth (JWT). Server-side functions verify the bearer token on every call.
Multi-tenant isolation
- Every user-data table has
organization_id+ RLS policy gated onauth.uid()membership. - Service-role writes (sync workers, simulations) bypass RLS but are scoped to a single org per job.
- Demo & simulation orgs carry
is_demo/is_simulationflags, surfaced in the admin console.
Scaling design
- Worker-friendly batching. Long jobs (bulk sync, simulations) are split into ≤10s server-fn invocations and chained from the client. No single Worker request runs past its CPU budget.
- Indexed hot paths.
orders (organization_id, sku_id, ordered_at)andstock_history (organization_id, sku_id, date)are the queries we measure in /status. - Webhook idempotency. Shopify event IDs are deduped at insert via unique constraint; replay storms are absorbed.
- Realtime view-models. Dashboard counts come from materialized aggregates updated by triggers, not
SELECT COUNT(*)at request time.
Service-level objectives
| Surface | Target | Live measurement |
|---|---|---|
| Public API & SSR availability | 99.9% rolling 30d | /status uptime card |
| Shopify webhook ack | p95 < 500ms | webhook_events.received_at vs response time |
| Bulk sync (500k orders) | < 30 min end-to-end | shopify_sync_jobs.duration |
| Dashboard load (any tenant size) | p95 < 1.5s | scale-report → p95_dashboard_ms |
| SKU detail (1k order rows) | p95 < 800ms | scale-report → p95_sku_detail_ms |
How we prove it
A nightly GitHub Actions workflow runs a k6 load test against the published API and posts results to load_test_runs. On demand, SuperAdmins can spin up a 500k-order synthetic tenant via the scale-sim harness — it runs the real ingest + analytics path and emits a token-gated /scale-report/$token page anyone can review.
What we are honest about
- This is a small platform run by a small team. The numbers above come from continuous measurement, not marketing.
- We publish failures: every degraded interval shows on /status.
- Scale-report links expire and are not indexed; share them with prospects who ask for proof.