How to manage projects in startups.
I almost wrote this article in our startup’s wiki as a guideline on how we think about projects.
However, after some thinking, I put it here, generalized it, and added a bit more information.
First, before diving into the details, let me tell you two extremes we want to avoid.
Classical waterfall
Let’s gather ALL requirements. Next, let’s do ALL design. Next, let’s do ALL coding… and so on.
I really hope that you understand how flawed this is. Any changes (in requirements, understanding, unknowns) throw this whole thing into complete chaos.
Cowboy coding
Let’s ignore any planning, any design. It’s Agile, baby. YOLO, etc.
These guys usually start fast and gradually grind to a halt because typing furiously rarely solves complex problems and doesn’t promote quality.
Where do we stand?
Over the years, we leaned heavily into the Agile side ( with a strong allergy to ossified SCRUM).
The rest of the article describes how I think about all of this. However, I will use my standard caution. Nothing is written in stone. This is more of a narrative than the absolute precise recipe. You CAN’T manage a project purely by following some written procedure. Software is messy; human relations are even messier. These two things intersect when you run the project. You will need to improvise when things don’t go by the plan.
Responsibilities
This one could be quite controversial.
We do centralize A LOT of responsibility and ownership (read: “power to make decisions”) in the hands of technical leaders.
Usually, such a person can be responsible for
- prototype & design
- planning & controlling that the project is on track
- tasks assignment
- some level of implementation
The positive thing is that you literally have a person who holds the whole project in their head. As a result, instead of having a big meeting inviting multiple parties, one person can have the most answers and make many decisions. And this allows to move forward fast.
The downside is that it’s not trivial to do (a person needs to be good with both the technical side and management). It takes a lot of energy to do it well.
Also, it may not jive well with people who believe that good decisions only come from groups. (BTW. Don’t get me wrong, this person doesn’t have to singlehandedly come up with all ideas. However, it’s that person’s responsibility to synthesize everything from the group and make it an actionable plan).
Project stages overview
The best picture I found that resembles what we do is this one (since it’s not mine, I have to insert the link vs. just putting it here).
Short summary. There are project several stages:
- Initiation (when you try to figure out what exactly you are doing).
- Design & Planning (when you figure out how to do it, what exactly will need to be done, who will do it, and so on).
- Execution (implementing, testing, fixing, and so on).
- Controlling (making sure that everything is on track).
- Closing (releasing it, including release notes, etc).
Each of these stages peaks and gradually fades. However, stages are not staggered one after another (like in Waterfall), but run concurrently.
A change to requirements can come up on the last day, the team can stumble upon some unknown which will require updates to a design, and so on. It’s normal to have these bumps. However, it is crucial for activities for each of these stages to trend down over time.
Initiation
First of all, no 20-page PRD’s.
A short story (not precisely about PRD, but close enough): I remember somebody wrote a ten-page testing plan and sent it to me for review. I started reading through it and quickly realized it was all smoke and mirrors. The useful part of these ten pages was literally a couple of paragraphs and a link to a set of test cases. Everything else was just useless fillers.
So, one of the first guiding principles — is “no fillers”. If you have just two paragraphs of information — write two paragraphs. If you need 15 minutes meeting, schedule a 15 minutes meeting. It doesn’t have to become a long-winded wiki page and a long meeting.
We usually have a call (or several short calls) to discuss and understand what needs to be done. This is done by a small group. A person who manages the project usually writes down the details and ensures people are on the same page. These details are reasonably high level —the problem we are trying to solve, some high-level guardrails (to not overextend what we are trying to solve).
The main goal is to be lightweight, with just enough documentation to ensure that everybody is on the same, trying to be roughly right (vs precisely wrong).
As we go through the project, we usually uncover new questions, new sub-requirements, and new important details, which we often incorporate into the original document (if they are critical enough). We may decide to skip smaller details, which can go into a specific ticket or sometimes communicated directly.
Second guideline principle. Overcommunicate critical things. And do just enough communication for minutia.
For example, I could be repeating the project's goal and deadlines often. However, some small aspects of some code will be mentioned once in some ticket and that’s it.
Design & Planning
We usually can figure out the T-shirt size of the project quite fast. You just get several technically senior people in a room and talk through the project to get a feeling.
We don’t do estimates. First of all, Estimates always fail. Secondly, even if you believe in estimates and want to have any level of precision of estimates, it starts taking not a trivial amount of time. As a result, having these more precise (than T-shirt size) estimates provides a small amount of value while costing quite a lot. (I am aware that it’s not going to fly in a bigger organization. Well… Maybe this is one of the reasons why small startups can often run circles around bigger companies in product development).
For small and less risky projects, the design & planning phase could be extremely anti-climatic. It could be one person writing up a wiki page with a high-level design, breaking it down to several JIRA tickets (yeah-yeah… I am not a fan of JIRA, but whatever). And handing it over to the team to work on.
For more complex projects, we usually go through prototyping, come up with several alternative approaches, and have a discussion about these approaches, the pros and cons, and so on. Again, this is done by a small group.
It’s very common to have to go back to the drawing board several times between discussions until we figure out the approach with which we are happy (or at least content about )
BTW. I strongly believe that architecture is not only about drawing boxes but mostly about figuring out and comparing options.
I think this concentration on options and comparison is quite different from a lot of organizations where I worked (where in the best case, only one option is presented, and in the worst case, it’s not even presented but taken for granted because a person with a big title drew it). This is probably another of our guiding principles — invest substantial time in figuring out a good option (before starting building).
BTW. This could be perceived as anti-Agile. Agile approach would probably concentrate on evolving into the best option (BTW, which we also do after things are released and we have some miles on it).
Ultimately, when the overall approach is chosen, everything is broken down into smaller chewable tasks. At that moment, the project kicked off in earnest (with several meetings to go over what needed to be done, the design, and the choices that were made), so the team understood the goal, timeline, and tasks. And this one is done with everybody who will be involved.
Usually, we do just enough planning. It should include probably 80% of tasks (by volume), and enough definition for people to be able to wrap their heads around it. However, as we proceed forward, we define smaller details around specific tasks and so on.
How much architecture is enough?
I will say two controversial things.
I really like a sentence: if the architecture is done well, you can literally see(imagine) the code (that will implement it).
That being said, we don’t do this. We do enough architecture for each level. If we are talking about several components, we explain how they interact, what are the interfaces, and so on. And leave the next level of architecture to be resolved a bit later (when people will start working on it).
There are two reasons for the idiosyncrasy in my head:
- Not pushing down all architectural decisions gives more freedom for more junior people to exercise their mental muscles (instead of following extremely prescriptive design)
- Also, this approach ends up being more Agile. Things do change during project execution and creating extremely prescriptive architecture upfront may be problematic because new requirements or unknowns won’t fit well and will require substantial rework (often making it obsolete really fast).
The truth is if you know EXACTLY what you are doing, the architecture should be more well-defined. If you are working on something new, it should be more flexible, concentrating on the risky items.
Execution & Controlling
Execution and controlling come hand-in-hand.
There is an absolutely unglamorous job of assigning tickets, ensuring that people work on the most critical items, chunking big tasks into smaller tasks, and checking whether anybody is stuck or hit some bottlenecks.
And here, several guidelines
- work on the most critical items first
- integrate as early as possible (in extreme following Thin Line Through pattern)
- test critical things as early as possible
- keeping an eye on whether things are on track
- break down big items into smaller ones (even if they are already in flight).
This is usually a highly messy part of the project. This is often the heaviest phase, with most things going sideways.
A lot of energy is spent on figuring out how to handle all these exceptions that come up, pushing the information to the right places, and driving down decision-making about these new things.
It’s extremely useful to be hands-on to dive in and surgically help in one place or another.
My take on it. A good software architect is gold. And a good project driver (who drags the project forward) is worth platinum. Let me use the same word again: the project must be dragged forward most of the time. If you let the project just flow forward naturally, it will take orders of magnitude more effort and calendar time (additional reading material on this subject — Parkinson’s law).
Closing
As a project wraps up, there is usually a flurry of activity. At some point in the project life, your default answer should become “No.” No new requirements, no improvement to architecture, and no bells and whistles.
It should be purely a drive toward getting it over the finish line. Everything that could be postponed should be postponed.
Generally, you should be prioritizing all the time. However, it should become incredibly aggressive closer to the end, leaving almost no wiggle room.
Standard problems
There are several standard problems that happen again and again on the projects.
We are running behind.
First of all, I use green/yellow/red zone categorization. If you are entering a yellow zone, it’s better to communicate that and start actively solving it. If you enter the red zone, it’s time to make complex and painful decisions.
If the project is behind, our first (preferred) approach is to reduce the scope and push out all the bells and whistles of the project.
On the one hand, we try to deliver the project on time and put a lot of effort into it. On the other hand, you can’t fight physics. Sometimes, for one reason or another, the project doesn’t fit, and you can’t cut the scope anymore, and in such cases, it’s important to discuss/communicate this as early as possible.
This is way more complex than we thought.
Sometimes, the thing looks trivial from a high level, but it is inherently complex. Maybe you need to handle some time/date information, and it explodes in your face because of different time zones, leap years, date/time formatting, etc.
Again, the standard thing for us is to try to build something small first (with limited scope) and just make sure we don’t paint ourselves in the corner.
Second reaction: should we step back and evaluate other options? Sometimes, we could have chosen a suboptimal option, and another option would not have this problem.
Don’t squeeze QA out.
If the project is running late, everything often shifts to the right (timewise), and one of the last big activities on the list (QA) gets squeezed out.
It’s a bad idea from multiple perspectives.
First of all, QA should be involved early. Secondly, it’s a bad idea to compromise quality. As a result, the project should allocate a sane amount of time to QA activities. (BTW. On one hand, I am a big proponent of automated testing. On the other hand, tons and tons of things that I worked on require a non-trivial amount of manual testing and having a person in the loop).
Summary
Man… It ended up way more text than I had hoped for. And it still touches only the most critical aspects.
I think if I step back, pretty much we can summarize a lot of things like that:
- Do just enough to be able to move forward without tripping over ourselves
- One person should be driving the project from the beginning to the end.
- Concentrate on choosing a better option rather than driving forward full-speed with a problematic option.
- Making sure that everybody is in the loop on where we are going
- Routine check whether the project is on track.
- Cut scope, reevaluate options first, and move target dates only as a last approach.
I do realize that it ends up being a collection of different pieces of advice with a very lightweight structure around it. And I think this is exactly what we are targeting. We want to get projects out fast and with high quality. As a result, we try to cut a lot of stuff out of the process to keep it lightweight and flexible. However, it requires people operating in this environment to be extremely good.