M0
Course Logistics and Policies 5 figures
course-logistics Four eras of data systems, compared on the same four questions
Four eras of data systems, compared on the same four questions
A four-column grid. The columns are Banks and retail in the 1970s to 1980s, the web from 1995 to 2010, the cloud era from 2004 onwards, and AI agents from 2025 onwards, the last one filled blue as the era the course is built for. Four rows compare them: the products of each era, who is on the other end of the query, the hard question each era had to answer, and what the industry invested in during it. The middle row escalates from hundreds of clerks, to millions reading, to billions writing at human pace, to machines at machine pace. The investments row runs from transactions and the relational model, through replicas and NoSQL and MapReduce, to LSM trees and object storage and columnar scans, to vector indexes and KV caches and lineage and Iceberg, the table format that lets any engine read the same storage.
PRODUCTS
WHO IS ON
THE OTHER END
THE HARD
QUESTION
INVESTMENTS
Banks and retail
1970s TO 1980s
Ledgers, inventory,
airline seats
Hundreds of clerks
Is it correct?
Transactions, ACID,
the relational model,
locking, write-ahead logs
The web
1995 TO 2010
Google, Amazon
Millions reading
Can everyone read it
at once?
Replicas, caches, NoSQL,
inverted indexes,
the cluster, MapReduce
The cloud
2004 ONWARDS
Gmail, YouTube,
Instagram
Billions writing,
at human pace
Can everyone write
and store forever?
LSM trees, sharding,
consistent hashing,
object storage, quorums,
columnar scans
AI agents
2025 ONWARDS
Copilots, agents,
assistants
Machines,
at machine pace
Machines read and
write nonstop. Is all
of it correct, and
what did it cost?
Vector indexes, KV caches,
eval sets, lineage,
Iceberg, lakehouses
Each era stacks on the one before it. This course is built for the column on the right.
Each era shifted the party issuing the query. CS145 targets the agent era.
Notes ↗
course-logistics · Before You Start What you need on day one, and what helps a lot
What you need on day one, and what helps a lot
Three panels. The first, with an ink top strip marking it as required, is Python and Colab: read Python and run a notebook, needed from day one. The next two, with grey strips marking them as helpful rather than required, are CS 161 Algorithms, giving sort and hash and complexity, and CS 111 Systems, giving filesystems and the memory hierarchy and scheduling. A closing line says CS145 runs those same concepts on data 100 to 1,000,000 times bigger, and points at the ten-question concept check that opens PSET 0.
WHAT YOU NEED
REQUIRED
Python and Colab
Read Python, run a notebook,
open a Colab and execute a cell.
df.head() → [10 rows]
HELPS A LOT
CS 161 · Algorithms
Sort, hash, complexity.
How an operation scales when
the input grows.
Modules 2 and 3 lean on it.
HELPS A LOT
CS 111 · Systems
Filesystems, the memory
hierarchy, scheduling.
Where the bytes actually live.
Module 2 leans on it.
CS145 takes those same concepts and runs them on data 100x to 1,000,000x bigger.
PSET 0 opens with ten questions on exactly these concepts. Start there, and scan ahead when one finds a gap.
The course leans on the concepts from CS161 and CS111 more than the coursework. Use PSET 0 to check where you stand.
Notes ↗
course-logistics · How It Works One week in CS145, and the eleven weeks it repeats across
One week in CS145, and the eleven weeks it repeats across
Two blocks in one picture. The top block is one week in three lanes, read top to bottom in the order you do them. LECTURES holds the two lectures, Tuesday and Thursday. PRACTICE holds one section band spanning Wednesday to Friday, marked one of three, running the Colab walkthrough. READING, tagged own time, holds the same page used in lecture with its three to five minute video, and the week's industry case study. A dotted rail down the left carries each lane into the next and continues into the second block. Between them, a line says section and the reading are the rehearsal and the PSET is the same material on your own, graded. The bottom block is the quarter: eleven week columns with the module each covers, M1 SQL through M5 Distributed, a Thanksgiving gap at week ten and industry lessons at week eleven, then two rows of real deadlines. Six PSETs: M0 Sep 25, M1 Oct 5, M2 Oct 12, M3 Oct 19, M4 Nov 9, M5 Dec 4, each landing the week after its module ends. Three project milestones: Project 1 Oct 16, the Project 2 proposal Oct 30, and Project 2 Nov 20.
ONE WEEK
TUE
WED
THU
FRI
1 LECTURES
2 PRACTICE
3 READING
OWN TIME
Lecture
new material, live
Lecture
new material, live
Section · pick any one
Colab walkthrough, hands on keyboard
1 OF 3
The lecture page, in Notes
plus a 3 to 5 minute video
The week's reading list
required pages, plus a case study
Section and the reading are your prep for the PSET. It is the same material, on your own, graded.
ELEVEN WEEKS
The module underneath changes. The rhythm stays the same.
W1 W2 W3
W4 W5 W6
W7 W8 W9
W10 W11
M1
M1
M2 · M3
M3
M4
M4
M4
M5
M5
break
Industry
PSETS
PSET M0 Sep 25
PSET M1 Oct 5
PSET M2 Oct 12
PSET M3 Oct 19
PSET M4 Nov 9
PSET M5 Dec 4
PROJECTS
Project 1 Oct 16
P2 proposal Oct 30
Project 2 Nov 20
Lectures are Tuesday and Thursday. Practice is section: the same Colab walkthrough runs Wednesday, Thursday and Friday across three slots, and you attend one. Reading is the lecture page in Notes with its three to five minute video, plus the week's reading list: the required pages and a case study, in ten of the eleven weeks.
Notes ↗
course-logistics · How Grading Works One hundred points: fifty fixed, and fifty you can earn two different ways
One hundred points: fifty fixed, and fifty you can earn two different ways
A hundred-point scale. The first fifty points are fixed for everyone: Project 1 worth ten, PSets worth fifteen, Project 2 worth twenty-five. From the fifty-point mark the bar splits into two alternatives for the remaining fifty. Path 1 accrues fifteen points from nano quizzes and puts thirty-five on the final. Path 2 is a final worth fifty. A brace on the right marks that you are given whichever of the two scores higher, automatically.
YOUR GRADE, OUT OF 100
0
50
100
FIXED FOR EVERYONE
Project 1
10
PSets
15
Project 2
25
PATH 1 · ACCRUE POINTS FROM NANO QUIZZES
Nano quizzes
15
Final
35
Final
50
PATH 2 · BET ON THE FINAL
You get
the higher
score.
Everyone earns 50 fixed points: Project 1 for 10, PSets for 15, Project 2 for 25. The remaining 50 points come from either Path 1 or Path 2, and the course uses the higher score. Path 1 accrues 15 points from nano quizzes across the term and puts 35 on the final. Path 2 assigns all 50 to the final. Nano quizzes run live on Poll Everywhere, one in every lecture and one in every section.
Notes ↗
course-logistics · AI Policy: Learn Like You'll Work Where AI is allowed in CS145, and what is graded in each place
Where AI is allowed in CS145, and what is graded in each place
Two panels. On the left, the projects: every AI tool is allowed, credited, and the grade is on four things you do after the model answers, namely verify the answer, fix the semantics, cut the cost, and defend the design. On the right, the paper test: no AI, standing in for a whiteboard interview and measuring the systems thinking you carry yourself.
SHIP WITH A I, OWN THE RESULT
On the projects
Use any tool you like. Credit it.
GPT, Claude, Gemini, whatever you prefer. The model
writing the first draft is assumed, so the grade is on
what you do after it answers:
Verify the answer is correct
Fix the semantics
Cut the cost
Defend the design
On the paper test
No A I.
This is the stand-in for the whiteboard job
interview, so it measures the part that is now
scarce: systems thinking you carry yourself.
Query semantics, what the SQL does
Performance debugging, why queries are slow
Index strategy, when it helps or hurts
Join algorithms, which one fits your data
Tradeoffs: memory vs disk, latency vs throughput
The model drafting your first query is assumed. What gets graded is the four things you do after it answers, and the paper test checks that you can do them without it.
Notes ↗
M0 Why Memory Matters CS145 is about how data persists over time.
2 figures
why-memory-matters · What this course teaches Five you learn, then the modern systems you build
Five you learn, then the modern systems you build
Top row: the five capability modules you learn, left to right, one machine to many. M1 SQL (blue): a query in, rows out; runs Postgres and BigQuery. M2 Storage (orange): a columnar cylinder over a disk; runs Chrome and Uber. M3 Indexing (emerald): a B+Tree on the cylinder, one billion rows to milliseconds; runs Spotify and OpenAI. M4 Transactions (violet): a lock on the cylinder, two users converging; runs Stripe and GitHub. M5 Distributed (pink): three shard cylinders with replication arrows; runs Netflix and Kafka. A green arrow leads down to the payoff: learn these five, build any new system, correct and scalable. Below, the destination panel, M6 Modern systems (slate): a database inside a phone, an AI agent, and a server stack, the systems running now, and your next app, agent, or system. Color key: each module is colored for consistency; the cylinder is the same throughout because the primitive does not change, only what surrounds it.
Every system is the same few ideas. You can build new ones.
The five you learn, then the modern systems you build with them.
ONE MACHINE → MANY MACHINES
M1 · SQL
SELECT genre, COUNT(*)
FROM listens GROUP BY ...
Declarative
Postgres · BigQuery
M2 · Storage
disk pages
On disk
Chrome · Uber
M3 · Indexing
1B rows → ms
Spotify · OpenAI
M4 · Transactions
all-or-nothing
Stripe · GitHub
M5 · Distributed
shard 1 · shard 2 · shard 3
Many machines
Netflix · Kafka
Learn these five. Build any new system: correct and scalable .
phone
agent
server
M6 · Modern systems : the ones running now
Build your next { app, agent, system }
Each module adds one capability, and each one supports the next scale.
Notes ↗
why-memory-matters · Where we start: three teardowns Three teardowns, one primitive
Three teardowns, one primitive
Three blue cards left to right: 0.1 small analytics, Pandas and Polars on a laptop, fast until it runs out of about sixteen gigabytes of RAM, the on-ramp; 0.2 agent memory, no memory then local then global, from one user to eight hundred million, the whole course in one example; and 0.3 a big service, UberEats with one database, three sides and the offline edge, billions of orders planet-wide. A grey scale axis underneath runs from one machine to many machines. A colour key notes that blue marks a teardown, the same database at growing scale.
Three teardowns, one primitive
The same SQL database, three settings. This course is the bridge.
0.1 · Small analytics
Pandas and Polars on a laptop.
Fast, until it runs out of RAM.
~16 GB on a laptop
the on-ramp
0.2 · Agent memory
No memory, then local,
then global.
1 user → 800 M users
the whole course in one example
0.3 · A big service
UberEats: one database,
three sides, plus the edge.
billions of orders, planet-wide
planet scale and the edge
one machine
many machines
Color key blue = a teardown, the same database at growing scale
Three environments run the same database, from one machine to many. Modules 1 through 6 build it.
Notes ↗
M0 Pandas: Deconstructing Small Analytics Pandas and Polars load your whole dataset into your machine's memory and work on it there.
3 figures
case-study-pandas What a DataFrame actually is
What a DataFrame actually is
On the left, one file sits on disk, listens.csv, written row after row. An arrow labelled read into memory carries it to the right, where it becomes a DataFrame: a table with named, typed columns user_id, song_id and rating, and rows of values. Below, the same DataFrame is shown the way it is really held, split into one contiguous typed array per column. A closing line notes that every column of every row is in memory at once, which is why it is fast on small data and why it fails on big data.
What a DataFrame actually is
One file, read into memory, then held one column at a time.
ON DISK
listens.csv
a CSV, or a Parquet file
read
IN MEMORY · A DataFrame
user_id
song_id
rating
int64
int64
int64
1
12
5
1
45
4
Held column by column
Each column is one
contiguous typed array,
which is why summing one
column is fast.
user_id
1
1
song_id
12
45
rating
5
4
Every column of every row is in memory at once. That is why it is fast on small data, and why it fails on big data.
A CSV on disk or a Parquet file reads into a DataFrame with named, typed columns. The system stores each column as one contiguous array of a single type, which makes column aggregation fast. The DataFrame keeps every column of every row in memory at once, so it runs fast on small data and fails when the data exceeds memory.
Notes ↗
case-study-pandas · A familiar example Pandas: the whole dataset has to fit in RAM
Pandas: the whole dataset has to fit in RAM
A blue-stripped box is the single machine, RAM about 16 gigabytes, holding a DataFrame that is grouped, sorted, and joined entirely in memory; grey shows the de-emphasized CSV or Parquet on disk that is read in. On the right, the red-stripped box is the failure state: when data exceeds RAM the program crashes or thrashes. A visible color key runs along the bottom. Color key: blue is the one machine in focus, red is the out-of-RAM failure, grey is out of focus.
Pandas: the whole dataset has to fit in RAM
One process, one machine. Everything lives in memory, until it does not fit.
CSV / Parquet
on disk
read
ONE MACHINE · RAM ≈ 16 GB
DataFrame
every row, one process,
in memory
group / sort / join
all in RAM
result
handed back fast
RAM
limit
data > RAM:
crash or thrash
Color key blue = the one machine in focus · red = out of RAM, the failure · grey = out of focus
Group, sort, and join all execute in memory in one process, which is fast while the dataset fits. Past that, the process does not slow down. It crashes, because nothing runs the same computation from disk.
Notes ↗
case-study-pandas · Pandas, Polars, and a database How far each engine gets on a data-size axis, and where one machine ends
How far each engine gets on a data-size axis, and where one machine ends
A horizontal data-size axis running from one gigabyte to one petabyte, each tick ten times the last. Landmarks along it: the small Spotify we built at a few gigabytes, a laptop's RAM at about sixteen gigabytes, one big server's RAM at hundreds of gigabytes, one big server's disk at tens of terabytes, and the real Spotify out past the end. A dashed boundary near the right divides the region where one machine is enough, tinted blue, from the region that needs many machines, tinted green. Four bars show how far each engine reaches. Pandas, writing DataFrame code, ends at a hard red wall while the data is still smaller than the laptop's RAM, because it copies at every step. Polars, also DataFrame code, runs solid to about one terabyte and fades out through tens of terabytes. A distributed database, also SQL, runs the whole axis and continues past it. Underneath, the tradeoff: one machine runs on hardware you already own, many machines needs a cluster you rent.
Same query. The data keeps growing.
How far each one gets before it needs another machine. Each tick is ten times more data.
One machine is enough
Needs many machines
small Spotify
laptop RAM
one server's RAM
one server's disk
the real Spotify
1 GB
10 GB
100 GB
1 TB
10 TB
100 TB
1 PB
Pandas
DataFrame code
out of RAM
Polars
DataFrame code
Distributed database
SQL
Hardware you already own
A cluster you rent
Each tick is ten times the last. Pandas copies the data at each step and holds every row in memory, so it hits a wall while the file is still several times smaller than the laptop's RAM. Polars keeps almost the same API but builds a lazy plan and streams from disk on every core, so it fades instead of crashing rather than stopping at a fixed size. Where exactly it gives out depends on the query, which is why its bar is not drawn with an end. Only the distributed database crosses the line, running the query where the data lives. Everything left of that line runs on hardware you already own; everything right of it is a cluster you rent.
Notes ↗
M0 Claude & OpenAI: Deconstructing Agent Memory An AI coding agent with no memory hallucinates.
6 figures
case-study-agent-memory Real facts: store and retrieve, local then global
Real facts: store and retrieve, local then global
Three panels left to right. Panel one, red: a grey de-emphasized model circle with only a context window; it hallucinates. Panel two, green: the same model plus a local database, SQLite running claude-mem, a file on disk on one machine, queried with SQL; it looks the answer up. Panel three, green: the same model plus the same database scaled out, ChatGPT's user data, Postgres on disk with read replicas, also queried with SQL, one private memory per user across 800 million users. The model talks to each database using SQL. Models keep upgrading and databases keep scaling; the database is the core infrastructure that holds their memory and context, and that is what is in focus. Color key: red is no memory and the ephemeral context window, grey is the model which is a separate topic out of focus, green is persistent memory.
Real facts: store and retrieve, local then global
Models keep upgrading and databases keep scaling. The database holds their memory and context.
1 · Model alone
Model
context
window
Short-term working memory.
Wiped when the session ends.
✗ Hallucinates a function
2 · + Local memory
Model
SQL
SQLite · claude-mem
On disk, one machine.
Survives every session.
✓ Looks it up · per laptop
3 · + Global memory
Model
SQL
Postgres
ChatGPT's user database.
On disk, many machines · × 800M
✓ One per user · ×800M
RAM forgets · disk remembers · one machine, then many
Color key red = no memory, the ephemeral context window · grey = the model, a separate topic, out of focus · green = persistent memory
Two steps: add a database so the model (grey) can store and retrieve real facts instead of inventing them, then scale that database across machines for one memory per user across millions of users. Local memory maps to Modules 1 to 4. Global memory maps to Modules 5 and 6.
Notes ↗
case-study-agent-memory · No memory, and the hallucination A plausible answer is still wrong
A plausible answer is still wrong
On Tuesday you ask the agent to extend the auth module you built with it on Monday. On the left, with no memory to consult, the agent predicts and calls a function named verifyJWTWithScope, a name that sounds exactly right. On the right, your codebase contains no such function; it never existed, and nothing errored until the code ran. A closing line notes that the agent looked nothing up, it predicted, and a plausible wrong answer is the hardest kind to catch.
A plausible answer is still wrong
With nothing to look up, the agent predicts.
Tuesday: "extend the auth module we built on Monday."
THE AGENT GUESSES
Monday is gone, so it predicts a name.
verifyJWTWithScope()
A name that sounds exactly right.
IN YOUR CODEBASE
Every function you actually wrote:
no such function
It never existed anywhere.
It looked nothing up. It predicted.
A confident wrong answer is the hardest kind to catch, and the fix is having somewhere to look.
Monday produced a working module. Tuesday starts without the Monday context. The agent generates verifyJWTWithScope() from patterns in its training distribution, and the name reads like real code. A persistent place to store Monday's decisions gives Tuesday something to query.
Notes ↗
case-study-agent-memory · The context window is the agent's working-memory limit The context window is working memory
The context window is working memory
Three sessions run left to right. In session one the context window fills with messages until it is full, and the oldest message falls out of the top, greyed and struck through, because the window holds only so much. Sessions two and three start completely empty, because nothing carries over when a session ends. Underneath all three sessions runs one continuous database bar, still holding everything. The closing line notes that working memory is bounded and temporary, while durable memory is a database.
The context window is working memory
Bounded, and gone when the session ends.
CONTEXT
working memory
SESSION 1
Full. It holds 200K to 1M tokens.
A real project runs to tens of millions.
SESSION 2
empty
SESSION 3
empty
Every new session starts with nothing.
Monday's decisions are gone by Tuesday.
DATABASE
durable
One database, underneath all three sessions, still holding everything.
Working memory is bounded and temporary. Durable memory is a database.
The context window has two limits. It stays bounded at roughly 200,000 to 1,000,000 tokens, while the project state can reach tens of millions, so older content falls out. It stays temporary because each session opens empty. A database persists across both limits.
Notes ↗
case-study-agent-memory · Local memory: a database on your machine Local memory: write and read are just SQL
Local memory: write and read are just SQL
A grey, de-emphasized model on the left (an LLM plus context extraction, for example pulling function signatures from code, a separate topic that is out of focus) talks to one green embedded database on your machine using SQL. A top arrow is SQL write, the model into the database. A bottom arrow is SQL read, the database back out through a small rerank box and into the model, a closed loop. The green database, claude-mem, is the focus: it holds two cylinders, SQLite with FTS5 for keyword and structured lookup, what you said, and a sqlite-vec vector index for semantic lookup, what you meant. Color key: grey is the model and your machine, a separate topic out of focus; green is the persistent embedded database, what we care about.
Local memory: write and read are just SQL
claude-mem on your machine: SQLite for what you said, vectors for what you meant.
Model
LLM + context
extraction
e.g. code → signatures
SQL write
SQL read
rerank
YOUR MACHINE
One embedded database · claude-mem
SQLite · FTS5
keyword · what you said
Vector · sqlite-vec
semantic · what you meant
Color key grey = the model and your machine, out of focus · green = the persistent database
Local memory uses one embedded database file. The model writes observations with SQL. Retrieval reads rows back through a rerank step. SQLite stores a keyword index with FTS5 and a vector index with sqlite-vec. The deployment uses one file and no server.
Notes ↗
case-study-agent-memory · Global memory: the same need, at scale Global memory: one Postgres primary, many read replicas, 800 million users
Global memory: one Postgres primary, many read replicas, 800 million users
On the left, two grey de-emphasized boxes that are a separate topic out of focus: 800 million ChatGPT users, and the GPT-5 model, OpenAI's LLM. They send SQL writes to one green Postgres primary inside a green shared-database region; the primary streams replication to about fifty read replicas that serve the SQL reads. Same SQL write and SQL read pattern as the local database, one machine versus many. Color key: grey is the users and the GPT-5 model, a separate topic out of focus; green is the shared Postgres database, what we care about.
Global memory: one logical database, many machines
One primary takes every write; ~50 replicas fan the reads out to 800 million users.
ChatGPT users
× 800M
writes and reads
GPT-5 model
OpenAI's LLM
a separate topic
Shared database · Postgres / SQL
Primary
takes all writes
~50 read replicas
serve all reads
replicate
SQL write
SQL read · fanned out from ~50 replicas
Color key grey = the users and the GPT-5 model, out of focus · green = the shared Postgres database
Global memory keeps the SQL interface (grey) and changes only the deployment (green). One Postgres primary accepts every write. It streams replication to about fifty read replicas, which serve 800 million users.
Notes ↗
case-study-agent-memory · Going deeper Three ways to rank the same rows
Three ways to rank the same rows
Three cards side by side, each a different ranking signal over the same observations table. The first is BM25, keyword matching, which catches the words you actually typed: a search for auth returns rows containing auth. The second is vector similarity, which embeds the question and finds rows pointing the same way, so a search for login also finds auth. The third is PageRank over the code graph, an importance signal: a file that forty others import outranks one that nothing points at. A closing line notes all three are just an ORDER BY, so mixing them is a one-line query edit.
Three ways to rank the same rows
Each one catches something the other two miss.
1 · WHAT YOU SAID
BM25
Keyword match on the text,
the words you actually typed.
search "auth"
rows containing auth
2 · WHAT YOU MEANT
vector similarity
Embeds the question, finds
rows pointing the same way.
search "login"
also finds auth
3 · WHAT MATTERS NOW
PageRank
An importance signal over
your code: what points at it.
auth.ts
40 files import it: ranks high
All three are just an ORDER BY over the same table.
Mixing them is a one-line query edit, which is the point of keeping memory in SQL.
One set of rows produces three orderings. BM25 ranks by term matches. Vector similarity ranks by embedding distance, so "login" can match "auth." PageRank ranks by importance in a code graph, so a file with forty importers outranks a file with none. Each strategy produces an ORDER BY, so a query can mix signals by editing the ordering expression.
Notes ↗
M0 UberEats: Deconstructing a Big Service UberEats keeps diners, drivers, and restaurants in a single relational database so each order updates all three records atomically, while the same SQL engine, embedded, runs offline on the driver's phone.
3 figures
case-study-ubereats UberEats: one database, three sides
UberEats: one database, three sides
Three red-stripped client apps, Diner, Driver, and Restaurant, each hold volatile in-memory state and all feed one green-stripped relational database, the persistent shared truth, where placing an order charges the diner, assigns one driver, and decrements inventory atomically. A box with an ink bottom strip and an ink target mark is the takeaway: two drivers can never claim the same order. Color key: red is volatile or ephemeral client state, green is the persistent shared database, ink is the takeaway.
UberEats: one database, three sides
A burrito order has three sides. They all have to agree the moment it is placed.
Diner app
volatile in-memory state
Driver app
volatile in-memory state
Restaurant
volatile in-memory state
Relational database · the persistent shared truth
TRANSACTION: place order → charge diner, assign one driver,
decrement inventory. All of it, or none of it.
⊙
Two drivers can never claim the same order
Color key red = volatile client state · green = the persistent shared database · ink bottom strip = the takeaway
Three apps write volatile client state. One relational database stores shared state. One order runs as one atomic transaction that charges the diner, assigns one driver, and decrements inventory.
Notes ↗
case-study-ubereats · One order, three sides One order. Three records. All or none.
One order. Three records. All or none.
Placing one order sits at the top. Below it, three records change inside a single transaction: the diner's balance is charged, exactly one driver is assigned, and the restaurant's inventory is decremented. Two outcomes follow. On commit, all three apply together. On abort, none of them do, and the greyed struck-through records show that nothing partial is left behind. A closing line notes that the database holds this guarantee even if the server dies mid-write, with no coordination code of your own.
One order. Three records. All or none.
Atomicity, the A in ACID.
One diner places one order
ONE TRANSACTION
DINER
balance charged
DRIVER
exactly one assigned
RESTAURANT
inventory decremented
COMMIT
All three apply together.
ANY ONE FAILS
None of them do.
The database holds that even if the server dies mid-write. You write no coordination code.
Atomicity in ACID. One transaction updates three records so the system never stores a charged diner with no order, and never stores one order with two drivers. The database commits or aborts even if the server dies between writes, so the application does not implement its own coordination protocol.
Notes ↗
case-study-ubereats · The disconnected edge The disconnected edge: a database on the phone
The disconnected edge: a database on the phone
A blue-outlined phone, the system in focus, runs the driver app over an embedded SQLite database and stays transactional with no signal. On reconnect, a green arrow pushes local changes to a green cloud database, the shared source of truth, and a grey arrow reconciles back. Color key: blue is the phone in focus, green is the cloud source of truth.
The disconnected edge: a database on the phone
Same SQL, offline. The driver app does not stall waiting for the network.
DRIVER'S PHONE · offline
Driver app
SQLite, embedded
transactional even if the phone dies
on reconnect: push local changes
reconcile against the truth
Cloud database
the shared source of truth
Color key blue = the phone, the system in focus · green = the cloud source of truth
The driver app stores state in an embedded SQLite database and executes transactions offline. The app syncs local changes to the cloud database on reconnect and reconciles cloud state back to the device.
Notes ↗
projects The project path: Project 1, then one of two Project 2 options
The project path: Project 1, then one of two Project 2 options
Everyone does Project 1 (BigQuery's First Heist, solo, Sep 25 to Oct 16, 16 to 20 hours, blue) and builds decision-worthy SQL and scalable cloud analytics, then picks one Project 2 (Oct 16 to Nov 20, pairs by default with solo optional, about 40 hours per person for a Tier 93 project (about 8 hours a week over five weeks), with the Tier 100 capstone adding about 8 more): Science (BigQuery Part Deux, violet, Spark ELT, vector embeddings, and a BigQuery ML model, a warehouse plus model to headline a portfolio) or Systems (NanoMem, green, a search engine giving AI coding agents persistent memory that races real production tools). Each card lists focus, skills you build, and the portfolio story. Blue is the SQL foundation, violet is data science, green is systems.
PROJECT 1 · SOLO
Sep 25 – Oct 16
BigQuery's First Heist
FOCUS
Write decision-worthy SQL on a
500 MB+ public dataset.
SKILLS YOU BUILD
CTEs, subqueries, window functions,
debug tables, cloud analytics
PORTFOLIO
3 decision-worthy SQL answers on real
cloud-scale data.
16–20 hrs
THEN PICK ONE
P2 · SCIENCE
Oct 16 – Nov 20
BigQuery Part Deux
FOCUS
Enrich with new data, visualize, and
train a BigQuery ML model.
SKILLS YOU BUILD
Spark ELT, vector embeddings,
BigQuery ML, query-plan analysis
PORTFOLIO
A warehouse + ML model to headline
your portfolio.
≈40 hrs/person (Tier 93)
or solo
OR
P2 · SYSTEMS
Oct 16 – Nov 20
NanoMem
FOCUS
Build a search engine that gives AI
coding agents persistent memory.
SKILLS YOU BUILD
Inverted index + BM25, LSH vectors,
hybrid retrieval, query planner
PORTFOLIO
A memory engine that races real
production tools.
≈40 hrs/person (Tier 93)
or solo
Notes ↗
projects · What you'll build Project 1 architecture: query a public dataset with SQL to answer questions
Project 1 architecture: query a public dataset with SQL to answer questions
Left to right: a read-only public dataset in BigQuery (three or more tables such as posts, users, and comments, at least 500 MB, grey) is queried by the SQL you write in a Colab notebook (a code card shows a CTE with a RANK window function and a join). It produces a result table of decision-worthy answers, one row starred as the insight. Below, you hand-trace two paper debug tables to verify how the SQL executes. Blue is what you build; grey is the read-only data you query.
The big picture: turn a 500 MB dataset into a decision
A read-only public dataset, real SQL, one insight worth acting on.
THE DATA
read-only, in BigQuery
posts id · user_id · score
41 · u12 · 88 42 · u07 · 15
users id · name · country
u12 · Ada · US u07 · Lin · SG
comments id · post_id · body
91 · 41 · "nice"
3+ tables · ≥ 500 MB
StackOverflow, NYC Taxi, GitHub…
query
YOUR SQL
10+ queries, written in a Colab notebook
top_posters.sql
WITH ranked AS (
SELECT user_id, COUNT (*) AS posts,
RANK () OVER ( ORDER BY COUNT (*) DESC ) rk
FROM posts GROUP BY user_id )
SELECT u.name, r.posts, r.rk
FROM ranked r JOIN users u USING ( user_id )
WHERE r.rk <= 10 ;
3 JOINs
2 CTEs
2 correlated subqueries
3 window fns
answer
THE PAYOFF
"Who are our power users?"
name posts rk
Ada 4,210 1
★
Lin 3,880 2
Ravi 3,102 3
★ Insert your insight:
why are they ranked #1? (+5)
3+ decision-worthy answers,
stated in English, backed by SQL
VERIFY ON PAPER
posts rk tie?
4210 1 no
Hand-trace how RANK breaks ties,
and a correlated subquery, row by row.
2 debug tables
blue = what you build · grey = the read-only data you query
Notes ↗
projects · What you'll build Project 2 Science architecture: a production data and ML pipeline
Project 2 Science architecture: a production data and ML pipeline
Left to right: two data sources, Wikipedia (about 22 GB, new in Project 2, violet) and your Project 1 warehouse (grey). A Spark ELT job funnels the 22 GB down to a filtered 1 GB slice; a partitioned, clustered BigQuery warehouse stores it; vector embeddings turn text into vectors so a nearest-neighbor scatter finds meaning; and a BigQuery ML model separates two classes with a decision boundary and makes a calibrated prediction (0.87) tied to a decision. Violet marks what is new in Project 2 (Project 1 was just SQL): Wikipedia, Spark ELT, embeddings, and the ML model. Grey is the Project 1 data you start from. Below the pipeline, a gold crown box marks the Tier 100 capstone: the Analyst's Agent, a governed text-to-SQL agent built on this stack, taking a bare model from 21% to about 95% accurate.
The big picture: the data + ML stack a team ships before lunch
Ingest outside data, embed it, model it, ship a calibrated decision.
WIKIPEDIA
NEW
~22 GB 6.7M articles
YOUR P1 WAREHOUSE
≥ 500 MB
SPARK ELT
NEW
22 GB in
filter
1 GB slice
Filter to your domain,
load it into BigQuery.
PySpark on Colab
WAREHOUSE
partition by date
Partitioned + clustered
so scans stay cheap.
fact + wiki layers
EMBEDDINGS
NEW
"token refresh"
→
[.12 -.4 .9]
near in space = near in meaning
Find neighbors keyword joins miss.
ML.GENERATE_EMBEDDING
BIGQUERY ML
NEW
0.87
stay act
a boundary + a calibrated probability
Predict something compelling
you’ll tell your team.
CREATE MODEL
violet = new in Project 2 (Project 1 was just SQL) · grey = the data you start from
TIER 100 · THE CROWN
The Analyst's Agent · a governed text-to-SQL agent
Notes ↗
projects · What you'll build Project 2 Systems architecture: a hybrid search engine for AI-agent memory
Project 2 Systems architecture: a hybrid search engine for AI-agent memory
Two data sources (about 2 million code functions from CodeSearchNet and about 8.8 million web passages from MS MARCO, grey) are indexed two ways you build from scratch (green): an inverted index with BM25 shows posting lists mapping each term to documents (keyword search, "what you said"); LSH hashes vectors into buckets so similar vectors share a bucket (semantic search, "what you meant"). A hybrid layer fuses the two ranked lists with RRF and your own fusion, a query planner picks the plan, and the result is memory an AI coding agent queries in a terminal before it answers. A benchmark scoreboard races your engine for parity against SQLite FTS5 (BM25) and sqlite-vec (vectors). Green is what you build; grey is the data you index. A gold crown box marks the Tier 100 capstone: web-scale memory, streaming retrieval over 22 GB of Wikipedia in a 1 GB working set, still keeping pace with the tools in a billion phones.
The big picture: a search engine that gives an AI agent memory
Two data sources, two kinds of search, fused, then raced against production tools.
CODESEARCHNET
~2M functions 6 languages
MS MARCO
~8.8M passages web + Bing labels
INVERTED INDEX + BM25
keyword search · "what you said"
"cache" →
d3:2
d7:1
d9:3
"index" →
d1:1
d3:4
term → posting list (doc:tf), scored by BM25
LSH VECTORS
semantic search · "what you meant"
query
b0
b1
b2
similar vectors share a bucket
HYBRID RETRIEVAL
BM25
d7
d3
d9
LSH
d3
d5
d7
FUSED
d3
d7
d5
→
RRF + your own fusion.
a query planner picks the plan
AI CODING AGENT
$ recall("session" )
→ token = lifetime
Look it up before you
make it up.
THE BAR
race the production tools for parity, same data, same eval
metric
your engine
reference tool
parity
R@5 keyword 0.71 FTS5 0.72 ✓
R@5 vector 0.68 sqlite-vec 0.69 ✓
+ R@1, MRR, p95 latency, peak memory
green = what you build · grey = the data you index
TIER 100 · THE CROWN
Web-scale memory · 22 GB Wikipedia, 1 GB working set
Notes ↗
M0
CS145: Your SQL Journey 3 figures
sql-metro CS145 career journey map
CS145 career journey map
A left-to-right map. The two blue boxes are CS145 itself, the content in focus: the core curriculum with Project 1, then a Project 2 choice of the Science path or the Systems path, NanoMem. The grey box is what you keep learning beyond the course, out of focus here. The green box is where it leads, the careers the path opens. Color key: blue is CS145 content, green is where it leads, grey is beyond CS145.
CS145: Your Data Journey
Master the core, pick a technical path, build a career.
CS
145
CS145 core curriculum
Core: SQL (+ Pandas, NoSQL)
the query languages for data
Project 1: SQL Mastery
BigQuery, tens of GB
Core: Systems
Storage, indexes, query opt
Core: Transactions
ACID, then distributed:
replication, sharding, CAP
Project 2: pick one
Science path
Enrich, visualize,
train an ML model
Systems path: NanoMem
Build a search engine
for AI agent memory
Beyond CS145
keep learning
Analyst /
Scientist skills
Engineer skills
Where it leads
Data Analyst
Data Scientist
Backend Eng
Platform Eng
Founder / CTO
Color key blue = CS145 content · green = where it leads · grey = beyond CS145
One map of the CS145 sequence: core database skills, then a project, then a project path, then typical industry roles that use that path.
Notes ↗
sql-metro · You'll read, debug, and write queries like this One query, three parts
One query, three parts
The power-users query broken into the three parts it is built from, each feeding the next. The first CTE, user_stats, rolls every listen up per user with counts of distinct songs and genres and a sum of minutes, grouped by user. The second CTE, power_users, keeps only users spanning at least three genres and ranks them into deciles by total minutes. The final SELECT joins back to user names and returns only the top decile. A closing line notes that an analyst, a scientist, an engineer and a founder all read the same query.
One query, three parts
The shape you will read, debug, and write.
user_stats
roll every listen up, per user
COUNT(DISTINCT song_id), SUM(...)
GROUP BY user_id
power_users
keep 3+ genres, then rank by minutes
WHERE unique_genres >= 3
NTILE(10) OVER (ORDER BY ...)
final SELECT
join back to names, take the top
JOIN users u ON p.user_id = ...
WHERE p.decile = 1
Analyst, scientist, engineer, founder. Same language, same query.
A production SQL pattern: two CTEs compute per-user aggregates and a decile rank, then an outer SELECT joins names and filters to the top decile.
Notes ↗
sql-metro · Where This Journey Leads: Real-World Architectures Spotify: one play event from click to dashboard
Spotify: one play event from click to dashboard
One play event traced across three panels, revealed in the order they matter. First OLTP, the real-time write path that takes the click. Then OLAP at the far end, the columnar analytics store, and the dashboards it powers. Last the ELT hop in the middle, the bridge that carries rows from one to the other. Originally: one play event traced left to right across three panels. The blue panel is OLTP, the real-time write path that takes the click. The grey panel is the ELT batch hop: extract from OLTP, load raw rows into the warehouse, transform them in place. The green panel is OLAP, the analytics store that serves dashboards. Each panel lists the algorithms this course teaches. Color key: blue is OLTP the write path, grey is the ELT hop, green is OLAP analytics.
Spotify: one play event, click to dashboard
OLTP writes it. ELT moves it. OLAP serves it. One SQL backbone, three roles.
OLTP: real-time writes
User app, then API
click "Anti-Hero",
100K requests / sec
LSM write path
MemTable, then flush to
SSTable L0, L1, L2;
background compaction
INSERT INTO listens
row store, under 10 ms,
write-optimized,
handles bursts
real
time
ELT: the batch hop
Extract + load
Spark bulk-loads raw
rows into the warehouse
Transform in place
aggregate at scale,
the algorithms this
course teaches
batch
load
OLAP: analytics
Columnar store
star schema, compressed
fact partitions
Aggregation queries
scan only the columns
a query needs,
read-optimized
Dashboards
Tableau, Snowflake,
the warehouse every
analyst reads
Color key blue = OLTP, the write path · grey = ELT, the hop · green = OLAP, analytics
One play event through OLTP for transactional writes, ELT for batch movement and transformation, and OLAP for analytics queries and dashboards.
Notes ↗
end of lecture 1 ~33 min of figures
Presenting
→ / space next build step, then next figure
← previous figure
↓ / ↑ one step forward / reset this figure
a reveal every step at once
g grid of every figure in this deck, with the lecture breaks
Home / End first / last figure
b break screen
Opening things
n the notes page for this figure
v the video, here, at this figure
s the schedule
q the nano quiz
y why this figure matters: the question it serves, and its level in the stack
c show the figure captions
Drawing on the slide
p / w pen colour / width
z / x undo one stroke / clear the slide
captions: the player's CC button
v or Esc to close