Skip to main content

ADR-005: Deployment Strategy β€” UAT on Render, Production TBD

Status: βœ… Accepted (UAT) Β· πŸ”² Pending (Production) Date: 2026-03-22 Decision Makers: Tilak Kumar


Context​

ThreatWeaver needs to deploy a React SPA (frontend) and a Node.js API server (backend). The deployment platform affects cost, latency, developer experience, and operational complexity.

The key constraints:

  • Backend runs long-lived WebSocket connections for scan sensors (rules out serverless functions with 30s timeouts)
  • Backend requires persistent process memory (in-memory scan state, agent concurrency tracking)
  • Frontend is a pure static SPA β€” no server-side rendering needed
  • Database is PostgreSQL β€” hosted on Render (UAT) or to be decided for production
  • Budget: keep infrastructure costs minimal during development phase

Decision​

UAT environment: Deploy everything to Render (backend + static site + PostgreSQL).

Production environment: Infrastructure not yet decided β€” will be finalized at launch using the main branch.

Active environments:

Local (dev machines):
Frontend β†’ localhost:3005 (npm run dev, native)
Backend β†’ localhost:4005 (npm run dev, native)
Database β†’ Docker PostgreSQL (port 5432)

UAT (dev.threatweaver.ai):
Frontend β†’ Render Static Site (dev.threatweaver.ai)
Backend β†’ Render Pro Plus (threatweaver-backend.onrender.com)
Database β†’ Render PostgreSQL Pro 8GB
Branch β†’ dev (auto-deploys on push)

Production (TBD):
Frontend β†’ TBD at launch (Vercel / Cloudflare Pages / Render)
Backend β†’ TBD at launch (Render / Railway / AWS)
Database β†’ TBD at launch (Supabase / Render / Neon)
Branch β†’ main (protected, manual release only)

Git branch β†’ environment mapping:​

BranchDeploys toWho triggers
localLocalhost onlyDeveloper manually
devUAT (Render)Auto on push
mainProduction (TBD)Manual release process

Consequences​

Positive (UAT on Render):

  • Single platform (Render) for backend + frontend + database simplifies UAT management
  • No cross-platform coordination β€” one dashboard, one billing account
  • Render's persistent Node.js process supports WebSockets and long-running scans
  • UAT database is isolated from local dev β€” safe to test migrations against
  • Auto-deploy on dev push means UAT always reflects latest code

Negative / Trade-offs:

  • Render is Singapore region (ap-southeast-1) β€” slightly higher latency for US/EU users
  • No built-in horizontal scaling β€” manual instance scaling required
  • Render's PostgreSQL backup schedule is less flexible than Supabase
  • Production hosting decision is deferred β€” will require migration work when decided

What was removed:

  • kinavulnerabilitymanagement.vercel.app β€” old Vercel frontend URL, no longer active
  • kina-vulnerability-management-uq1t.onrender.com β€” old Render backend URL, no longer active
  • These URLs appeared in vercel.json, docusaurus.config.ts, and several docs β€” all cleaned up

Alternatives Considered​

OptionStatus
Vercel (frontend) + Render (backend) splitUsed previously, removed. Re-evaluate at production launch.
Full Render (frontend + backend + DB)Current UAT approach β€” working well
AWS (ECS + CloudFront)Candidate for production β€” higher control, higher operational cost
Cloudflare Pages + WorkersCandidate for production β€” edge performance, but Workers have execution limits
RailwaySimilar to Render, less mature β€” evaluate at launch
Self-hosted VPSToo much operational overhead for small team

Production Decision Criteria (When Ready)​

When production hosting is selected, evaluate against:

  1. WebSocket support β€” scan sensors require long-lived connections
  2. Persistent process β€” no cold starts, no serverless timeout limits
  3. PostgreSQL managed service β€” daily backups, PITR, SSL enforced
  4. Latency β€” target < 100ms p95 for API responses (Singapore β†’ global)
  5. Cost at scale β€” estimate for 50 concurrent tenants
  6. Zero-downtime deploys β€” rolling restart or blue/green