Decisions & Trade-offs
An unfiltered log of our engineering compromises, performance benchmarks, and the explicit rejection of generic SaaS paradigms.
Go vs Python for Ingress
Context: Webhook ingestion needs high throughput and low memory footprint. Python (FastAPI) was initially evaluated.
Decision: We opted for Go at the edge. Python's GIL and async event loop overhead became apparent during synthetic load tests of 5,000+ concurrent webhook deliveries. Go's goroutines allow us to ingest, validate signatures, and dump to the event bus with minimal latency.
Trade-off: This forced a polyglot architecture. Go handles the dumb pipe, Python handles the smart AI parsing, increasing deployment complexity.
Rejection of 'Agentic' Loops
Context: Trend towards autonomous AI agents that reply and delete emails on the user's behalf.
Decision: We explicitly rejected autonomous actions. SortMail uses deterministic logic to construct prompts, but execution (sending, scheduling) always requires human confirmation.
Trade-off: Lower automation score on paper, but absolute trust in reality. We prioritize decision clarity over feature count. No silent actions, no hidden automation.
Ephemeral Token Storage
Context: Storing Gmail/Outlook OAuth tokens securely.
Decision: Tokens are encrypted at rest using a rotating master key (KMS). More importantly, the system aggressively expires refresh tokens if inactivity is detected, forcing re-authentication.
Trade-off: Increased user friction if they don't log in frequently. We accept this UX hit to maintain a fortified security posture.
Latency Benchmarks (p99)
| Operation | Target | Actual | Delta |
|---|---|---|---|
| Webhook Ingress (Auth + Enqueue) | < 50ms | 12ms | -38ms |
| Attachment Extraction (Air-Gapped) | < 2000ms | 2800ms | +800ms |
| LLM RAG Context Assembly | < 300ms | 185ms | -115ms |
| Full BLUF Generation (Claude Haiku) | < 1500ms | 1200ms | -300ms |