ADR 011: Multi-Tenancy Model¶
Status¶
Accepted
Context¶
InertialEvent must support multiple users trading simultaneously, each with their own: - Exchange credentials - Strategy configurations - Position tracking - Rate limits
The system must prevent "noisy neighbor" problems where one user's activity degrades performance for others, while remaining cost-effective for smaller users.
Decision¶
Implement a hybrid multi-tenancy model with pod-based isolation for enterprise users and shared infrastructure with strict quotas for basic users.
Tenancy Tiers¶
| Tier | Isolation Level | Resource Guarantees |
|---|---|---|
| Free/Basic | Shared binary | Strict rate limits, tokio::semaphore protection |
| Enterprise | Isolated Pods/Containers | Dedicated CPU/memory, guaranteed throughput |
Implementation Pattern¶
pub struct UserContext {
user_id: UserId,
subscription_tier: Tier,
rate_limiter: RateLimiter,
}
impl OrderExecutor {
pub async fn execute(&self, ctx: &UserContext, order: Order) -> Result<OrderId> {
// Rate limit check
ctx.rate_limiter.check()?;
// Tier feature check
if order.is_arbitrage() && !ctx.subscription_tier.allows_arbitrage() {
return Err(Error::UpgradeRequired);
}
// Execute with user's credentials
self.submit_order(ctx.user_id, order).await
}
}
Isolation Mechanisms¶
| Mechanism | Purpose | Implementation |
|---|---|---|
| Rate Limiting | Prevent API exhaustion | Token bucket per user |
| Semaphores | Prevent CPU hogging | tokio::semaphore per user |
| Row-Level Security | Data isolation | PostgreSQL RLS policies |
| Credential Isolation | Security | Per-user encryption keys (ADR-009) |
Quota System¶
- Token bucket algorithm for API/order throughput
- Configurable limits per subscription tier
- Real-time usage tracking in Redis
- Alert on quota approaching exhaustion
Alternatives Considered¶
| Approach | Pros | Cons | Verdict |
|---|---|---|---|
| Hybrid (shared + pods) | Cost-effective, scales | Complexity | Chosen |
| Single binary, all users | Simple, cheap | Noisy neighbor risk | Rejected |
| Pod per user | Perfect isolation | Cost prohibitive at scale | Enterprise only |
| Separate deployments | Maximum isolation | Operational nightmare | Rejected |
Consequences¶
Positive¶
- Cost-effective for small users (shared infrastructure)
- Enterprise users get guaranteed performance
- Clear upgrade path from free to paid tiers
- PostgreSQL RLS provides strong data isolation
Negative¶
- More complex deployment model
- Need to monitor and tune semaphore limits
- Enterprise pods increase operational surface
Neutral¶
- Quota tuning will require iteration based on real usage patterns
Security Considerations¶
- Credential isolation: Each user's keys encrypted with user-specific key
- Data isolation: PostgreSQL Row-Level Security enforced at database layer
- API isolation: Each user gets unique API keys
- Audit: All cross-user access attempts logged and alerted
References¶
- PostgreSQL RLS - Row-Level Security
- Token Bucket Algorithm - Rate limiting
- FRS Section 3.7 - Multi-tenancy requirements
Linked Requirements¶
- NFR-ARCH-007: Support multi-tenant with pod-based isolation
- FR-MT-001: User registration and onboarding
- FR-MT-002: Subscription tiers (Free, Pro, Enterprise)