System Design Fundamentals
INFO 153B/253B Backend Web Architecture
Week 11: You've Been Building Blocks All Along
Spring 2026 | UC Berkeley School of Information
Today is a pivot point in the course. We're moving from learning individual technologies to thinking about system design. The big reveal: everything they've built this semester maps directly to universal system design building blocks. They've been system thinkers without knowing it. This should feel like an "aha" moment.
Today's Agenda
Part 1: From Code to Systems Thinking
Part 2: The 7 Building Blocks
Demo: Assignment 2 as a System Diagram
Exploration: Design a URL Shortener
Reminder: Assignment 2 due Friday, April 10th
Layout the plan. First half is lecture in two parts. Then a live demo where you diagram Assignment 2 using building blocks. Then hands-on exploration where they design a URL shortener.
Part 1
From Code to Systems Thinking
This section bridges what they already know (Flask, Docker, databases, workers) to the formal language of system design. By the end of Part 1, they'll see their semester of work through a new lens.
The Big Question
You've built Flask APIs, Dockerized apps, connected databases, and run background workers.
But how do you design a NEW system from scratch?
When someone says "build me a URL shortener" — where do you start?
When your boss asks for a notification system — what's your approach?
You know the tools. Now let's learn the thinking .
This is the motivating question for system design. They've learned technologies, but system design is about knowing which technologies to pick and how to connect them. Pause here and ask the class: "If I asked you right now to design a URL shortener, what's your first step?" Let a few people answer. Most will say something technology-specific. That's the gap we're closing today.
Code Writer vs System Thinker
Code Writer
"How do I implement this feature?"
"What framework should I use?"
"Let me find code to copy"
Focus: Implementation
System Thinker
"What are the requirements?"
"What patterns apply here?"
"What are the trade-offs?"
Focus: Architecture
This course is moving you from left to right.
Don't frame this as one being bad and the other good — both are necessary. Code writers build things; system thinkers design them. The best engineers do both. But most people start on the left and never get formal training on the right side. That's what Weeks 11-13 are about. In the AI era, this matters even more: AI can write code for you, but choosing the right architecture still requires human judgment.
Patterns Last, Technologies Don't
The Caching Pattern
2005: Memcached — fast key-value lookups
2015: Redis — richer features, same pattern
2020: AWS ElastiCache — managed cloud, same pattern
2026: Whatever's next — still the same pattern
Technologies evolve every few years
Patterns remain stable for decades
Learn the pattern once → apply to any technology
This is a career-level insight. The students who master patterns will adapt effortlessly when new technologies emerge. The ones who only learn specific tools will have to start over every few years. Redis might be replaced by something in 5 years, but the concept of "fast key-value lookup for caching" will still be there. This is especially relevant with AI — you can ask AI to implement any specific technology, but you need to know which pattern to ask for.
What is a Building Block?
Building blocks are proven system components that appear repeatedly across all modern systems.
Technology-agnostic: describe what a component does, not how
Universal: Instagram, Netflix, Gmail, Uber all use the same ones
Composable: combine them to design any system
Timeless: the same blocks have been used for decades
Think of them like LEGO — a small set of standard pieces that build anything.
Building blocks are the "right level of abstraction" for system design. Too low-level (code) and you get lost in details. Too high-level ("make it scalable") and you can't make concrete decisions. Building blocks sit in the sweet spot — concrete enough to make decisions, abstract enough to be universal. The key idea: when you see "Service" you don't think Flask or Express or Django — you think "something that handles request/response." The technology is an implementation choice that comes later.
You Already Know Building Blocks
Your 253B tech stack is building blocks:
SQLAlchemy / PostgreSQL
→
Relational Database
This is the "aha" moment. Let it land. They've been building with universal system design building blocks all semester — they just didn't have the vocabulary. Flask routes? That's a Service — it handles synchronous request/response. rq workers? That's a Worker — background processing. Redis Queue? Queue. PostgreSQL? Relational Database. They already know 4 of the 7 universal building blocks. Ask them: "So what are you missing?" That leads into Part 2.
Same Blocks, Everywhere
Instagram photo upload uses the same building blocks you used in Week 10:
User uploads photo
↓
[Service] receives the request
↓
[Relational DB] stores photo metadata
↓
[File Store] saves the actual image
↓
[Queue] triggers background processing
↓
[Worker] creates thumbnails, applies filters
↓
[Key Value Store] caches popular photos
Walk through this step by step. Point out that their Week 10 Notification Hub had almost the exact same flow: Service receives request, stores in database, enqueues job, Worker processes it. Instagram is just bigger — but the architecture is the same building blocks. That's the power of patterns: scale changes, blocks don't. Companies like Instagram, Netflix, Uber, Spotify — all built from the same 7 building blocks.
Building Blocks vs Technologies
Building Block (Pattern)
What: Fast lookup capability
Purpose: O(1) data access
Focus: Interface & behavior
Lifespan: Decades
Technology (Implementation)
Examples: Redis, Memcached, DynamoDB
Specifics: APIs, configs, pricing
Focus: Implementation details
Lifespan: Years
System thinkers say: "We need a Key Value Store for caching"
Then choose: "Let's use Redis because..."
This distinction is crucial. When you design a system, you pick building blocks first, then choose technologies. Not the other way around. In a design interview, if someone jumps straight to "we'll use Redis," that's a red flag. The right approach: "We need fast lookups for caching — that's a Key Value Store pattern. Redis is a good implementation choice because of X, Y, Z." Requirements first, technology second. This is the thinking that separates junior from senior engineers.
What Drives Your Design?
Three external forces shape every system:
User
Human interactions Your Flask API endpoints Login, search, upload
External Service
Third-party APIs Payment (Stripe) Email (SendGrid)
Time
Scheduled triggers Cron jobs, recurring tasks Daily reports, reminders
These forces determine which building blocks you need
Start every design by asking: Who/what interacts with this system?
External entities are the starting point of any system design. Before you pick building blocks, ask: Who are the users? What external services do we integrate with? What needs to happen on a schedule? In 253B: Users hit your Flask endpoints. You might call external APIs for email or payment. Time triggers things like reminder notifications (exactly what Assignment 2 does with due date reminders). These three forces drive everything.
Part 2
The 7 Building Blocks
Now we formalize the building blocks. They already know 5 from hands-on experience. We'll name all 7, go deep on each, and introduce the 2 they haven't used yet (File Store and Vector Database).
The 7 Building Blocks
Task Blocks (Do Work)
Service
Worker
Storage Blocks (Hold Data)
Key Value Store
Queue
Relational Database
File Store
Vector Database
2 ways to do work + 5 ways to store data = every system
This is the complete framework. Only 7 building blocks — not too few to be useful, not too many to be overwhelming. Just right. The 2:5 ratio reflects reality: there are really only two ways to process work (now or later), but data storage has more variety. Every system you've ever used — Instagram, Netflix, Uber, Gmail — is composed of some combination of these 7 blocks. They already know 5 of them from this class. Let's go through each one.
Service Request/Response Processing
What it does: Handles synchronous requests, returns immediate responses
Mental model: A restaurant server — takes your order, brings back results
Perfect for: API endpoints, user-facing operations, real-time interactions
Not ideal for: Long-running processes, heavy computations
Your 253B experience: Every @app.route you've written in Flask is a Service.
@app.route('/tasks', methods=['POST'])
def create_task(): # This IS a Service
data = request.json # Receive request
task = Task(**data) # Process it
db.session.add(task) # Store result
return task, 201 # Immediate response
They've been writing Services since Week 3. Every Flask route is a Service — it receives a request, processes it, and returns a response. The key rule: Services should be fast. If something takes more than a few seconds, it should move to a Worker. That's exactly what they learned in Week 8 when we introduced background tasks. Ask: "What happens when a Service takes too long?" They know — the user waits, the experience degrades.
Worker Background Processing
What it does: Handles long-running tasks asynchronously
Mental model: Kitchen staff — works behind the scenes on complex dishes
Perfect for: Background jobs, data processing, scheduled tasks
Not ideal for: User-facing requests, immediate responses
Your 253B experience: Every @job function you've written with rq is a Worker.
@job('default', connection=redis)
def send_notification(notification_id): # This IS a Worker
notification = Notification.query.get(notification_id)
# Takes time - that's fine, we're in background
deliver(notification)
notification.status = 'delivered'
db.session.commit()
Workers are the powerhouse. When you upload a video to YouTube, a Service quickly says "got it" and returns. Then Workers spend hours encoding formats, generating thumbnails, processing audio — all in the background. Students experienced this directly: in Week 8 they moved slow notification delivery to a background worker and saw their API become responsive again. The Service + Worker pattern is one of the most fundamental in system design.
The Fundamental Async Pattern
Service handles NOW. Worker handles LATER. Queue connects them.
User sends request
↓
[Service] validates, stores in DB, returns 202 Accepted
↓
[Queue] holds the job message
↓
[Worker] picks up job, processes it
You built this exact pattern in Week 8 (rq tasks) and Week 10 (Notification Hub).
User gets an immediate response (fast UX)
Heavy work happens in the background (scalable)
If a Worker crashes, the Queue retains the job (reliable)
This is THE pattern. Service + Queue + Worker. It appears everywhere: email sending, image processing, order fulfillment, notification delivery. Draw this on the board: Service on the left, Queue in the middle, Worker on the right. Arrows flowing left to right. They built this in Week 8 with Flask + Redis Queue + rq Worker. Same pattern Instagram uses for photo processing. Same pattern YouTube uses for video encoding. Same pattern Uber uses for ride matching. Scale differs, pattern is identical.
5 Storage Building Blocks
Building Block
Optimized For
253B Tech
Key Value Store
Fast lookups, caching
New concept
Queue
Ordered message flow
Redis Queue (rq)
Relational Database
Structured data + relationships
PostgreSQL
File Store
Large files (images, video)
New concept
Vector Database
Similarity search (AI)
New concept
You've used 2 of 5. Let's see all of them.
Quick overview before the deep dives. They know Queue (Redis Queue) and Relational Database (PostgreSQL) hands-on. Key Value Store, File Store, and Vector Database are new concepts but they'll recognize them from apps they use. Each storage block is optimized for a different access pattern — that's why there are 5, not 1. One size does not fit all for data storage.
Key Value Store Fast Dictionary Lookups
What it does: Fast data retrieval using unique keys — O(1) performance
Mental model: Coat check — give a ticket (key), get back your coat (value)
Perfect for: Caching, sessions, counters, configuration
Limitation: No complex queries, no relationships — simple key-based access only
Real-world examples: Redis, Memcached, DynamoDB
User sessions, shopping cart contents, cached API responses, real-time counters
The speed demon of storage. Optimized for incredibly fast lookups. Every time you cache an API response so you don't recompute it, that's a Key Value Store. Every session token stored for quick validation — Key Value Store. The trade-off is simplicity: you can only look up by key. No "find all users older than 25" — that's what a Relational Database is for. But for raw speed on simple lookups, nothing beats it. Redis is the most popular implementation, but DynamoDB, Memcached, and others implement the same pattern.
Queue Ordered Message Processing
What it does: Manages ordered message flow — first in, first out (FIFO)
Mental model: Line at a coffee shop — first in line, first served
Perfect for: Task coordination, background job scheduling, event processing
Limitation: Messages are temporary, not for permanent storage
Your 253B experience: Redis Queue from Week 8.
queue.enqueue(send_notification, notification_id)
The bridge between Services and Workers
Provides reliability — if a Worker crashes, the message stays in the Queue
Enables decoupling — Services and Workers don't need to know about each other
Queues are the traffic controllers of your system. They ensure orderly processing and provide the coordination mechanism between Services and Workers. When a Service receives work that needs background processing, it puts a message in a Queue. Workers pick up messages and process them. This decoupling is powerful: the Service doesn't wait, the Worker doesn't need to be available at that exact moment, and if anything crashes, no work is lost. They experienced this firsthand in Week 8 and the Week 10 Notification Hub.
Relational Database Structured Data with Relationships
What it does: Stores structured data with ACID guarantees and complex relationships
Mental model: Filing cabinet with cross-references — organized, connected, reliable
Perfect for: Business data, financial transactions, user accounts, complex queries
Limitation: Slower than KV Store, requires fixed schema, not great for unstructured data
Your 253B experience: SQLAlchemy + PostgreSQL from Week 7.
Tasks belong to Categories. Users have Orders. Relationships.
class Task(db.Model): # Structured data
category_id = db.Column(
db.Integer,
db.ForeignKey('category.id')) # Relationship!
category = db.relationship('Category', back_populates='tasks')
The workhorse for business data. Every time they place an order online, check their bank account, or update their profile — Relational Database. The special sauce is relationships (Tasks belong to Categories) and ACID guarantees (a financial transaction either completes entirely or not at all). They built this in Week 7 with SQLAlchemy. The trade-off: slower than a Key Value Store, requires upfront schema design. But for structured data with relationships, it's indispensable. PostgreSQL, MySQL, SQLite all implement this same pattern.
File Store Large File Storage
What it does: Stores and retrieves large files with metadata
Mental model: Warehouse — stores big items with tracking info
Perfect for: Images, videos, documents, backups, global content delivery
Not ideal for: Structured data, complex queries, transactions
New building block! You haven't used this in 253B yet.
Real-world tech: AWS S3, Google Cloud Storage, Azure Blob Storage
Every photo on Instagram, every video on YouTube — File Store
Often paired with a Relational DB: file in File Store, metadata in database
This is the first new building block for them. They haven't used it in class, but they interact with File Stores every day. When you upload a photo to Instagram, the actual image bytes go to a File Store (like S3), and the metadata (who uploaded it, when, caption) goes to a Relational Database. This separation is a key pattern: store the big blob in File Store, store the searchable metadata in a database. If they're building anything with user uploads in their group projects, they'll need this. AWS S3 is the most common implementation — incredibly cheap, globally distributed, virtually unlimited storage.
Vector Database Similarity Search
What it does: Finds similar items using AI embeddings and semantic search
Mental model: Smart librarian — finds books similar to what you're looking for
Perfect for: AI applications, recommendations, semantic search, image similarity
Not ideal for: Exact matches, simple lookups, structured business data
New building block! The newest addition — designed for the AI era.
Real-world tech: Pinecone, Weaviate, pgvector, ChromaDB
"Customers who bought X also bought Y" — Vector Database
"Find documents about this topic" (even without exact keyword match)
The newest building block. While other databases find exact matches, Vector Databases find similar items. Search "comfortable running shoes" and it finds results even if the word "comfortable" never appears — because it understands meaning, not just keywords. This powers recommendation systems, AI chatbots with memory, image search, and content discovery. More complex to set up, but becoming essential for modern AI-powered features. If anyone is building AI features in their group project, they'll want to know about this. Brief introduction here — they'll see more in Week 12.
Choosing the Right Building Block
5 questions to systematically select the right block:
Is this about doing work or storing data?
→ Task block vs Storage block (eliminates half your options)
Does it need an immediate response?
→ Service (now) vs Worker (later)
How will the data be accessed?
→ By key? By query? By similarity? By file name?
What are the performance requirements?
→ Speed (KV Store) vs Features (Relational DB) vs Scale (File Store)
What are the data relationships?
→ Simple key-value? Complex with foreign keys? Unstructured files?
This is the decision framework. Walk through it with a concrete example. "We need to store user profiles with name, email, and order history." Question 1: storing data → Storage block. Question 3: accessed by complex queries and relationships → narrows to Relational Database. Question 5: users have orders, orders have items → complex relationships, confirms Relational Database. Now try: "We need to cache the 100 most popular products." Question 1: storing data. Question 3: accessed by product ID. Question 4: needs to be extremely fast. Question 5: no relationships. → Key Value Store. The framework works. Requirements first, technology later.
Common Anti-Patterns
Using a Relational DB for caching
Like using a filing cabinet to temporarily hold your coat — works, but slow and wasteful.
→ Use a Key Value Store instead.
Storing large files in your database
Like trying to fit a couch in a filing cabinet drawer — doesn't fit well.
→ Use a File Store for the file, database for the metadata.
Using a Service for long-running tasks
You experienced this in Week 8! The API blocked while processing.
→ Use Service + Queue + Worker pattern.
Rule of thumb: Match the building block to its strengths, not your familiarity.
These are real mistakes that happen when engineers choose building blocks based on familiarity rather than requirements. The third one is especially relatable — they literally experienced the pain of a blocking Service in Week 8 before they learned about Workers. That "aha" moment when their API became responsive after moving work to background — that's what happens when you use the right building block. When you fight a building block's design, you get poor performance and complicated code. When you match it to its strengths, everything clicks.
Your Complete System — In Building Blocks
Building Block
Technology
Role in Your System
Service
Flask
Receives HTTP requests, validates, responds
Relational DB
PostgreSQL
Stores tasks, categories, relationships
Queue
Redis
Holds background job messages
Worker
rq
Processes jobs in the background
All wrapped in Docker Compose
4 building blocks working together: Service, Worker, Queue, Relational DB
Docker isn't a building block — it's the deployment wrapper
Marshmallow isn't a building block — it's a validation layer on the Service
This same architecture scales from your laptop to millions of users
This is the complete picture of what they've been building. Four building blocks, each doing its job. Docker wraps everything for consistent deployment. Marshmallow is a tool within the Service for validation — not a separate building block. Point out that this architecture is genuinely production-ready. Instagram started with almost exactly this stack. The difference between their Assignment 2 and Instagram isn't architecture — it's scale, polish, and years of iteration. The building blocks are the same.
Key Takeaways
System thinkers think in patterns, not specific technologies
7 building blocks (2 Task + 5 Storage) compose every system
You already know 4 from this semester — Flask, rq, Redis Queue, PostgreSQL
Requirements first, technology second — always
The same patterns scale from your Assignment 2 to Instagram
You've been a system thinker all along.
Now you have the vocabulary and framework to design anything.
Let this land. They came into this class learning individual technologies. Now they see that those technologies are implementations of universal patterns. This is the foundation for Weeks 12-13 where we'll apply these building blocks to real system design case studies. The shift from "I know Flask" to "I know the Service pattern, which Flask implements" is subtle but powerful. It means they can walk into any company, see any tech stack, and understand the architecture — because the building blocks are the same everywhere.
Demo
Assignment 2 as a System Diagram
Transition to the demo. Pull up a whiteboard or drawing tool. You're going to diagram Assignment 2's Task Manager architecture using building block language. This doesn't give away HOW to build it — the system design is already described in the assignment. What it does is show them how to see their own code through the lens of building blocks. This reinforces everything from the lecture.
Assignment 2: Task Manager API
Let's diagram it using building blocks...
[User]
↓ HTTP Request
[Service: Flask API] — validates with Marshmallow
↓ ↓
[Relational DB: PostgreSQL] [Queue: Redis]
Tasks & Categories ↓
[Worker: rq]
Due date reminders
(Live demo — draw this step by step on the board)
LIVE DEMO: Draw this step by step on the whiteboard. Start with User at the top. "When a user sends a POST /tasks request, what's the first building block?" (Service — Flask). "Where does the task data go?" (Relational Database — PostgreSQL). "What happens if the due date is within 24 hours?" (Service enqueues a job to the Queue — Redis). "Who processes that job?" (Worker — rq). Draw each block, label it with both the building block name AND the technology. Show the flow arrows. This is exactly 4 building blocks: Service, Relational DB, Queue, Worker. All running inside Docker Compose. Point out: "This is the same architecture diagram you'd draw at a system design interview — just at smaller scale."
In-Class Exploration
Design a URL Shortener
Now they apply what they've learned. This is a classic system design problem. They'll work in small groups to identify building blocks and draw a system diagram. Give them the 5 requirements and the Google Drawings template. Walk around and help groups that are stuck.
Your Task: Design a URL Shortener
Scenario: Your startup needs a link shortener service (like bit.ly). Design the system using building blocks.
The 5 Requirements
Generate unique short URLs that redirect to long URLs
Handle large amounts of load (what if a link goes viral?)
Handle concurrent requests without compromising performance or data consistency
Track and log click counts and basic usage metrics per short URL
Handle invalid or expired URLs with appropriate error responses
Read through the requirements one by one. For each one, ask the class: "Which building block do you think handles this?" Don't answer yet — let them discuss. Requirement 1 is straightforward (Service + Database). Requirement 2 is where caching (KV Store) becomes important. Requirement 4 brings in analytics (Worker + Queue for background tracking). Give them time to think before moving to the instructions slide.
Exploration Steps
Copy the template (link on bCourses / posted in chat)
Identify building blocks — which of the 7 does each requirement need?
Draw the system diagram — place building blocks and show data flow
Label everything — building block type + what it stores/processes
Bonus: Map technologies — which specific tech would you use for each block?
Time: ~40 minutes | Format: Small groups (2-3)
Post the template link in the chat. Make sure everyone can access it and make a copy. Walk around as groups work. Common hints if groups get stuck: "What happens when someone clicks a short URL? What needs to be fast?" (Service + KV Store for cached redirects). "How do you track clicks without slowing down the redirect?" (Queue + Worker for async analytics). "Where do the URL mappings live permanently?" (Relational Database). After 30-35 minutes, bring the class back together and have 2-3 groups share their designs.
Hints: Building Block Selection
Requirement
Think About...
Generate & redirect URLs
What receives the request? Where are mappings stored?
Handle viral load
How do you make redirects fast? What if the DB is too slow?
Concurrent requests
Which storage block guarantees consistency?
Track click metrics
Should tracking block the redirect? What pattern avoids that?
Handle invalid/expired URLs
Where do you check validity? What does the Service return?
Show this slide after ~15 minutes if groups need a nudge.
Don't show this slide immediately — let groups struggle productively first. After about 15 minutes, if you see groups stuck, show these hints. They're designed to guide thinking without giving away the answer. The key insight most groups will discover: you need a Key Value Store (cache) in front of your Relational Database for fast redirects, and you need the async pattern (Queue + Worker) for click tracking so it doesn't slow down the redirect. These are the same patterns they learned today.
What's Next
Week 12: Technology Mapping — deeper into design patterns and real-world case studies
Assignment 2: Due Friday, April 10th — you now see it's 4 building blocks!
Quick wrap. Assignment 2 should feel more approachable now that they can see it as 4 building blocks. Next week we go deeper into technology mapping — how to evaluate which specific technology best implements each building block for your use case.