Problem Decomposition: Verbs, Nouns and Adjectives in System Design
Turn a vague system design prompt into requirements: verbs become use cases, nouns become owned entities, adjectives become constraints that justify components.
System design prompts usually arrive as one vague line: "Design Twitter" or "Design Uber". The first job is to turn that into concrete technical requirements. Instead of guessing what the interviewer wants, use the words in the problem statement as anchors. Three kinds of words carry three kinds of information:
Step 0: verbs become use cases
Verbs reveal operations. "Users can post tweets" contains *post*; "users view their feed" contains *view*. Pull out every verb and each one becomes a use case, a functional requirement and usually an API endpoint. Most verbs map to CRUD or a few extras: create, read, update, delete, search, notify, process.
Don't stop at listing them. For each one, define what correct means:
- Does "post a tweet" deduplicate identical posts?
- Must followers see a new tweet immediately, or is eventually acceptable?
- Must posts be kept forever? Can deleted ones be recovered?
These questions turn a fuzzy verb into a precise contract, and the answers feed directly into the consistency and storage decisions later.
Step 1: nouns become entities and ownership
Nouns reveal data models. "Users post tweets" has two nouns, *users* and *tweets*. "Users follow other users" reveals a relationship entity, *follow*. List every entity and how they relate; they usually become your tables or collections.
Then, for each entity, name its source of truth. Who owns user profiles? Where do tweets live? Which service controls the follow relationship? Ownership decides write authority: only the user service updates profiles, only the tweet service creates tweets. Clear ownership prevents two services from writing the same data in conflicting ways and draws the consistency boundaries of the system. See database per service.
Step 2: adjectives become constraints and add-ons
Adjectives reveal non-functional requirements, and those force architectural choices. "Instant notifications" contains *instant*, which needs real-time push or precomputation. "Highly available feed" contains *highly available*, which needs replication and stateless services.
| Adjective | Components it justifies |
|---|---|
| Instant / real-time | Push notifications, WebSockets, caching, precomputation |
| Reliable | Retries, idempotency, dead-letter queues, write-ahead logs |
| Highly available | Replication, stateless services, health checks |
| Auditable / secure | Encryption, access control, audit logs, compliance |
| Scalable | Partitioning, read replicas, message queues, horizontal scaling |
| Durable | Replicated storage, backups, write-ahead logs |
| Consistent / correct | Transactions, locking, sagas |
| Low latency | Caches, CDNs, precomputation, data placed near users |
Each adjective adds components. The goal isn't to cram in every technology; it's to justify each addition by tying it to a specific constraint. If no adjective asks for it, leave it out.
Worked example: Twitter
| Step | Extracted | Result |
|---|---|---|
| Verbs | post, view, follow, like, comment | Five use cases and one endpoint each: POST /tweet, GET /feed, POST /follow… |
| Nouns | user, tweet, follow, like, comment | Entities User, Tweet, Follow, Engagement (likes and comments merged), each owned by one service |
| Adjectives | low latency, highly available, scalable, durable | Feed cache, message queue, load-balanced instances and sharding, replicated databases |
The complete walkthrough is in Design Twitter.
Worked example: a ride-hailing app
Prompt: "Riders request rides and are matched with nearby drivers in real time. Drivers share their location continuously. Payments must be reliable."
- Verbs: request (a ride), match, share (location), pay. Use cases: create a ride request, find and assign a driver, ingest location updates, charge the rider.
- Nouns: rider, driver, ride, location, payment. Owners: the ride service owns rides and their state machine; the location service owns the latest driver positions; the payment service owns charges.
- Adjectives: *nearby* → a geospatial index; *real time* → WebSockets or push and in-memory location storage; *continuously* → a high-write ingestion path, often through a log like Kafka; *reliable* (payments) → idempotency keys, retries and a saga across ride and payment.
Worked example: a file sync service
Prompt: "Users upload large files and see them on all their devices. Uploads should resume after a network drop. Sharing must be secure."
- Verbs: upload, sync, share. Use cases: chunked upload, change notification to other devices, grant access.
- Nouns: user, file, chunk, device, share. The metadata service owns files and versions; blobs live in object storage.
- Adjectives: *large* → chunking and direct-to-storage uploads; *resume* → resumable uploads with per-chunk checksums; *all devices* → push notifications or long polling for changes; *secure* → presigned URLs, encryption and access checks.
Where it’s used
The first 5–10 minutes of any design round: it produces the functional requirements, the entity list and the non-functional requirements in a form you can design against.
The same extraction works on a real product brief: verbs become the API surface, nouns the data model, adjectives the SLOs.
Check every component in someone's diagram against the adjectives; anything that doesn't trace back to a constraint is a candidate to remove.
In an interview
- Read the prompt back as verbs, nouns and adjectives; it shows structure and gives the interviewer a chance to correct scope early.
- Ask what "correct" means for each verb before you design.
- Name an owner for every entity.
- When you add a component later, say which adjective it serves.