This is the third post in a series that formed the basis of my 2017 DevCon session on Increasing Code Quality While Staying Lean. Check out the first post for an introduction to the series. This series describes techniques that have made a big impact at SeedCode and we hope you’re inspired to incorporate some of these into your own work.
We Break Things into Small Chunks
Of all the things we do, this probably has the widest application. I think of this when I’m replying to a customer’s email, when I’m designing a new feature, or writing up the cases for what’s to be done in a sprint. And the more I keep this in mind, the better things go.
Here’s what we do:
We deliver every 3 to 10 hours of code.
For large projects, we deliver every week.
Deliver means deploy: putting code into production with data migration and everything.
[bctt tweet=”Break things into small chunks & deliver as they’re done–so we don’t outrun our understanding of the problem.” username=”seedcode”]
We do not listen to a client for 2 hours then head into the desert for 4 months to build their software, hoping they like it when we return. That is not how great software is made. Instead, we break things into really small chunks so we don’t outrun our understanding of the client’s issues. And, by delivering small pieces of work more often, that work gets validated quickly so clients can easily course correct.
In order for this to work, the small pieces of larger mods need to be put-into-production. It doesn’t help to deliver small pieces if they’re not deployed and validated. So whenever possible we construct sprints so that the outcome is a usable small feature—not part of a feature.
The same applies to work on our own products. We should have many small deliverables (many short QA videos) over the course of a two-week sprint instead of realizing at the end of the sprint that we made an assumption early on that went unchecked because nobody saw our work for weeks.
Tactics for Shipping Small Chunks & Why This Works
What does this look like when we’re making cases for each other and for subs?
- Cases should be binary: something that’s either completely done or not.
- Subcontractor cases should be < 10 hours. Ideally < 5 hours.
- Use timeboxing to keep things small. That means sticking to your delivery schedule even when features start to balloon. At the end of our sprints we QA and ship what we have and create new cases for the gaps or undone edge cases. Those become just more small chunks.
- We create gap / bug cases as we find them during development and QA.
- In cases where what we have isn’t a whole user-facing feature, we may disable the interface but still ship the code.
- FileMaker developers often freak out about this since “deployment” is one of the toughest things they do. Migrating data, managing serial numbers, and backfilling data changes is all time consuming and fragile. All I can say is that this is a place to invest in systems–be they as simple as thorough checklists, scripted imports, or moving solutions to the separation model. (At some point I hope Dan will publish an article on how he manages weekly deployments on our big projects.)
Delivering FileMaker Projects Every Week
We’ve been delivering in small chunks for a long time now: at least 6 years. But the best evidence for why this works comes from the fact that we’re delivering more often on our biggest projects. When we started our largest custom development project five years ago, we decided to deliver every three weeks, at the end of each sprint. This seemed audacious at the time and I remember lots of talks with Jason about how that would work. That original plan was delivering 70 hours of new work every three weeks (we QA’ed that work in 2-3 hour cases, with a video for each case).
But over time, and especially as we got into trickier parts of the project, Jason started doing some mid-sprint deliveries. He said it was less stressful to deliver what he’d done as it was finished than to save it up for a bigger delivery, with more moving parts, at the end of the sprint.
That eventually turned into delivering every week. And this just came about organically as a result of Jason trying to get a handle on his work. Jason and Dan are now delivering about 30 hours a week on that project. That we started delivering more often on our toughest project–and have stuck with it–is the best evidence we have that this works.
Why This Works
We don’t outrun our understanding of the problem
With small chunks, we’re just speaking to the customer more often. Our work is also getting validated because it’s being deployed in small enough pieces for the customer to digest. This means our work can get seen by all our constituents, not just the project’s informants. And we’re getting feedback now, instead of months from now.
[bctt tweet=”The only real mistake is to build the wrong thing.” username=”seedcode”]
No more half-done features: increased restart speed
It sucks to restart work on something that was never finished. And this means greater role portability as it’s easier to pick up someone else’s finished work than that undone novel you found in their drawer.
Redefines what’s a “bug”
This one sneaks up on you, but if you’re always delivering small chunks, it gets much easier to make a distinction between an error (i.e. “this column does not add up”) and something that just hasn’t been tackled yet (“I thought we’d be able to sort these columns by clicking on the header?”).
Most of what we used to call “bugs” are really either things we misunderstood or edges we hadn’t gotten to yet. An iterative delivery process makes that obvious both to your clients and your developers, keeping everyone’s morale high and making billing disputes a non-issue. Billing looks more like agreeing on a run rate (dollars per week or per sprint) and then comparing that to the velocity of features being delivered.
Reduced cognitive load
Uncommitted code Unmerged code is the greatest cognitive load, the loudest spooky music: large amounts of unmerged code are cancer.
We call this role-playing “the game” and we’ve found two real benefits to playing the game, even when applied to things that already appear to be pretty small features.
- It somehow just makes you see the feature more clearly. In particular, it lets you see the consequences of each change you propose to make: the lens of “ship every day” seems to throw consequences into relief.
- The truly tangible benefit is agility (below).
We were recently working on a small new feature for a customer: maybe 10 hours of code in DayBack Online. As part of the game we’ve broken this into 4 pieces and had deployed each one to DayBack Online as it was completed. The day before we’d promised to deliver the whole thing to our customer, one of our developers had an “automotive complication” that required his full attention. We emailed the customer and told them that their feature was live except for a small interface refinement (the last chuck we hadn’t shipped yet) and that we’d get that deployed next week. The customer was happy, and our developer could get to work on his car without distraction.
Picture the alternate universe in which we hadn’t deployed those 3 earlier chunks: in order to get the customer anything, we need to rush the QA and deployment of everything we’d done so far, risking the inclusion of unfinished code, and definitely stressing our developer at a time when they needed to step away from the project in the first place.
And when that developer does come back to finish the last piece, it will really feel like a refinement to something already completed, rather than like opening up the entire feature again.
That’s just a small example of something we’ve seen over and over since we started delivering more often. When we have to change direction, because someone’s car breaks down or because a customer pivots to another area of their project, we’ve more or less packed our bags already. We’re ready to head in a new direction, knowing that we can easily come back to the code we’re setting aside.
Jason adds, “These earlier chunks can be soft launches, and maybe we don’t even tell the customer…unless we have a complication…but that kind of detail doesn’t matter to the developer, because as far as they are concerned, those are done. It’s the developer we’re looking out for, because that’s how you build amazing apps.”