In this post, I will explore a rather elusive idea of 'productivity' in software development – productivity of individuals and of software development teams, with the latter being more relevant. Why? Simply because teams deliver software – teams with people who have a diverse set of skills, varied backgrounds, as well as different individual strengths and weaknesses.
Let me begin by saying that productivity is hard to define in the context of software. 'If 5 guys take 10 days to build a wall, how much time will 10 guys take to build the same wall?' kind of primary school math problem doesn't apply here. In fact, in his famous book, The Mythical Man-Month, Fred Brooks said that adding people late in the project delays it even further! One of the reasons for such counter-intuitive behavior is communication (or noise created by too many channels of communication). Communication plays an important part in how productive a team might be. For example, a team of 10 people has 10*9 or 90 channels of communication. Add one more and that number goes up to 110. A twenty-person team, on the other hand, has 380 channels of communication – that is doubling the number of people has quadrupled the number of possible (mis) communication channels. This is a trait that is peculiar to the software industry. Many of the attributes of software and its processes deteriorate at an ever-increasing rate. Bugs, test cases, and general complexity – all grow at an increasing rate.
The Mythical Man-Month is the most widely read and quoted book in the software engineering world – from posts such as this one to books and conference keynotes. It is also a book whose principles are relentlessly and passionately NOT followed in practice!
There are some metrics that measure individual productivity – the most popular one being Lines of Code or LOC/day written by a developer. By lines of code, in this context, we mean lines of tested, production-ready code. Many studies have shown that this tends to average around 20-25 lines per developer/day. Fred Brooks' own studies put this number at 10 LOC.
In some special cases, such as embedded systems, a more productive programmer is the one who writes a lesser number of lines of code, because of lack of resources such as memory. Therefore, measuring individual productivity by using such metrics is pointless.
In the case of teams, we can measure their output by the number of features, functions, or stories delivered in successive periods of equal length. Earlier attempts to formalize these using empirical techniques into Functions Points, Feature Points, COCOMO, etc. – have all lost their shine and seem to have been abandoned. The popular metric nowadays is called a story point. The number of story points delivered to production during a 'sprint' represents the team's productivity and is called 'velocity'. Please note that the term velocity always applies to a team and not to any individual, as per the principles of Agile. The trouble with this number is that the assignment of points to a story is largely arbitrary and relative. But if one uses a consistent way, the points may make sense as far as a project/team is concerned. For longer projects (10+ sprints), the team velocity can be reasonably approximated if a consistent way of assigning complexity (story points) to stories is being followed.
Now, here is a question – if we can't measure productivity in any objective manner, how can we improve it? This may seem like a meaningless pursuit, but let me assure it is not. Software development is not about being efficient but being effective. We can increase the effectiveness of individuals and teams over a period so that we can set up a reasonably predictable cadence of delivery.
What are the factors that affect productivity or effectiveness in the context of Scrum/Agile sprint-based processes?
Interrupting teams or individual contributors, i.e., developers, designers, and quality guys. While all the sprint-based processes encourage a SINGLE sync-up scrum meeting per day, it is common for teams and individuals to be interrupted for various things – ranging from status requests from multiple stakeholders – technical leads, project managers, manager's managers, product owners/customers, account managers, and so on. On many days, I have seen 2-3 full team meetings to assess the status of a troublesome story. Such interruptions add no value – the status is unlikely to have changed between the scrum meeting and the middle of the workday. It is better to regroup at the end of the day to re-assess the status and communicate with the clients. For communicating with the client, the whole team is probably not required. But it has become customary for the entire team to have a meeting with the client (in the Indian context, with an overseas client), sometimes every day.
Team members interrupting each other for some clarifications. While these are unavoidable, team members must figure out a protocol – here is where the tech leads and project managers can play a key role in bringing some sort of order.
Software development requires immense concentration. When such interruptions happen, the flow gets disturbed and the person who is interrupted will invariably take 10-20 minutes to come back to the groove to pick up things from where they were left off. I would go as far as to say that individual contributors should put up 'do not disturb' signs at their workplace – and define a protocol for collaboration.
The team's objective should be that each member should spend at least 6 hours doing their core work – designing, coding, and testing. One hour can be set aside for team meetings and another hour for collaborative activity. If the target of 6 hours can be achieved, the productivity will go up significantly.
Scope changes during a sprint
For any agile/scrum model to work and be able to consistently deliver (and measure reasonably accurate velocity), it is important that every sprint is absolutely scope boxed – which means no changes to requirements and no new stories. All such things can be deferred for a few days.
Scope changes hit productivity twice over. Some team member must stop working on what was planned, switch the context, and learn the new requirement/change. All of these have an impact on the velocity of the current sprint. And when, in a future sprint, the story that was interrupted is taken up again, the team member must go through a mini learning curve.
Under pressure to deliver, developers might take shortcuts using poor practices, which will add technical debt (a euphemism for bad and unmaintainable code, which makes developers feel less guilty!). Technical debt always reduces future productivity and as more of it is added, akin to normal financial debt, technical debt increases at a compounding rate. After a while, team productivity begins to fall dramatically, until it reaches a point where no features can be added without breaking something else.
Lack of automation
Despite the availability of a wide range of tools that enable automation and enforcement of coding standards, software development teams and their managers refuse to take this up seriously. For example, in unit testing, it must be mandatory for code to be considered done. And this must be hooked to the check-procedures. It just happens that the developers are not used to writing unit test cases. In earlier sprints, the argument is that the stories are not stable and hence automation of unit tests should be done later. And later, the same bunch will tell you that now there are just too many unit test cases to be written and creating unit tests will be too time-consuming!
Adoption of a static code analyzer, automation unit and integration along with system-level testing are probably the two most important technical initiatives any software organization can take to improve productivity dramatically and sustainably. This is the foundation for continuous integration and deployment and other productivity enhancement programs.
Differences in skill levels of developers
As mentioned earlier, developers' individual capabilities can vary by a large order of magnitude. The weakest member of the team can bring down the overall velocity of the team – as his/her work must be double-checked or triple checked, builds broken by him/her must be fixed by other team members, and more. In other words, poorly skilled individual contributors reduce the productive time of the skilled ones. In most cases, removing an underperforming developer can increase the team’s productivity.
The adoption of new technologies for a project may also result in increased differences between the competence levels of individual contributors, as people learn at different speeds. This can have a serious impact on the overall team productivity.
Any non-trivial project will have several technical unknowns or grey areas. One uses so many third-party libraries and other artifacts with potential poor documentation, compatibility issues, etc. – that it is impossible to ascertain beforehand whether a specific library or a component will work as advertised in the context of the application under development. Therefore, the impact of these unknowns is often discovered very late in the development cycle.
While there is no silver bullet for handling technical unknowns, it is for the developers to be aware of these risks and provide adequate buffers for POCs during estimation. This requires an element of rigor on the part of the developers – they must anticipate the risks, be prepared with alternatives, and so on.
But this rarely happens – generally, in the middle of a sprint, a developer will throw in the towel and say that a new approach is required. This is one area where developers are directly responsible for low productivity. This makes stakeholders lose confidence in the development team, triggering multiple reviews in the solutions that are proposed in the future, which then starts eating into development time (see interruptions, above).
Technical unknowns may also be a result of developers not upgrading themselves on a regular basis. For this, developers are solely to blame; it is about time that developers treat software development as a serious profession like that of surgeons or lawyers. No lawyer or surgeon will be effective if they don't learn continuously.
Lastly, developers hate to admit that they don't know something or that they are wrong. This is a cultural issue. The fact is that no one can know everything in this industry – and individuals must be encouraged to come forward and say that they were wrong, or they got it wrong, without fear. The management should encourage such behavior and ask the right questions to evaluate when a developer's assessment is on thin ice!
The above list is not a comprehensive list of factors that have an impact on productivity. There are several seemingly obvious issues such as managing dependencies between teams that are almost always spread across different time zones, coordinating and managing communication, avoiding miscommunication – all of these must be tackled by the management and leadership teams.
The productivity of software teams is a complex topic. Every organization needs to figure the best way to improve productivity by fine-tuning its practices ranging from hiring and engineering processes, as well as by fostering a culture of excellence. In order to do this, several technical areas and cultural issues need to be addressed in a systematic and sustained manner.
Want the full infographic? Get it here!
Read other Extentia Blog posts here!