Gravel vs BRICKs: The Framework That Changed How I Measure a Build Session
The Problem With "Productive" Days
I'd close my laptop after eight hours feeling like I'd built something, but when I checked production, nothing had changed. The metrics hadn't moved. Users saw nothing new.
I'd reorganized my task board, researched state management patterns, debated CSS architectures, written TODO comments about refactoring — all legitimate work. But none of it compounded. None of it was still working for me the next day.
That's when I started separating GRAVEL from BRICKs.
What Makes Something a BRICK
A BRICK is deployable output that compounds. Key word: deployable.
Not "could be deployed eventually." Not "sets up future deployment." Actually shippable to production right now, even if it's behind a feature flag.
Examples from my last build session:
- New API endpoint that returns user analytics: BRICK
- Database migration that adds the analytics table: BRICK
- React component that displays the analytics: BRICK
- Supabase RLS policy that secures the new table: BRICK
Each one went to production within an hour of being written. Each one is still working while I sleep.
What Makes Something GRAVEL
GRAVEL is work that disappears the moment you stop doing it.
It's not useless — you need some GRAVEL. But it doesn't compound, and it's dangerously easy to fill an entire day with it.
Examples from that same session:
- Reading three articles comparing Zustand vs Jotai: GRAVEL
- Reorganizing my components folder by feature: GRAVEL
- Writing a 40-line comment explaining why I chose a certain approach: GRAVEL
- Researching the "perfect" database index strategy: GRAVEL
The refactored folder structure didn't ship. The research didn't ship. The comments might help future-me, but they're not working for me right now.
The Framework in Practice
I now track every build session with two numbers: BRICKs laid, GRAVEL moved.
Today's session:
BRICKs: 4
- Email notification system (deployed)
- User preference toggle (deployed)
- Database backup script (running on cron)
- Error boundary component (in production)
GRAVEL: ~2 hours
- Debated email provider options
- Read docs on rate limiting
- Cleaned up old console.logs
4 BRICKs, 2 hours of GRAVEL. That's a good ratio.
But I've had sessions with 0 BRICKs and 6 hours of GRAVEL. Those days feel productive — I'm busy, I'm thinking, I'm learning — but I wake up the next morning with nothing new running.
The Trap: Preparation Gravel
The most seductive GRAVEL is preparation work that feels like building.
- "I need to finalize the architecture before I write code"
- "Let me research best practices first"
- "I should set up proper testing infrastructure"
These sound responsible. But I've learned: architecture emerges from deployed code, not the other way around. Best practices matter when you're refactoring something that already works. Testing is easier to add to a feature that users actually need.
I used to spend hours planning the perfect implementation. Now I ship a working version in 30 minutes, then improve it based on real usage.
GRAVEL You Can't Avoid
Some GRAVEL is necessary:
- Triaging support emails
- Fixing a production bug that's blocking users
- Renewing an SSL cert that's expiring
- Responding to a Stripe webhook failure
I call this reactive GRAVEL. You can't defer it. But you can timebox it.
I handle reactive GRAVEL in dedicated 30-minute blocks. If a bug takes longer, I either ship a quick patch (a BRICK) or defer it until I can build a real solution (more BRICKs).
What I don't do: let reactive GRAVEL consume an entire build session.
How This Changed My Build Sessions
Before this framework, I measured productivity by hours logged. Now I measure it by BRICKs deployed.
Some sessions I lay one BRICK in 45 minutes. Others I lay six BRICKs in four hours. The time matters less than the output.
This also solved my burnout problem. BURN happens when you're working hard but not making progress. When I track BRICKs, I can see progress clearly. Even slow days accumulate.
Last week I had a terrible build session — couldn't focus, kept getting distracted. But I shipped one BRICK: a small API refactor that reduced response time by 200ms. That improvement is still running. The distracted time is gone.
The Question I Ask Now
Every time I start a task, I ask: "Is this a BRICK or GRAVEL?"
If it's GRAVEL, I need a reason. Usually the reason is "this is reactive GRAVEL I can't defer" or "this is 10 minutes of research before I lay a BRICK."
If I can't justify the GRAVEL, I don't do it. I find a BRICK to lay instead.
Some days I only lay one BRICK. But one BRICK is infinitely more than zero.
10 CLAUDE.md templates that enforce the behavioral doctrine, not just your job title. Drop one in your project and your next session starts with Claude already knowing how you work.
Get The Compound Stack — $27 →