---
title: Delivering features faster
teaser: 'Get the most velocity from your product team as it transitions from prototyping
  and validation to growth.

  '
tags: technical debt,design sprints,product design,productivity
author: Kane Baccigalupi
published_on: 2019-05-15
---

Some teams play [planning poker](https://en.wikipedia.org/wiki/Planning_poker)
to carefully estimate and track their velocity. Others don't have such a
formal process, but can feel on a gut level when the team starts to lose
speed. Most teams do slow down. The terrible irony is that adding more
developers to the team to offset diminishing velocity has diminishing returns.
So, how can we get back to the sweet spot of delivering value fast?

## Don't get suckered by launch velocity

![Rocket with cowboy robot!](https://images.thoughtbot.com/blog-vellum-image-uploads/HbtOUEgXSuqqE9xh0O9n_rocket-robot-cowboy.png)

The beginning of a project feels so optimistic, and fast. There are lots of
foundational decisions, and then you are off to the races. Within a day you
can see something on a staging server. A day later, authentication is baked
in. By the end of the week, the product future starts to unfold with design
looming into coded reality.

While previous projects have decayed into technical debt, this time it feels
like you will get it right; you can fully understand your needs and build the
right stuff. The possibility of this kind of amazing delivery continuing
forever seems easy and achievable.

The thing that can be hard to recognize is that our early work on the project
is aided by many great frameworks and libraries that amplify every effort. If
we are honest, we have borrowed most of our stellar velocity.

![Graph of borrowed versus actual velocity at launch](https://images.thoughtbot.com/blog-vellum-image-uploads/dmFhfmnEQsGsRWJbLj2Y_launch-velocity.png)

*Borrowed and actual velocity at product launch.*

The more user interface and product that we borrow with those libraries the
faster we go, but with a cost. Libraries are meant to address general needs,
and products thrive on addressing very specific needs and flows. The vision
that we have borrowed from our libraries starts to
[drift](https://codeclimate.com/blog/are-you-experiencing-technical-drift/)
from our real needs. The greater the borrowing, the faster we descend into
technical and product debt.

In the launch phase, teams need to go to market quickly, and it would be
foolish to handcraft your own framework. Having a clickable wireframe that has
been tested with users, means the developers won't write useless code. Often
though, the product and business team don't understand or value product design
sprints, and aren't able to cut scope. These kinds of products will stagger
under their debt before we can know whether they are viable.

The thing that teams should keep in mind is that these early stage practices
of heavy borrowing are only sustainable during this early development, twelve
weeks or less. Much of the borrowing will need to be paid back, and postponing
that work after the pain point only leads to a compounding slow down.

## Hooray! you made it. Time to invest in a better growth plan

Now that your product has been validated, your process for developing the
product has to change.

### Invest in yourself

Many of the libraries that we depend on don't serve us well. Because we have
gotten so much from them in that early launch, we can hold on to them dearly.
Teams will write acres of code trying to force their libraries to bend to
their drifting will.

Listen to your pain, and beware of
[sunk cost fallacy](https://en.wikipedia.org/wiki/Sunk_cost#Loss_aversion_and_the_sunk_cost_fallacy).
You can be tricked into investing more time in propping up libraries than it
takes for you to write all new code that works the way you need.

Costly libraries typically have a lot of user interface, or opinionated ways
of working. It is pretty easy to notice your own user interface patterns and
aggregate them into a micro-framework. Don't rush to this work. Notice
patterns when they repeat three or more times, and clean them up then.

### Refactor in the small, not the big

Even in code that you have built to do exactly what your product needs, change
is constant. Your team will drift from the ideas that were once perfect. For
that reason, it is important to write lightweight code that changes easily,
and change it often.

Be a good camper and leave your code in a better place with every commit.
Small refactors and cleanups will help the team discover patterns and designs
that can be reused. Even extracting those patterns should be fast and easy.

Invest 10% of every feature, but not more, on this kind of clean up. That way
you will never be forced to do a major retrofit, or rebuild.

### Follow product and design

In the launch phase of a product, team members wear every hat. Changing hats
from product to design to development many times over while working on a
feature is fun, but costly. Development happens slower when we have to stop
and figure out what something should look like or how it should behave.

Product people are amazing orchestrators. With their focus on delivering the
highest impact and value, they can calculate what features and bugs a team
should work on first, last, and never. They get into the weeds about how
things should behave, who should get to do what. When they race ahead and do
that work with the help of design and user research, they de-risk and reduce
the cost of development.

Following product and design, we build just what is needed. That means lower
technical debt. Consistent products have more consistent code patterns.

## Rescue me!

![Graph of velocity at launch diminishing to rescue](https://images.thoughtbot.com/blog-vellum-image-uploads/ROGSaXWsTL2NfJHsf1ZA_rescue-graph.png)

<em>
  Diminishing velocities after launch when a product continues to borrow
  product and user interfaces instead of investing.
</em>

Teams don't always recognize they have transitioned from launch stage to
growth stage. Even teams that know they should be doing things differently
can't figure out how to make that change. Alarmingly often, great products
decay into a rescue project.

Teams come up with drastic and unrealistic ideas in these dark times.
Sometimes they want to rebuild from scratch. Sometimes they want to break
their behemoth ball-of-mud into microservices. A team that can't refactor that
kind of technical disaster won't be able to rebuild it as a whole or in tiny
parts. A code base in this state has to slow down and take stock.

Technical debt of this scale does not happen in a vacuum. It is driven by
practices outside the development team. Features that are under-specified or
shoved into the queue without validation, pile up as unmaintainable code.
Business leaders pushing for unrealistic releases can lead to a proliferation
of hard to track bugs. Evaluating the whole company's process of building
software is foundational to getting back to reliable feature delivery.

While it is counter-intuitive, the best approach to massive technical debt is
to do a product evaluation so that the team can trim down the feature bloat. A
retrospective design sprint that investigates the product's highest value can
help an overwhelmed team focus their efforts.

## Product lifecycle revisited

An idea launches itself into software and then grows up to be valued and used.
There are different and important practices for these two phases that can
prevent the product from becoming a rescue project.

### Launch

* Keep it small
* Borrow, but borrow wisely
* Validate everything with design and product practices

### Growth

* Pay back product that has been borrowed
* Get rigorous about design and product validating features
* Keep trimming and renewing the code
