Chapter 2: Gathering Requirements — Functional vs Non-Functional

The first step in any system design is understanding WHAT you're building. Skip this and you'll design the wrong system. Every design starts with requirements gathering.

Functional Requirements (FR)

What the system DOES. The features, the behavior, the user-facing capabilities.

// Example: Design a URL shortener
Functional Requirements:
1. Given a long URL, generate a short URL
2. Given a short URL, redirect to the original long URL
3. Users can optionally set custom short URLs
4. URLs expire after a configurable time (optional)
5. Analytics: track click count per URL

Non-Functional Requirements (NFR)

How well the system performs. The quality attributes that constrain the design.

CategoryQuestionExample
ScaleHow many users/requests?100M URLs created/month, 10B redirects/month
LatencyHow fast must it respond?Redirect in < 50ms (p99)
AvailabilityHow much downtime is acceptable?99.99% uptime (< 52 min/year)
DurabilityCan we lose data?Never lose a URL mapping once created
ConsistencyCan reads be stale?New URL must work within 1 second of creation
SecurityAuth? Encryption? Abuse?Rate limit creation, block malicious URLs
CostBudget constraints?Run on < $10K/month infrastructure

The Questions to Always Ask

💡 Requirements Checklist
  1. Users: How many? Where geographically? Growth rate?
  2. Traffic: Reads vs writes ratio? Peak vs average? Burst patterns?
  3. Data: How much? How long to keep? What format?
  4. Latency: What's acceptable? p50? p99?
  5. Availability: What's the SLA? Can we have maintenance windows?
  6. Consistency: Must reads always be fresh? Or is eventual OK?
  7. Existing constraints: Tech stack? Cloud provider? Team expertise?

Read-Heavy vs Write-Heavy

URL Shortener: Writes: 100M/month = ~40 writes/sec Reads: 10B/month = ~4000 reads/sec Ratio: 100:1 read-heavy → Optimize for reads (caching, read replicas) Chat System: Writes: Every message is a write Reads: Users read messages once (mostly) Ratio: ~1:1 balanced, but write-heavy at peak → Optimize for writes (append-only, async) Telemetry/Monitoring: Writes: Thousands of metrics/sec from every server Reads: Occasional dashboard queries Ratio: 1000:1 write-heavy → Optimize for writes (LSM-tree, time-series DB)

Deriving Numbers from Requirements

// URL Shortener example:
// 100M new URLs/month
// → 100M / (30 days × 24h × 3600s) ≈ 40 URLs/sec (write QPS)
// Read:Write = 100:1 → 4000 reads/sec (read QPS)
//
// Storage: each URL mapping ≈ 500 bytes
// → 100M × 500B = 50GB/month new data
// → 5 years retention = 3TB total
//
// Bandwidth: 4000 reads/sec × 500B = 2MB/sec (trivial)

Example: Telecom System Requirements

// Design: AMF Session Management
// Functional:
//   - Handle UE Registration (create context)
//   - Handle Service Request (retrieve/update context)
//   - Handle Deregistration (delete context)
//   - Handle N2 handover (move context between AMFs)
//
// Non-Functional:
//   - 1M concurrent UE contexts
//   - Registration latency < 200ms (p99)
//   - 99.999% availability (5 nines = 5 min downtime/year)
//   - Stateless compute (context in external store)
//   - Survive single node failure with no data loss
//   - Geographic redundancy (multi-site)
Key Takeaways