# Non-functional requirements

> Latency, availability, durability, consistency and cost — written down as numbers.

Concept · Requirements & scale · https://levelcode.org/concepts/non-functional-requirements

Functional requirements say **what** a system does. Non-functional requirements say **how well**: how fast, how often available, how safe the data is. They decide most of the architecture, so they need to be numbers you can measure, not adjectives.

## The usual list

| Quality | Weak | Strong |
|---|---|---|
| Latency | "Fast" | "p99 under 200 ms for reads in-region" |
| Availability | "Highly available" | "99.9% monthly for reads, 99.5% for writes" |
| Durability | "Don't lose data" | "No acknowledged write is ever lost; backups restorable to any point in the last 14 days" |
| Consistency | "Consistent" | "A user sees their own writes immediately; others within 5 seconds" |
| Throughput | "Scalable" | "Sustain 5,000 writes/s at peak, 3× headroom" |
| Cost | — | "Under $0.002 per active user per month" |

## Percentiles, not averages

State latency as a percentile (p95, p99). The average hides the slow requests users actually notice, and if a page makes many calls, most page loads include at least one slow one. See [tail latency](https://levelcode.org/concepts/tail-latency).

## Different parts, different targets

Not every feature needs the same guarantees. Checkout might need 99.99% availability and strong consistency; recommendations can be stale and occasionally missing. Writing targets per feature keeps the expensive guarantees small.

## Ask for the weakest guarantee that works

Every step up in a requirement costs money and complexity: from 99.9% to 99.99% availability is the difference between one region with redundancy and active failover across regions. Ask which guarantee the product can actually live with, and design for that. See [availability and the nines](https://levelcode.org/concepts/availability-and-nines) and [SLIs, SLOs and error budgets](https://levelcode.org/concepts/sli-slo-sla).
