Files
2nd/10_Wiki/Topics/AI_and_ML/SaaS.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

209 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-saas
title: SaaS (Software as a Service)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Software as a Service, Cloud Software, Multi-tenant SaaS]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [saas, multi-tenancy, subscription, ai-native, vertical-saas]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Next.js / Stripe / Postgres RLS
---
# SaaS (Software as a Service)
## 매 한 줄
> **"매 multi-tenant, subscription-based, browser-delivered software — 매 install 의 X, 매 always-latest"**. 매 1999 Salesforce ("End of Software") 로 출발 → 매 2010s SaaS 1.0 (horizontal CRM/HR) → 매 2020s vertical SaaS (Toast, Procore, Veeva) → 매 2026 AI-native SaaS (Glean, Harvey, Cursor) 가 매 outcome-based pricing 으로 매 seat-based 모델 을 흔드는 시기.
## 매 핵심
### 매 Pillars
- **Multi-tenancy**: tenant-isolated data on shared infra (RLS, schema-per-tenant, DB-per-tenant).
- **Subscription**: MRR/ARR, Stripe billing, dunning, proration.
- **Self-serve onboarding**: PLG funnel, time-to-value 분 단위.
- **Continuous delivery**: weekly/daily ship, no version skew.
- **Observability**: per-tenant SLO, usage analytics, churn signals.
### 매 SaaS metrics
- **ARR/MRR**, **NRR** (Net Revenue Retention) — best signal of product fit.
- **CAC payback** — months to recoup acquisition.
- **Magic Number** = (ΔARR × 4) / S&M spend.
- **Gross margin** — typical SaaS 70-85%, AI-SaaS 50-70% (inference cost).
- **LTV/CAC** ≥ 3, payback ≤ 12 months.
### 매 Pricing models
- **Per-seat**: classic Salesforce/Slack — saturating in AI era.
- **Usage-based**: Snowflake, Twilio, OpenAI — aligns to value.
- **Outcome/agent-based**: 2026 AI-native — pay per resolved ticket, per qualified lead.
- **Hybrid**: platform fee + usage overage.
### 매 응용
1. Horizontal SaaS (CRM, HRIS, ITSM, comms).
2. Vertical SaaS (legal, dental, construction, hospitality).
3. Developer SaaS (GitHub, Vercel, Sentry).
4. AI-native SaaS (Cursor, Glean, Harvey, Decagon).
5. Embedded SaaS (in-app commerce, fintech).
## 💻 패턴
### Multi-tenant Postgres RLS
```sql
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON documents
USING (tenant_id = current_setting('app.tenant_id', true)::uuid);
-- App connection middleware
SET LOCAL app.tenant_id = '7f3a...';
```
### Stripe subscription with proration
```typescript
import Stripe from 'stripe'
const stripe = new Stripe(process.env.STRIPE_SECRET!)
await stripe.subscriptions.update(subId, {
items: [{ id: itemId, price: 'price_pro_monthly', quantity: 25 }],
proration_behavior: 'create_prorations',
billing_cycle_anchor: 'unchanged',
})
```
### Usage-based metering (Stripe meters, 2026)
```typescript
await stripe.billing.meterEvents.create({
event_name: 'api_calls',
payload: {
stripe_customer_id: customer.id,
value: '1',
},
})
// Subscribe customer to metered price; Stripe aggregates and bills monthly
```
### Tenant context middleware (Next.js)
```typescript
// app/middleware.ts
import { NextResponse } from 'next/server'
export async function middleware(req: Request) {
const session = await getSession(req)
const tenantId = session?.tenantId
if (!tenantId) return NextResponse.redirect('/login')
const res = NextResponse.next()
res.headers.set('x-tenant-id', tenantId)
return res
}
```
### Per-tenant rate limit (Upstash Redis)
```typescript
import { Ratelimit } from '@upstash/ratelimit'
import { Redis } from '@upstash/redis'
const limiters = new Map<string, Ratelimit>()
function tenantLimiter(plan: 'free' | 'pro' | 'enterprise') {
const limits = { free: 100, pro: 1000, enterprise: 10000 }
return new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(limits[plan], '1 m'),
})
}
```
### PLG signup with magic-link (no password)
```typescript
// Send magic link, no password friction
const token = jwt.sign({ email, tenantId: nanoid() }, SECRET, { expiresIn: '15m' })
await sendEmail(email, `https://app.example.com/auth?t=${token}`)
// On click: provision trial tenant, redirect to onboarding wizard
```
### AI-native SaaS — usage-aware inference cost
```typescript
async function chat(tenantId: string, msgs: Message[]) {
const tier = await getTier(tenantId)
const model = tier === 'enterprise' ? 'claude-opus-4-7' : 'claude-haiku-4-5'
const resp = await anthropic.messages.create({
model, max_tokens: 1024, messages: msgs,
metadata: { user_id: tenantId },
})
await meterUsage(tenantId, {
input_tokens: resp.usage.input_tokens,
output_tokens: resp.usage.output_tokens,
model,
})
return resp
}
```
### Outcome pricing instrumentation
```typescript
// Charge only when AI agent successfully resolved
async function recordResolution(tenantId: string, ticketId: string, resolved: boolean) {
if (resolved) {
await stripe.billing.meterEvents.create({
event_name: 'resolved_ticket',
payload: { stripe_customer_id: tenantId, value: '1' },
})
}
}
```
### Tenant-isolated S3 (per-prefix IAM)
```python
# Generate scoped STS token per tenant request
sts = boto3.client("sts")
policy = {"Version": "2012-10-17", "Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": [f"arn:aws:s3:::tenants-bucket/{tenant_id}/*"],
}]}
creds = sts.assume_role(
RoleArn=ROLE, RoleSessionName=f"tenant-{tenant_id}",
Policy=json.dumps(policy), DurationSeconds=900,
)
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Early-stage horizontal | Shared schema + RLS, Stripe per-seat |
| Vertical w/ compliance | Schema-per-tenant or DB-per-tenant |
| AI-native, variable cost | Usage-based + cap to protect margin |
| Enterprise w/ SOC2/HIPAA | Single-tenant deploy option, BYOC |
| PLG self-serve | Magic-link + provisioned trial in <60s |
**기본값**: shared-DB RLS + hybrid pricing (platform fee + usage) + Stripe meters + PLG onboarding.
## 🔗 Graph
## 🤖 LLM 활용
**언제**: in-product copilot, customer support deflection, churn prediction from usage signals, content/email generation, dynamic onboarding.
**언제 X**: pricing/billing computation — must be deterministic for audit and revenue recognition.
## ❌ 안티패턴
- **No tenant isolation**: WHERE tenant_id checked only in app layer → IDOR breach.
- **Per-seat pricing for AI**: high-usage user breaks margin; need usage cap or tier.
- **Free tier without limits**: abuse → infra cost spirals.
- **Single-region SaaS for global**: latency + data residency violations (GDPR).
- **No self-serve cancel**: regulatory risk (FTC click-to-cancel 2024) + churn spikes.
- **Version skew**: different customers on different versions → support combinatorics explode.
## 🧪 검증 / 중복
- Verified (a16z SaaS metrics, OpenView PLG benchmarks, Stripe Billing docs, AWS SaaS Lens).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — multi-tenancy, pricing models, AI-native SaaS 2026 |