← Back to writing

The 'Smallest Possible Slice' Heuristic for Shipping Complex Features

Most 'we delivered late' stories trace to one decision: the team scoped the first slice too big. The vertical-cut rule, the deploy-by-Friday filter, the pattern that breaks the heuristic, and a real before-and-after example.

Most "we delivered late" stories trace to one decision: the team scoped the first slice too big.

The team breaks down the feature into "frontend, backend, database changes, the new microservice." They estimate two weeks. Six weeks later, the database changes are merged but the backend isn't, the frontend is half-built, the microservice is on a feature branch that's now 800 commits behind main, and nobody can demo anything because nothing actually works end to end yet.

This pattern is so common it's worth giving it a name. Most teams break work down by layer when they should break it down by slice. The corrective: a heuristic I've leaned on for the better part of a decade — the smallest possible slice that touches every layer.

Why "MVP" is too vague to fix this

"Just ship the MVP" is good advice in spirit and useless in practice. MVP gets defined by stakeholder negotiation: marketing wants this, product wants that, engineering says we can have either of two things by date X. The result is a feature that's sized to "what fits in a sprint" rather than to "what actually works end to end."

The smallest-possible-slice heuristic is more specific. The first version of any non-trivial feature should be defined by these three constraints, in order:

  1. It touches every layer the final feature will touch — frontend, backend, persistence, infrastructure.
  2. It works end to end for one trivially specific case.
  3. It can be deployed to production by Friday.

Notice what's not on the list: completeness, polish, edge cases, performance. Those come later. The first slice exists to prove the wiring is correct.

The vertical-cut rule

Most teams default to horizontal decomposition. Sprint 1: schema changes and migrations. Sprint 2: backend API. Sprint 3: frontend. Sprint 4: integration. Each sprint produces something, but nothing is testable in production until sprint 4.

The vertical cut runs the other way. Sprint 1: the simplest possible end-to-end version. The schema has one table with three columns. The backend has one endpoint that returns a hard-coded response if the input matches. The frontend has one input and one output. It works for exactly one case. Ship it.

The reason the vertical cut wins: every sprint after the first is now additive. You're adding cases, polishing UI, expanding scope — but the core wiring is already proven. When the inevitable scope cut comes (and it always comes), you have shipping software to ship instead of four feature branches to merge.

The deploy-by-Friday filter

The cleanest forcing function for the smallest-possible-slice mindset is a question I ask the team every time we scope a new feature: can we get the first version into production by Friday?

If the answer is "yes, but only the schema changes," the slice is too horizontal. Throw it out. Re-scope.

If the answer is "yes, with one customer behind a feature flag, working for the simplest case," that's the right slice. Ship that, see what breaks in production, then iterate.

If the answer is "no, even the first slice will take three weeks," the work is genuinely large and you need to break it down into smaller features, not smaller slices of one feature. Bigger problem, different conversation.

The reason the Friday filter works is that it forces the team to find the small case. Most engineers are uncomfortable shipping something obviously incomplete. The Friday deadline overrides that instinct just enough to get the first slice out the door, and once it's out, the team's attitude shifts from "what should we build" to "what should we add next."

A concrete example

At Lavender, we shipped a new AI feature that recommended improvements to user-written sales emails. The first scoping pass from the team came back as a four-week project: prompt engineering work, a new evaluation pipeline, a UI component for inline suggestions, an analytics dashboard, an A/B testing harness.

I rejected it. Re-scoped to: one user, one email, one suggestion type, one model call, one button. The button shows up on a hardcoded email body for one specific user account. Click it, get a suggestion, render it. No analytics, no A/B, no eval pipeline.

That version shipped on the fourth day. It was visibly thin. It also worked, which we hadn't yet proven the original four-week design would. Over the next two weeks we extended it to all users, added the suggestion-type variations, layered in the eval pipeline, and turned on the A/B harness. The full feature was in production at three weeks instead of four, and we caught two architectural issues during the first week — issues that would have been brutal to fix at the four-week mark with everything already integrated.

Total elapsed: roughly the same. Total risk: dramatically lower. The "smaller" first slice was paradoxically the faster path.

When the heuristic breaks

The smallest-possible-slice rule fails for one specific category of work: research-shaped problems. Things where you don't yet know what the right answer is, only that there's a question.

Examples: training a custom model from scratch, designing a novel cryptographic protocol, exploring whether a certain optimization is even possible. You can't ship a thin vertical slice of a question. You have to do the research first.

The way I handle these: time-box the research as a separate phase, with a defined exit condition ("by week three we will have a written go/no-go decision on training a custom embedding model"). Once the research phase exits, the implementation phase reverts to vertical slicing.

The mistake to avoid: dressing up the research phase as a feature build. If you're scoping "build an MVP of the new model" when the real question is "is custom training viable for our use case at all," the team is going to drift. Be honest about which kind of work you're doing.

The tactical checklist

When a team comes to me with a feature breakdown, I run it through five questions:

  • Does the first slice touch every layer the final feature will touch?
  • Can it be deployed to production by Friday?
  • Is there at least one user (or test account) who will see something different on Monday?
  • If we shipped only this slice and nothing else, would it be embarrassing but functional, or non-functional?
  • What's the explicit list of what's not in the first slice?

The fifth question is the one most teams skip and the one that prevents scope creep most reliably. Writing down what's not in the first slice locks the team into the discipline of shipping something thin. Without it, "just one more thing" creep extends the slice by 50% before code is written.

The takeaway

The most reliable way to ship complex features fast is to ship a thin one first and grow it. Most teams know this in principle. Most teams violate it in practice because the first thin slice always feels embarrassingly incomplete.

The discipline is sitting with the embarrassment. Ship the thin slice. Watch it work in production. Then add the next slice. Repeat for as long as the work is generative.

The teams that internalize this ship faster than the teams that try to scope the whole feature up front, every time. The teams that try to predict everything at sprint planning and then deliver in one big bang ship slower and ship buggier. The slice heuristic is what separates these two patterns. Use it.

Convincing a skeptical team

The slice heuristic is intellectually obvious and culturally hard. Engineers who've spent years on teams that scope full features upfront will resist shipping the embarrassingly thin first version. The objections are predictable.

"It's not ready for users." Right — that's why it's behind a feature flag with one allowlisted account. Nobody will see it except the team.

"We're going to have to throw away this code when we build the real version." Maybe. But the discarded code is rarely the expensive part. The expensive part is the architectural learning, and that's preserved regardless of whether you keep the code.

"The product team will think we're shipping garbage." Get product in the room when you scope the slice. Show them that the next slice ships next week. The thin version stops being garbage when it's framed as a milestone, not a shipped feature.

The way I get past this with new teams is to show, not tell. Pick a feature, scope it the team's preferred way, then re-scope it as a thin slice. Walk through both timelines on a whiteboard. The thin slice almost always wins on calendar time, even when the team initially said it would take longer. After one or two demos of this, the team converts itself.

The retro question that locks the habit in

One question, asked in every retrospective for a quarter: could we have shipped a smaller first slice of the work we did this sprint?

The answer is yes more often than the team initially thinks. Asking the question consistently trains the muscle. After a quarter of asking, the team starts asking it during sprint planning instead of in retro — and that's when the heuristic has actually been internalized.

One additional pattern: the slice heuristic compounds with continuous deployment. If your team can ship to production multiple times a day, slicing becomes the default mode of operation rather than a discipline you have to remember. If your deploys are weekly or batched, slicing requires constant re-justification because each "small slice" feels like a wasted deploy slot. The teams that internalize the heuristic fastest are usually the teams that already have the deploy infrastructure to support it. If your team doesn't, fix that first — the slice discipline rests on it.