The Art of Finishing: Why Projects Die at 90% (And How to Ship Complete Work)
Your GitHub has 12 projects at 90% done. Why? Last 10% is hard: unsexy work (error handling, edge cases, polish), scope creep, fear of judgment, shiny new projects. Learn to design finishable projects (vertical slices, Definition of Done including polish), enforce WIP limits, run focus weeks and finishing sprints to actually ship.

TL;DR
Most engineering work stalls at 90% because the last 10%—error handling, edge cases, docs, real-world deployment—is unsexy but critical. Unfinished projects deliver zero value despite months of work. Build a culture that celebrates finishing by defining "done," protecting finisher time, and rewarding shipped projects, not just started ones.
The Art of Finishing: Why Most Engineering Projects Die at 90% Done
Look at your team's board. How many tickets say "90% done" or "almost there"?
The rewrite that's been 80% complete for three months.
The internal tool that's 90% done but no one actually uses.
The refactor that's 70% finished and quietly abandoned.
Your team has shipped thousands of lines of code. But how much is actually finished?
Here's the uncomfortable truth: Most engineering work stalls at 90%. The last 10%—the unglamorous polish, edge cases, docs, and real-world deployment—is where projects go to die.
And that last 10%? It's where all the value lives.
Let's talk about why finishing is so hard, why it matters more than starting, and how to design your team to actually ship complete work—not just "almost done" tickets.
The Graveyard of "Almost Done" Projects
Let's inventory the wreckage.
The Big Rewrite (stuck at 80%):
- Started 6 months ago
- New architecture, modern stack, clean slate
- Status: Core features work in staging. Missing: error handling, observability, data migration path, rollback plan
- Reality: Still running old system in production. Rewrite is vaporware.
- Sunk cost: 6 engineer-months. Delivered value: Zero.
The Internal Tool (stuck at 90%):
- Built to replace manual SQL queries
- Status: Works for happy path. Missing: error messages, input validation, docs, examples
- Reality: Engineers still write SQL queries manually because tool is confusing and breaks on bad input.
- Sunk cost: 2 engineer-months. Delivered value: Zero.
The Refactor (stuck at 70%):
- Extract common logic into shared library
- Status: Library exists. 5 of 15 services migrated. Remaining 10 still use old code.
- Reality: Now you maintain two implementations. Worse than before.
- Sunk cost: 3 engineer-months. Delivered value: Negative (increased complexity).
Total sunk cost: 11 engineer-months. Delivered value: Zero.
What if those 11 months had gone toward finishing 3 smaller projects? You'd have 3 wins instead of 3 half-done failures.
Why the Last 10% Feels So Hard
Finishing is hard because the last 10% is all the stuff you skipped to get to 90%.
Reason 1: The Last 10% Is Unsexy
The first 90%:
- Build core feature
- Make happy path work
- Demo it in sprint review (applause!)
The last 10%:
- Handle edge cases (what if input is null? empty? too large?)
- Write error messages users can actually understand
- Add logging and metrics
- Write docs
- Deploy to production and monitor for issues
- Fix weird bugs that only appear in prod
Guess which part is fun? Guess which part gets skipped?
Engineers optimize for interesting work. The last 10% is not interesting. It's necessary.
Reason 2: Scope Creeps During the Last 10%
What should have been:
- Finish logging
- Write docs
- Deploy
What actually happens:
- "While we're here, let's add this related feature"
- "Can we make it work with X too?"
- "Actually, we should redesign the API first"
Result: The finish line keeps moving. The project is "almost done" forever.
Reason 3: Fear of Real-World Feedback
Shipping to production means:
- Real users will use it
- They'll find bugs
- They'll complain about UX
- You'll have to support it
- You'll be on-call for it
Keeping it "almost done" in staging means:
- No users = no complaints
- No production bugs = no pressure
- No support burden = comfortable
Finishing means exposure. Some engineers (and teams) avoid that subconsciously.
Reason 4: New Shiny Projects Appear
Month 1-2: "This rewrite is the most important thing!"
Month 3: New feature request from CEO. "Can we build this for the big demo?"
Month 4: Another fire. "We need to fix this customer issue now."
Month 5: Rewrite is 80% done. But no one's working on it. Everyone's chasing new shiny things.
Starting is exciting. Finishing is not. Teams gravitate toward excitement.
Designing Projects to Be Finishable
If you want to finish more projects, design them to be finishable.
Technique 1: Smaller, Vertical Slices
Bad (horizontal slice):
- Phase 1: Build entire backend
- Phase 2: Build entire frontend
- Phase 3: Connect them
- Phase 4: Deploy
Problem: Nothing is usable until Phase 4. Can't get feedback. Can't deliver value.
Good (vertical slice):
- Slice 1: One feature, end-to-end (backend + frontend + deployed)
- Slice 2: Another feature, end-to-end
- Slice 3: Another feature, end-to-end
Each slice is shippable. Value delivered incrementally.
Example: Building a reporting dashboard
Horizontal approach:
- Week 1-2: Build all backend APIs
- Week 3-4: Build all frontend components
- Week 5: Integrate
- Week 6: Deploy
Vertical approach:
- Week 1: One chart type (backend + frontend + deployed)
- Week 2: Another chart type (backend + frontend + deployed)
- Week 3: Export feature (backend + frontend + deployed)
After Week 1, you have something users can use. Feedback loop is immediate.
Technique 2: Clear Definition of Done (Including the Last 10%)
Bad Definition of Done:
- ✅ Feature works in demo
Good Definition of Done:
- ✅ Feature works in demo
- ✅ Edge cases handled (null, empty, invalid inputs)
- ✅ Error messages are user-friendly
- ✅ Logging and metrics added
- ✅ Tests written (unit + integration)
- ✅ Docs updated (API docs, user guide)
- ✅ Deployed to production
- ✅ Monitored for 24 hours, no issues
Now "done" means actually done, not "90% done."
Enforcement: If it doesn't meet Definition of Done, it's not shippable. Period.
Technique 3: Explicit Cut Scope vs Nice-to-Have
At the start of a project, create two lists:
Must-Have (Core Scope):
- These features must ship. No negotiation.
Nice-to-Have (Future Scope):
- These features are explicitly deferred. We'll revisit later if needed.
Example: Building a notification system
Must-Have:
- Email notifications for critical events
- Opt-in/opt-out preferences
- Basic templates
Nice-to-Have (explicitly cut):
- SMS notifications
- Push notifications
- Rich HTML templates
- Scheduled digests
Benefit: When you hit 70% done and someone says "Can we add SMS?", the answer is: "It's on the Nice-to-Have list. Let's finish Must-Have first."
This prevents scope creep from killing the finish line.
Technique 4: Set a "Finish Sprint"
What it is: The last sprint is dedicated 100% to finishing. No new features. Just polish.
Activities:
- Fix known bugs
- Write missing tests
- Update docs
- Harden error handling
- Add observability
- Deploy and monitor
Team focus: Ship it. Make it production-ready. Close the loop.
Rule: No new features during Finish Sprint. If someone requests one, defer to next project.
Execution Patterns That Push Things Over the Line
Even with good design, you need execution discipline.
Pattern 1: "No New Projects Until These 2-3 Big Rocks Are Shipped"
The problem: Teams start 10 projects, finish 2.
The fix: Limit work in progress (WIP).
Policy:
- Max 3 active projects at a time
- To start a new project, finish an existing one
Example:
Before (chaos):
- Rewrite (80% done)
- Internal tool (90% done)
- New feature A (50% done)
- New feature B (30% done)
- Refactor (70% done)
After (focus):
- Rewrite (active, push to 100%)
- Internal tool (active, push to 100%)
- New feature A (active, push to 100%)
- Everything else: backlog
Result: Finish 3 projects in 6 weeks instead of starting 5 more and finishing 0.
Pattern 2: Focus Weeks for Finishing Work
What it is: Dedicate 1 week per quarter to "finish all the almost-done stuff."
Rules:
- No new features
- No meetings (except critical ones)
- Focus: ship what's at 70-90%
Activities:
- Deploy the rewrite
- Finish the internal tool docs
- Migrate remaining services to new library
- Fix the 10 "minor" bugs that have been sitting for months
Result: Quarterly cleanup. Prevents accumulation of half-done work.
Pattern 3: Dedicated Polish Sprints
What it is: After building an MVP, schedule a 1-week polish sprint before calling it "done."
Polish activities:
- Improve error messages
- Add loading states and animations
- Fix UI quirks
- Write user-facing docs
- Test edge cases manually
Why it matters: Polish is the difference between "works" and "feels good."
Users won't say: "The feature works but error messages are confusing."
They'll say: "The feature sucks." (Even though the problem is just polish.)
Polish makes features feel finished.
Leadership's Role in Rewarding Finished Work
Teams optimize for what's rewarded. If you reward starting, you'll get lots of starts. If you reward finishing, you'll get finishes.
What Gets Praised in Your Standups?
If you praise:
- "Alice started the new dashboard!" → You're rewarding starts.
- "Bob wrote 2,000 lines of code this week!" → You're rewarding output.
Instead, praise:
- "Carol finished the dashboard, deployed it, and 10 users are already using it." → You're rewarding completion.
- "Dan closed 5 long-standing bugs that have been annoying users for months." → You're rewarding impact.
Engineers notice what you celebrate. Celebrate finishing, not starting.
Make Completion Visible
Problem: Finished work is often invisible. It just works, so no one talks about it.
Solution: Make finishing visible and celebrated.
Ways to do this:
- Demo finished projects in sprint reviews (not just "in progress" work)
- Highlight shipped features in all-hands
- "Ship of the week" recognition
- Track "projects finished" as a team metric (not just "story points completed")
Example metric:
| Quarter | Projects Started | Projects Finished | Finish Rate |
|---|---|---|---|
| Q1 | 12 | 4 | 33% |
| Q2 | 8 | 6 | 75% |
Goal: Increase finish rate. Not by working harder, but by starting fewer and finishing more.
Treat Polish as Real Work, Not Filler
Bad attitude: "We're done with the feature. Polish is optional if we have time."
Result: Polish never happens. Every feature feels half-baked.
Good attitude: "Polish is part of the feature. It's not done until it's polished."
How to enforce:
- Include polish in Definition of Done
- Allocate time for it in sprint planning
- Don't mark tickets "done" until polish is complete
Polish is not optional. It's the last 10% that delivers 50% of the perceived quality.
Closing: Done Is a Feature
Here's what separates great engineering teams from mediocre ones:
Mediocre teams: Start lots of things. Finish few. Board full of "almost done" work.
Great teams: Start fewer things. Finish most. Small backlog, high completion rate.
Why it matters:
Half-finished work has zero value. It can't be used. It can't be supported. It's just sunk cost.
Finished work compounds. Users use it. It provides value. It's a foundation for the next thing.
Finishing is a skill. And like all skills, it can be learned and systematized.
Challenge: Pick One 90% Project and Finish It
Here's your homework:
Step 1: Inventory the graveyard
List all projects that are 70-90% done but not shipped.
| Project | % Complete | What's Missing? | Est. Time to Finish |
|---|---|---|---|
| Example: Dashboard rewrite | 85% | Error handling, docs, deploy | 1 week |
Step 2: Pick ONE project
Criteria:
- Highest business value
- Smallest time to finish
- Clearest definition of "done"
Step 3: Design a 2-week push to finish it
Week 1:
- Day 1-2: Fix edge cases and error handling
- Day 3-4: Write docs and tests
- Day 5: Code review and merge
Week 2:
- Day 1: Deploy to staging, test
- Day 2: Deploy to production (gradual rollout)
- Day 3-5: Monitor, fix bugs, stabilize
Step 4: Ship it
Step 5: Celebrate
Sprint review: "We finished the dashboard rewrite. It's live. Users are happy."
Then: Move to the next 90% project.
Goal: Finish 3-4 "almost done" projects over the next quarter.
Result: Your team will have shipped more value in 3 months than the last 6.**
Starting is easy. Finishing is hard. But finishing is where the value is.
A graveyard of 90% projects is just a museum of wasted effort.
Done is a feature. Ship it.
