Lesson 7
Design a Simple App
Apply everything you have learned by architecting a production-ready todo application from scratch.
25 min read · Beginner
Putting it all together
You have learned about clients and servers, APIs, databases, caching, and load balancing. Now combine these concepts into a real architecture. In this capstone lesson, you will design a todo application — simple enough to understand, complex enough to exercise every concept from the learning path.
This is how architecture work actually happens. You start with requirements, identify components, define how they communicate, and make tradeoffs.
Step 1: Define requirements
Functional requirements
- Who are the users? Individuals managing personal task lists
- What do they need to do? Create, read, update, and delete todos; mark todos complete; optionally organize by category
- What is out of scope for v1? Real-time collaboration, offline sync, complex permissions
Non-functional requirements
| Requirement | Target | Why it matters |
|---|---|---|
| Availability | 99.9% uptime | Users expect their todos to be accessible |
| Latency | p95 < 200ms for reads | Snappy UI keeps users engaged |
| Durability | Zero data loss | Losing todos destroys trust |
| Security | Auth required, data isolated per user | Users must not see each other’s todos |
| Scalability | Support 10k users initially | Room to grow without redesign |
Clear requirements prevent over-engineering. A todo app does not need Kafka on day one.
Step 2: Full architecture diagram
Clients connect through a load balancer to stateless API servers, with Redis cache and PostgreSQL as source of truth.
Step 3: Define the API
| Endpoint | Method | Description |
|---|---|---|
/api/todos | GET | List all todos for the authenticated user |
/api/todos | POST | Create a new todo |
/api/todos/:id | PUT | Update a todo |
/api/todos/:id | DELETE | Delete a todo |
/api/auth/login | POST | Authenticate and return token |
/health | GET | Health check for load balancer |
All endpoints require authentication except /health. The server filters todos by user ID — users never see each other’s data.
Step 4: Create todo sequence
What happens when a user creates a todo:
1. User types "Buy groceries" and clicks Save
2. Web App → POST /api/todos { "title": "Buy groceries" }
3. Load Balancer → routes to API Server 2
4. API Server 2:
a. Verify JWT token → user_id = 42
b. Validate input (title required, max 500 chars)
c. INSERT INTO todos (user_id, title, done) VALUES (42, 'Buy groceries', false)
d. DELETE cache key user:42:todos
e. Return 201 Created { "id": 99, "title": "Buy groceries", "done": false }
5. Web App → adds todo to UI
Step 5: Failure modes
What happens when components fail:
| Component down | User experience | Recovery |
|---|---|---|
| Redis down | Slower responses (DB hit every time) | App still works; fix Redis, cache repopulates |
| PostgreSQL down | ”Unable to save todos” error | Critical — enable maintenance page, restore from backup |
| API Server 1 down | No impact (LB routes to Server 2) | LB health check removes Server 1; auto-restart or replace |
| Load Balancer down | Entire app unreachable | DNS failover to standby LB; this is why managed LBs matter |
| CDN down | Web app loads slowly from origin | Fallback to serving static files from API server |
Design for graceful degradation: Redis failure should slow things down, not break the app. Database failure is catastrophic — invest in backups and monitoring.
Step 6: Growth path
| Users | Architecture changes | Estimated cost |
|---|---|---|
| 1k | Single API server, no cache, managed PostgreSQL | ~$50/month |
| 10k | 2 API servers, Redis cache, load balancer | ~$200/month |
| 100k | 4-8 API servers, read replica, CDN, auto-scaling | ~$1,000/month |
| 1M | Microservices split, database sharding, multi-region | Engineering team decision |
You do not build for 1M users on day one. Design so each step is possible without rewriting everything.
Your turn: design checklist
Work through each item below. Click “Show hint” if you need guidance.
Design Your Todo App
Work through this checklist to design a simple but production-ready todo application.
Key takeaways
- Start with requirements — functional AND non-functional
- A simple app still needs deliberate architecture — client, API, cache, database, load balancer
- Design for today’s needs with tomorrow’s growth in mind — but do not over-build
- APIs are the contract between client and server — design them first
- Plan for failure — know what happens when each component goes down
- Every component from this learning path has a role in even a basic application
Common mistakes
- Skipping requirements and jumping to code — you will rebuild things you did not need
- Building microservices for a todo app — a monolith is the right choice for v1
- Forgetting authentication — even simple apps need to know who is making each request
- Not planning for failure — what happens when the database is down?
- Ignoring non-functional requirements — latency and availability matter from day one
Go deeper
- System Design Primer — comprehensive system design guide
- The Twelve-Factor App — principles for building modern applications
- Martin Fowler: Web Application Architecture — patterns for structuring web apps