🧵Understand Concurrency Memory Models and Write Race-Free Code
Stop guessing whether your atomics need `seq_cst` and start picking orderings from first principles — one primitive at a time — until you can write a lock-free counter that provably can't race.
Phase 1Why Memory Models Exist
See why sequential consistency is a lie you rely on
Your program runs in an order nobody wrote
7 minYour program runs in an order nobody wrote
A data race and a race condition are not the same bug
6 minA data race and a race condition are not the same bug
Five memory orderings, each with a different job
7 minFive memory orderings, each with a different job
Store buffers are why your store didn't show up yet
7 minStore buffers are why your store didn't show up yet
Phase 2Happens-Before on Paper
Reason about happens-before with tiny, concrete programs
Happens-before is a graph, not a clock
8 minHappens-before is a graph, not a clock
Release is how you hand data to another thread
7 minRelease is how you hand data to another thread
Acquire is how you claim what was published
7 minAcquire is how you claim what was published
CAS isn't just an atomic swap — it's an ordering decision
8 minCAS isn't just an atomic swap — it's an ordering decision
Relaxed is correct exactly when you don't care about order
7 minRelaxed is correct exactly when you don't care about order
Phase 3Picking the Right Ordering
Compare seq_cst, acquire/release, and relaxed in real patterns
You inherit a spinlock that deadlocks only on ARM
8 minYou inherit a spinlock that deadlocks only on ARM
The reference count that crashes during destruction
8 minThe reference count that crashes during destruction
The once-init that double-runs on two cores
8 minThe once-init that double-runs on two cores
The SPSC queue that drops messages under load
8 minThe SPSC queue that drops messages under load
Phase 4Build a Lock-Free Counter
Write and defend a correct lock-free counter
Ship a lock-free counter you can defend
8 minShip a lock-free counter you can defend
Frequently asked questions
- What is a data race, and is it different from a race condition?
- This is covered in the “Understand Concurrency Memory Models and Write Race-Free Code” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- When is it safe to use memory_order_relaxed?
- This is covered in the “Understand Concurrency Memory Models and Write Race-Free Code” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- What does happens-before actually mean?
- This is covered in the “Understand Concurrency Memory Models and Write Race-Free Code” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- Why isn't volatile enough for thread safety?
- This is covered in the “Understand Concurrency Memory Models and Write Race-Free Code” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- Do I need seq_cst for a counter?
- This is covered in the “Understand Concurrency Memory Models and Write Race-Free Code” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
Related paths
🐳Docker Containers Basics
Build the mental model first, then the commands — from containers vs VMs through images, layers, volumes, and networking to composing a multi-service app.
🧪Property-Based Testing
Go beyond example-based tests — learn to express what your code should always do, then let a framework find the inputs that break it.
🦀Rust's Ownership Model
Build a working mental model of Rust's ownership system — from stack vs heap intuition through borrow checker mastery — so you can read and write Rust without fighting the compiler.
💻Elixir Pattern Matching
Stop reading `=` as assignment and start using it as Elixir's core flow-control tool — through function heads, guards, and `with` — until you can rewrite a tiny command parser without a single `if`.