Velocity is not the Goal

Quote

“ve·loc·i·ty (n) – a measure of how many points a team completes during a sprint.”

On velocity

Velocity is often the first scrum metric we encounter.  It’s a quick way to gauge how many points a team completed during the previous sprint, and how many they’ll likely complete in the next.  It’s clean, simple, and easy to understand.  It’s also easy for people to get attached to.

On predictability

Teams that post consistently high velocities are often treated as valuable to the organization.  However, those teams that tend to be more erratic…posting a high velocity one sprint then falling off dramatically the next…may not be as valuable as they may first appear.

The reason is that velocity isn’t as valuable as predictability.  Much of what we do in agile is done with the aim increasing the predictability of our team.  The more predictable a team is, the more effectively we can plan into the future.  This lets us take risks more intelligently as well as formulate more realistic strategies based on what our teams can likely deliver in a given timeframe.

Teams that post high velocities followed by low velocities are very erratic, and thus can’t be planned for.  And if a team can’t be planned for, then its value to the organization declines.

What’s the harm in an erratic velocity?

Erratic velocities can lead to difficult planning for any team.  Not only long term release planning, but even short term sprint planning will suffer since the team won’t be able to accurately forecast how many points they can complete during a given iteration.

If your team is experiencing erratic velocity, then it may be time to look upstream at your estimating process.  Often unpredictable velocities or missed forecasts are the result of poor estimates at sprint planning time.  Even exceeding your forecast can be a symptom of over-estimating the amount of work selected for the sprint.

Regardless of whether your estimates are missing up or down, your planning process is suffering.

So what’s the goal?

If velocity isn’t the goal, then what is?

Regardless of the hype surrounding ‘fast’ agile teams, at the end of the day agile is often more concerned with predictability than speed.  Posting a high velocity for one sprint isn’t helpful if your team can’t sustain it.  However, posting consistent velocity numbers goes a long way towards great planning.

Does this mean that a team shouldn’t strive to produce their velocity?  Not at all, it means that improving a team’s velocity shouldn’t be its goal.  Instead, the team should focus on what it takes to improve that velocity.  Practices such as continuously improving the engineering process or systematically identifying and chasing out risk will naturally result in higher velocity.

Focus on these things and the velocity will come.

 

Zappos and the Elimination of Managers

There’s been a lot of discussion lately about Zappos’ move to eliminate managers from their hierarchy.  If you haven’t heard yet, go check out the Fast Company article on the transition, which does a nice job of summing up the move.

While the tagline Zappos abolishes Managers has gotten great press, in actuality it’s a bit of an over-simplification of what’s happening.  In actuality, Zappos is transitioning to a new structure which organizes its employees in groups around work to be done, called a holacracy.  Rather than following a traditional hierarchical management system, this new structure tends to resemble self-organizing circles focused on individual projects comprised of employees selected for their skill sets.

Are there really no managers?

Perhaps, but that doesn’t necessarily equate to no leaders.  Reams of business literature have told us time and time again that given any group of sufficient size, leaders naturally emerge.  Whether we want them or not, this seems to be a a natural part of human nature…it’s in our DNA.

If this is indeed the case, then any attempt to eliminate traditional managers from an organization may be for naught.  Left unchecked, it wouldn’t be surprising for the exact same organizational structure to reemerge, sans titles of course.

However, this natural tendency to evolve towards structure may not be a bad thing either.  Elimination of titles and structure will effectively give Zappos the opportunity to press the reset button on their organization and allow the true leaders to emerge across the company.

Most organizations would kill for this chance.

What’s wrong with a traditional hierarchy?

Of course, this begs the question “What’s wrong with a traditional hierarchy?”  After all, history is full of companies which have become very successful under one.  However, the fact that traditional management hierarchies have not killed every company in history doesn’t exactly absolve them of guilt, either.

Imagine a small startup, perhaps made up of two co-founders.  It’s unlikely that one co-founder has asserted themselves as the manager of the other.  Rather, its more likely that the two co-founders view one another on equal footing and have come together due to the unique skills each has to offer.  In the early stages, even as a few more employees are added here and there, it’s likely that this culture will remain largely unchanged.

However, as the company becomes successful and begins to scale this organizational structure will not.

Eventually the leadership of the company will face a day when they need to introduce some sort of management structure to help the company scale.  On the whole they will be faced with two options: Flat or Deep.

Flat Hierarchies

Flat hierarchies tend to evolve when individual managers have responsibilities for managing large groups of people.

Flat Hierarchy

This particular structure seems to have come into favor in recent years, especially in the tech industry.  And for good reason too, as flat structures offer a lot of benefits:

  • Fewer layers of indirection between the people on the bottom of the organization and those on the top.  This tends to lead to more efficient execution of strategies set by the top ranks as the strategy is less likely to be watered down or changed as it passes through each successive rank.
  • The evolution of cross-functional teams.  Since less managers are available in the organization, they tend to accrete more direct reports.  One of the common side effects of this is those reports may not only specialize in the same field as the manager, but also those that are complementary.  For example, an engineering manager may not only be responsible for managing engineers, but may also be given responsibility for complementary teams such as quality assurance or technical writers.  These cross-functional teams tend to delivery more efficiently as the walls of bureaucracy are torn down.  In fact, this can even result in reduced in-fighting amongst groups that have to work closely together.
  • Faster scaling teams.  When an individual manager is already responsible for managing 12 people, adding one new employee to their ranks has much less impact than adding an employee to a manager who only has 3 direct reports.  This lets flatter organizations scale up teams more rapidly, for better or worse.

However, for all of the benefits of a flat organization they’re not without their drawbacks.

  • Less one-on-one attention from managers.  Obviously a manager whose responsible for 12 people has less time to spend with each than a manager whose only responsible for 3.  This translates to not only less time for one-on-ones, goal setting sessions, and mentoring, but also less time to simply get to know each employee on a personal level.  This can lead to less engagement amongst employees, less attachment to an organization’s goals, and ultimately, higher turnover.
  • Less mentoring to those employees not in the manager’s speciality.  Let’s return to our example of the fateful engineering manager tasked with responsibility for not only software engineers, but also quality assurance engineers, and technical writers.  If the manager’s background is in software engineering then they are likely to be an excellent resource for their reports who are also aspiring software engineers wanting to take their careers to the next level.  However, what about the quality assurance engineers and technical writers?  If this is not the manager’s area of speciality they’ll need to invest extra time in learning how to coach these employees, or risk having an overall lower skilled team.

Deep Hierarchies

Deeper hierarchies tend to evolve when organizations grow towards many layers of middle management, with each manager responsible for only a few direct reports.

Deep Hierarchy

This is a bit more of a traditional management structure, and can offset many of the disadvantages of flatter hierarchies described above.  Specifically,

  • More one-on-one attention from managers.  More managers means smaller teams which means that managers have more time to focus on each of their people.  This can translate into not only more frequent one-on-ones with each employee, but also more time for career planning and goal setting.  All of this translates into each manager getting to know each employee better and having more opportunities to imbue the organization’s culture and goals to the employee.  All of this can lead to more engagement for the employees and, ultimately, lower turnover.
  • More appropriate mentoring for each employee.  More managers also means that it’s less likely teams will evolve to be cross-functional.  Rather, they’ll tend to stay siloed in teams focusing on specific areas of expertise.  The benefits of cross-functional teams notwithstanding, increasing the likelihood that a quality assurance engineer will be mentored by a manager who built their career in quality assurance means that engineer can have more relevant mentoring and may reach their career goals quicker.

These benefits aside, however, deep hierarchies are not without their drawbacks.

  • Less efficient execution of strategies.  Just like the classic game of Telephone, no matter how great any strategy starts at the top, the more layers of indirection it crosses through the more likely it is to become weakened or watered down.  In the worst scenarios, it may even be corrupted to serve each individual manager’s own goals and agenda.
  • More silos between closely operating teams.  If you have more managers the temptation is greater to divide teams amongst specialities.  While this can lead to better management of each employee, the effect of these artificial barriers between teams working together each day cannot be understated.  Given any team structure the members of those teams will eventually grow to rival and compete against one another.  While a little competition is a great thing, it can easily get out of hand and evolve to resentment between teams working closely together.  Once started, this in-fighting can be difficult to reign in.
  • Slower scaling teams.  When a multitude of hierarchies exist in a given organization adding more employees can create friction.  This is due not only to the greater impact a new employee can have a smaller team, but also to the waves of indirect disruption the change can have on teams that work directly with that team.  While this effect may occur simply because the manager is more effectively managing their people due to the smaller team, the effects that it can have on an organization that needs to scale up and down quickly shouldn’t be ignored.

Will this scale better than a hierarchy?

Returning to our discussion of a holacracy, one of the biggest questions facing the this structure is how effectively will it scale?

Bearing in mind the points above regarding deep versus flat hierarchies, we know that larger teams, in particular cross-functional teams, tend to scale quicker than smaller and more siloed teams.  The holacracy seems to exhibit both of these larger and cross-functional qualities.  In addition, we also know that the elimination of a middle management layer could lead to a more effective execution of strategies since each team member has the opportunity to work closer to the top-level decision makers.  Whether or not this will be the actual result, however, remains to be seen.

While the lack of middle management may in theory give rank-and-file employees more access to top leaders, it also puts the onus on the employee to take the initiative for their own career growth in the organization.  This includes not only mentoring and growth opportunities, but also the adoption and incubation of the organizational culture and values across all employees.  Given what we know about Zappos hiring practices and resulting culture this may not be much of an issue for the average Zappos employee.  However, not every company has earned the reputation of hiring for passion that Zappos has, how this will effect other, less passionate, organizations remains be seen.

Regardless of the result of Zappos move to a holacracy I have no doubt that we’ll have plenty of visibility and insight in the results, due to Tony Hsieh’s transparent operating style.

I’m looking forward to seeing what we can learn.

Lessons learned using Flyway DB with distributed version control

Recently our team introduced Flyway for automating schema changes to our database.  Along the way, we learned a few interesting lessons about using a schema migration tool in a team heavily bought into a distributed version control.

Our team uses Git for source control which gives us the ability to easily create branches used only by a few developers.  Like most teams, our workflow consists of creating a branch from the mainline branch of code, implementing and testing a new feature inside of that branch, and then merging that branch back into the mainline for shipping.

branching-workflow

This can cause a bit of havoc with the default configuration of Flyway, but it can be easily worked around using the tips below.

Prefix your migrations with timestamps rather than integers

By default, most migration frameworks choose to prefix the individual migrations with an integer, as in the example below.  When the framework encounters migrations not yet applied to the current database, it starts with the first migration whose prefix isn’t present in the database and begins applying them in ascending order.

  • 1__add_customers_table.sql
  • 2__add_email_address_column_to_customers_table.sql
  • 3__add_orders_table_with_reference_to_customer_table.sql

This works great when everyone is on the same branch of code.  However, once members of the team begin working on their own branches, the likelihood of a prefix collision increases dramatically.

Branching workflow with collision

But, if you choose to prefix your migrations using timestamps rather than integers, then the likelihood of a collision virtually disappears, even across branches.  For example, using a pattern such as yyyyMMddHHmmssSSS the migrations above now look like…

  • 20130704144750766__add_customers_table.sql
  • 20130706132142244__add_email_address_column_to_customers_table.sql
  • 20130706151409978__add_orders_table_with_reference_to_customer_table.sql

Branching workflow with timestamps

The timestamp pattern above is precise down to the millisecond.  While a highly precise timestamp can lead to hard to read prefixes, the more precise your prefix then the less likely a collision will be.

For best results, you’ll want to automate the creation of this timestamp so all members of your team are using a consistent format.  To get you started, I’ve added Gists of both the Ant task and the Groovy task that we use to prefix new migrations.

In addition, note that Flyway also treats timestamp prefixes as integers.  This means that if you originally began working with Flyway using integers then you can still switch to timestamps at any point.  Since the timestamps are just very large integers, the first timestamp prefixed migration will simply be applied after the last integer prefixed migration.

Enable out of order migrations

Now that we’re using prefixes to timestamp our migrations we can rest assured that we won’t have any collisions when our branches are merged back into the mainline.  However, what about your teammates who stayed on the mainline?  Once your changes are merged back in they’ll need to apply your migration to their databases but they’ll already have higher prefixed migrations.

By default, Flyway will not apply migrations older than the latest migration already applied to the database.  That means in our last example your team members will not be able to apply your latest migration.

To allow this, you’ll need to enable out of order migrations with Flyway.  This is as easy as setting the Out of Order value to true in whichever API you’re using to drive Flyway.

Create idempotent migrations

In a perfect world, each migration will only be run once against each database.

In a perfect world, that is.

In actuality, there will be cases where you’ll need to re-run migrations against the same database.  Often this will be due to a failed migration somewhere along the line, causing you to have to retrace your steps of successful migrations before to get the database back in a working state.  When this happens, it’s incredibly helpful for the migration to be written in an idempotent manner.  If you’re not familiar with idempotence, it’s simply a very fancy term describing an operation that can be performed multiple times without additional effects.

Let’s take the migration below, which adds a column to a table, as an example…

ALTER TABLE customers ADD email_address VARCHAR(256);

Assuming that your database already contained a table customers, this migration will successfully add the email_address column to it.

However, what would happen if you ran this migration a second time against that same database?  Since the email_address column now already exists in the customers table, you would receive and error along the lines of this…

ERROR 1060 (42S21): Duplicate column name 'email_address'

Now imagine troubleshooting this situation if it occurs in a much more complex migration script, particularly if that script is only one of multiple scripts currently being applied to the database.

We can avoid this issue by making our migrations idempotent…or able to be applied multiple times without side effects.

This is done by checking the the state of the database before making any change to it, and only applying the change if necessary.  In the example above, changing the script to be idempotent might yield something like this…

IF NOT EXISTS ((SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='customers' AND column_name='email_address')) THEN
     ALTER TABLE customers ADD email_address VARCHAR(256);
END IF;

This is introduces a fair amount of noise into our script, but at a high level we’re simply enclosing our ALTER statement in an IF statement that first checks the database’s information schema tables to determine whether that column exists for that table for that database.  If the column already exists then the script simply returns, otherwise it is added to the table.  This allows us to run the same script multiple times against the same database without issue.

Note that this is actually a bit tricker if you’re using MySQL.  Since MySQL doesn’t allow IF statements outside of stored procedures the statement above actually won’t work as a stand alone script.  In order to create idempotent migrations in MySQL it’s actually necessary to enclose each migration in a stored procedure, execute the stored procedure against the database, and then drop the stored procedure at the end.  I’ve added a Gist here that demonstrates this method for MySQL.

Wrapping up

While I’ve used Flyway, MySQL, and Git in my examples here, none of this is actually specific to these technologies.  In fact, you’re likely to encounter the same types of issues when introducing database migrations in any environment using a distributed version control system.  Luckily, the techniques above should be supported in any mature migration framework and can save you a lot of potential pain and headaches.

 

If you build it they will come, and other lies you’ve been told.

A group of plucky college kids churn away in their dorm room creating the next website   that takes the world by storm. After months of hacking away, the site is unveiled to the world and instantly becomes a runaway success.

A pair of developers spend their evenings around their kitchen table working tirelessly on the next killer app. After weeks of work the app finally emerges from the dim light of the kitchen to become the latest app store hit.

LightBulbWe’ve all seen the movies and read the stories, a group of outsiders create something completely under the radar that when unleashed on the world becomes the next runaway success. It’s sexy, it’s exciting, and it’s inspirational to millions of young entrepreneurs. However, there’s one problem: it rarely happens that way.

Sure there are the exceptions, like the Facebooks and the Angry Birds of the world. But what makes these stories so sensational is not that they’re the norm…it’s that they’re the outliers.

In reality, products that are built inside the vacuum of a dorm room or kitchen often emerge only to a different kind of vacuum: silence. More often than not these products that have been built without customer input tend to miss the mark in meeting, much less exceeding, the market’s needs. They rarely provide that “a-ha” moment or “scratch the itch” the customer never knew they had. Instead, these products are met with a lack of interest or impact, if the customer even looks at them at all. The end result is that the product of all of that work in the vacuum becomes yet another casualty of missing the mark.

Getting customers involved

Most companies test their product with customers during beta phases, but this late in development many critical decisions have already been made. These decisions can make it difficult to correct the issues brought up by customers during the beta process. Rather than taking advantage of the opportunity to learn how their product can better serve the customer’s needs, many teams insist on spending this time trying to sell the customer on why the decision they made without their involvement is actually better.

Other teams take the opposite of approach. They spend endless hours interviewing customers before a single line of code has been written, instead trying to divine the customer’s every want and need. These sessions are incredibly valuable and yield a fountain of user information about the day to day struggles and pain points a customer faces as well as what could make their life better. While this is a great start, unfortunately many of these promising teams then take their new found information away and disappear for the remainder of the development process. By the time they reappear they’re often dismayed to learn that the customer’s initial vision and the reality of actually interacting with the end product are often nothing more than a study in stark contrasts.

Customer involvement throughout the entire life cycle

What’s wrong with these scenarios? In both cases, the team is seeking customer feedback. In both cases the team seems genuinely willing to hear what the customer says. However, in neither case does the team does set themselves up to respond to the customer’s feedback in an efficient way.

In the first case, the team can incorporate customer feedback at the beginning but will never have the opportunity to course correct since the customer doesn’t see the product again until launch. In the latter case, the the entire product has been developed on assumptions of the customer’s needs that were never even validated. The solution is to involve the customer from start to finish. Incorporate the customer in the early visioning of the product, and make the effort to understand their needs. Then, as development begins, continue to seek feedback from the customer throughout the entire process, evolving the product as the customer’s needs evolve in light of realizations about what your product can deliver.

If I’d ask people what they wanted, they would have said a faster horse

This quote, often attributed to Henry Ford, is usually cited as an excuse for not asking customers what they want when building a product. But unfortunately the quote focuses on the wrong question to ask.

Asking what a customer wants will yield less than stellar results…instead ask the customer what they need. What one thing would give them the edge against their competition? If money were no object, what would they do for their business? Spend time with the customer learning how they do business. Learn the pain points that have become so routine and such a daily part of their lives and they don’t even notice them anymore. And most importantly, encourage them to dream and to challenge you on what they want…not what you want them to have.

But we’re disruptive

And I’m very happy for you. However, being disruptive is not an excuse for not talking to customers. Even disruptive ideas benefit from feedback. Don’t flatter yourself to believe that your the first person who has ever thought of disrupting the healthcare/financial/education market. You’re not. Others have come before you and they have failed. Talk to your customers and understand why those others have failed. There’s a reason your customers did not buy from those others, you owe it to yourself…and your product…to understand why.

Take the opportunity

We all want to build great products. We all want to create things our customers want. However, many of us miss an easy opportunity to gain insight into what our customers want by simply involving them in the product development process. Talk to your customers, you’ll be glad that you did.

How to Build the Right Team

Did you know that payroll is usually the biggest expenditure of any software company? If you do, then it should come as no surprise that many companies tout the line ‘people are our greatest asset’. However, it can be scary just how little thought those same companies put into hiring the right people for their teams. Here are some things that we’ve learned over the years which have helped us continue to build a great team.

A-B-R. Always Be Recruiting

With apologies to Glengarry Glen Ross, the number one rule of the game is Always BRecruiting. Too many times a team will only think about who they would like for an opening just as that position is posted. This is the easiest way to guarantee that you’ll move faster than you meant to on a hiring decision and inevitably settle for a candidate. And, when you’re working on something as important as growing your team, settling is one thing you do not want to do.

So how do you prevent yourself from being forced to make a decision before you’re ready? By always having a pipeline of strong candidates available at any given time. We build this pipeline by constantly having a recruiting presence in our local market by getting involved in networking events, user groups, or by just encouraging our team members to get out and build their own relationships among friends. We’ll regularly troll user groups looking for people talking about the same types of ideas that we value as a team. Or, we’ll post our open positions to LinkedIn and Twitter which allows us to instantly reach out to former colleagues who may be in the market for a change. The goal is to constantly be building a pipeline of great candidates that is ready to draw on whenever a position opens up.

Know Your Gaps (And How to Fill Them)HowToBuildTheRightTeam

At the beginning of each year, we make a list of the skills we have on our team and the skills we need…i.e., our ‘gaps’ for the more business savvy amongst us. The result is a list of skills that we know we need to get better at in the coming year, or that are missing entirely from our team. What’s interesting is that the vast majority of our gaps tend to be very niche skills rather than full-blown positions. For example, rather than ‘DBA’ we may list ‘SQL Server performance tuning’ as a gap. But unless we think our team of less than 6 can support a ‘Senior SQL Server Performance Tuning Specialist’ we’re not likely to be hiring it as a full-time position anytime soon. That leaves us with three options:

  1. Grow those skills in our existing team through training and education.
  2. Temporarily bring those skills in from outside through a consulting engagement.
  3. Find a candidate for an existing position who also happens to bring those skills to the table.

Finding a candidate who already has those skills can be a huge win, arguably even more so than growing them in-house since the incoming candidate presumably has real-world experience putting those skills to the test. But how do you find such a candidate? By looking at those who are already in your pipeline.

Imagine that you have an open Software Developer position. Now imagine that you have two equally skilled candidates applying for that same position. Both have several years of experience with the platform that you’re currently using and both have logged enough hours in your domain to wield the arcane terminology of your industry like a second language. However, one candidate worked to improve the performance of a large SQL Server backed application at his last job by tracking down multiple bottlenecks between the application code and the database. Remembering our skillset gaps from above the choice becomes clear. By hiring a developer who already has those skills not only do we fill an open position, but we also fill one of our gaps with someone who can share her experience with the rest of the team.

Don’t Hire Yourself

Let me be abundantly clear, in a team-oriented field like software development fit trumps all. How someone’s personality fits in with the dynamic of your team, regardless of how amazingly talented they may be, is the single biggest factor as to whether or not they’ll be successful. However, just because you’re hiring for someone that fits in well with your team, doesn’t mean that you want your very own Mini-Me.

One of the biggest results of the rapid evolution of our field is that there are now tons of moving parts to any software project and countless ways to handle each of them. Odds are that you’ve developed some pretty strong opinions about the best way to do each piece and, odds are, you’ll gravitate towards others who share those same opinions. Because, if we’re really honest with ourselves, we tend to believe that our opinions are correct by the virtue of them being our opinions. Hiring someone who shares those opinions can have some great advantages as long as we remember this: those that share our same opinions about techniques and technologies will inevitably share our same blind spots. This is true whether those blind spots are confirmation biases about a given platform, ignorance of emerging alternatives, or just misunderstandings about how an alternative technology works. Don’t perpetuate those same blind spots by hiring them again.

Summary

In a knowledge worker industry there is no single greater advantage that you can give to your team than to infuse them with good people. Why not approach this task with the same rigorous thought and attention to detail that you expect each member of your team to bring to their own tasks?

No deadline. No ship. It’s that simple.

When I was a kid, my big sister and I were addicted to a show called “Out of This World”.  The show revolved around a Evie, a young girl with an alien for an estranged father, who could freeze time simply by pressing her index fingers together.  I don’t have to tell you that this is the type of concept that takes hold in the mind of an 8 year old and never lets go.  I also don’t have to tell you that I spent countless hours in my room pressing my fingers together hoping that ‘maybe this time’ time would freeze for me.

NoDeadlineNoShip

As I’ve gotten older, obviously I’ve realized the fallacy of this idea.  The idea that a race of aliens (the Antareuns, I believe) who are capable of freezing time could ever develop interstellar travel is ludicrous.

You see, interstellar travel would be a huge technological achievement, even for the race of extra-terrestrial swingers that existed in the show.  An achievement so large, in fact, that it could have only been wrought by the constant pressure of deadlines.  The problem, however, is that deadlines and time pressure would be meaningless to a race that could freeze time on a whim.  Why march towards a ship date when you can just freeze time until it’s ready?  What forces the tradeoff between delivery and functionality when you can simply freeze time until all of the functionality is done?  You see, as technologically advanced as the Antareuns were they lacked one crucial piece of knowledge that we learned in software long ago:  if you don’t have a deadline, you’ll never ship.

Without the pressure of a hard deadline features will creep, schedules will slip and a released product yours will never be.  Part of the reasoning behind this comes back to an idea known as Parkinson’s Law.  Parkinson’s Law succinctly states: Work expands so as to fill the time available for its completion.  What this means in a nutshell is that regardless of the true time required for a task, however much time you schedule for the task is how long that task will take.  Do you have a 1 week feature on the schedule for 2 weeks?  Then that feature will take 2 weeks.  How about that 30 minute meeting scheduled for 1 hour?  Congratulations, you just bought yourself a 1 hour meeting.  Like water, any task will invariably expand to fill the time allotted for it.

So what happens when you have a task without a deadline?  Then that task has an infinite amount of time allotted for it, and thus, that task will never be completed.  If you want to ship your product then you have to set a deadline.  No, your product won’t be done at arrival of your deadline.  It won’t have all of the bells and whistles you so desperately believe that your customers need and it won’t have that last 0.999% of polish that it would be unthinkable to release without.  However, guess what: your competitor’s product won’t be done yet either but it’ll already be in the market.  And if their product is all your customers are going to see, then all of the polish in the world won’t save you.