🧵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
🐍Python Decorators Introduction
Build one mental model for Python decorators that covers closures, argument passing, functools.wraps, and stacking — then ship a working caching or logging decorator from scratch in under 30 lines.
🦀Rust Lifetimes Explained
Stop reading `'a` as line noise and start reading it as scope arithmetic — one failing snippet at a time — until you can thread lifetimes through a small parser or iterator adapter without fighting the borrow checker.
☸️Kubernetes Core Concepts
Stop drowning in 30+ resource types. Build the mental model one primitive at a time -- pods, deployments, services, ingress, config -- then deploy a real app with rolling updates and health checks.
📈Big O Intuition
Stop treating Big O as math you memorized for an interview — build the intuition to spot O(n²) disasters, pick the right data structure without thinking, and rewrite a slow function from O(n²) to O(n) in under five minutes.