Good project management is one of the most underrated things in software. It’s normal to take the view that project managers exist to hound people and update JIRA. Yet, most projects are complicated and have a ton of moving pieces. The wheels don’t stay on the bus; nothing works together. Actually getting stuff integrated is the hard part, not something that happens.
To get most systems working as a whole takes a ton of time and coordination. This is most obvious when it’s encoded as an API contract. There are lots of dependencies that don’t exist this way. For example, operations have a dependency on working software being in their hands. There isn’t an API for this but there is a contract and somebody needs to make sure that all the conditions of it are being met. Also, stuff needs to get done usually quickly and without enough money. As an engineer, it’s tempting to say it’ll be done when it’s done but to make money you need your return on investment to be higher than the cost of capital. Doing this means understanding the chances of schedules slipping and the risk of it happening.
Every software project carries risk with it. If you are developing something new by definition it hasn’t been done before. If it had been you could use already existing code and be done with the whole thing. That means that there is a degree of uncertainty that exists with new development work. One of the major goals of project management is reducing that uncertainty as much as possible and making it as easy to tell when things go off the rails. Generally speaking, the goal is to avoid status that is green right up until the last minute when everything crashes. This is one of the hardest parts of being a project manager because it’s as much about politics as it about getting the answer.
Breaking down Tasks
Work is usually broken down into the smallest possible increment. This is done to reduce risk. Small tasks are simpler to understand than large ones. This is useful for communicating status to others and it makes it easy to know what needs to be done. The problem with large tasks is they aren’t super tractable and an enormous amount of brainpower has to go into figuring out what’s next. When you are in a state of actually getting things done you don’t have to think about what’s next or the logistics of the whole project.
There is uncertainty with every software project. This means breaking things down isn’t always immediately possible. The solution is to build a prototype of the project. This can be super hacky as long as it is a working solution. It’s better to make it in such a way that it’s done by hand, so no one tries to call the project done and go to production with a prototype. The key thing is it provides an approach for building the final system. Once enough work is done to define a usable approach and create an RFC you can stop prototyping and begin work.
It is easier to make changes when a project is beginning and everything is new. This means that as much work as possible to reduce risk should be done upfront. Usually, this means building the riskiest part of the project first. A couple of places to look for risk is with technologies or ideas that are new and interfaces that exist with other tools. Both of those have a high possibility of going wrong. The first one from lack of knowledge and the second because outside systems are less understood than what you are in every day.
Some of the risks that come with new technology can be mitigated with prototypes. Yet, it’s tough to know how a piece of technology will behave in production until it’s in production. The easiest way to avoid this risk is to choose boring technology. Sometimes though what you are building is only possible because of new technology. If that is the case then prototype as much as you can with the technology. Investing even more in observability can help with debugging when things go wrong.
Integration risk on the other hand pretty much exists in every project. Making systems play nicely together has a ton of failure modes. API first development is a way of forcing you to think about those integration points early on for systems that are downstream of you. Often when working with systems upstream there is a need for doing some data translation. This is a frequent source of performance issues so it’s worth taking more time
When you are figuring out how to do a task it worth finding the simplest way to get to the answer in the beginning. From there you can iterate and spend more time figuring out what things should look like. Making sure everything fits together is simple to do when a project is starting but it’s hard to make changes to large amounts of code. Once a project has users changes become even more difficult.
Telling people how things are going and what is available is critical for a project to be successful. It doesn’t matter if something is completely superior to every alternative if no one knows about it. Communication is also an issue when things are getting built, especially when you need others to help. In theory, you should be able to use an API and some documentation for everything. In practice talking with other people can be the only way to get a good answer. In the early stages of the project, communication is even more important inside large organizations. Executive sponsors want to know how things are going and other teams need to know how their timelines will have to be adjusted to make things work. Early customers need to know when features are ready to be used. All of this makes it necessary to figure out who the different stakeholders are and set up a regular schedule for communicating with them.
The amount that you talk to different groups will vary depending on what is being worked on. You want to make sure that you are building something that customers want and you understand what they need. For business success talking with customers and making sure that you meet their needs is critical. If people don’t use what you are building then there isn’t a point in making something in a business.
Executive sponsors are needed to keep a project funded. They also play an important role in dealing with internal roadblocks and other teams that aren’t willing to help. You usually want to keep them in the loop about what is going on at a high level. Also, don’t be afraid to ask for help with a specific thing. If something is an executive’s pet project they want to help get it done. You can use them to make introductions or remove political roadblocks.
Once you’ve figured out who your stakeholders are you’ll want to set up a regular schedule for communicating with them. Communication can be async like email updates or slack messages but there’s a decent chance you’re also going to have to have meetings as well. Good writing that is distributed regularly reduces the number of meetings that you need to have. Depending on how involved they are check-ins should occur between once a week to once a month. Going much longer than a month is theoretically feasible but in practice is a little too far into the range of out of sight out of mind.
Getting things done is necessary for any project to deliver. That sounds super obvious but actually doing it isn’t easy. The problem usually comes from poor prioritization. Having many priorities is much less efficient than working on one thing at a time.
Context switching imposes significant costs. This means a significant part of managing a project is minimizing how often it has to happen. The goal is to be working on a single task at a time which requires being ruthless about prioritization. If you are getting the response that two things are a priority you need some way to rank them against each other.
This isn’t only for big tasks but also smaller deliverables. Ideally, a person is only working on one thing at a time. Multiple priorities require more juggling. It usually also means more people are asking for updates. Even in an ideal world where there is a project manager to run interference some stuff slips through.
If you have 10 things as a priority it’s the same as having nothing as a priority. You want to have a single major goal that is being worked on. Realistically you should limit to at most three priorities since it can be hard to drive consensus on what the single major goal looks like. If you are looking at a short enough time horizon (a day to a week) it’s still possible to get down to the single highest priority thing.
At some point with everything that you are working on it’ll be good enough. This doesn’t necessarily mean perfect but it does mean that it’s usable and you can put it in the hands of users. Getting to this point rapidly is needed to get real feedback from users.
Speed in finishing tasks has tremendous value. This is especially true in large organizations. Having a reputation for actually getting things done tends to result in more interesting work heading your way. While having a high quality is critical there actually isn’t a direct tradeoff between speed and quality. Automating tests, builds and infrastructure can go a long way towards making a team faster and creates higher quality.
If your team stays focused on delivery speed for a long enough period. Eventually, automation will have to happen. Crossing over this bridge is the key to truly delivering high-quality software. While this transition is happening quality can suffer and things will seem worse. Coming out on the other side of this is worth it though for the long term health of the product.
Also if you solve a burning problem for people they will forgive rough edges. If you don’t solve a burning problem for people the most likely result is that what you build won’t be used at all. The only real exception to that is if you have executive buy in to push your project. However, that is the worst way to get people to use what you have built. If you’ve built something and people aren’t coming you need to talk to your customers more and figure out what they want.
As Steve Jobs said real artists ship. Shipping is the only way to know if what is being done has any value. Project management and making sure that things ship isn’t easy. Keeping people coordinated and delivering on time while making users happy is much rarer than it should be. Delivering requires grit and keeping organized.
Helping a team maintain flow and figuring out which things are at risk of getting stuck is an art form. It’s worth getting good at but it takes time and practice. Ultimately the only way to get good at shipping is to ship working things, now go make something great!