 Hello everyone and thank you for joining me for this webinar. I'm very happy to be here and I want to say big thanks to ProtoSchool for inviting me to do this talk. My topic for today is my favorite one, non-functional requirements. What are those? Why are they important for us as product managers and how we can manage them effectively? A little bit about the agenda today. We're going to start with a brief overview of the topic and then dive into specific non-functional requirements like availability, performance and scalability. Then I'll cover how do we balance such requirements and how to find the right level of investment. And finally we're going to wrap up this topic. Before getting into all of this, just a little bit about myself. My name is Emil, I'm coming from Sofia, Bulgaria and I'm the Senior Product Manager at Coursera. I'm responsible for one of the products focused on innovative hands-on learning experience and a big part of the product lies on the technical side of things. I have more than 8 years leading engineering teams doing all kinds of applications like software as a service, mobile technologies and various web applications. If you want to get in touch with me after the talk, I'm easily accessible on LinkedIn and would love to hear your questions or thoughts on what we are discussing today. So first, what are non-functional requirements? I'll give you the textbook definition by Wikipedia and then some examples to make it more clear. A non-functional requirement or NFR is a requirement that specifies criteria that can be used to judge the operation of a system rather than specific behaviors. Let's say our product is a car, a very simplistic and maybe silly example, but I think it can illustrate most of the concepts that we are going to go over today. Non-functional requirements can be identified by the verb be. A car can be fast, be safe or be cheap. On the other side, the functional requirements are those that a car does. It navigates, entertains and maybe does your caravan. Non-functional requirements are frequently referred as quality attributes and are usually manifested in the system architecture of your product. Let's see some examples of non-functional requirements. They can be broken down into groups. Execution qualities which are observed during the runtime of your product like safety, usability and performance. And evolution qualities which are embedded in the architecture or the beaut of your product like testability, portability or extensibility. There are more than 60 other examples that you can find out there and some of them would be relevant to your product. Some of them would not. Some would be more relevant than the others. So we need to find the right balance between all of them. But before that, why are NFR important at all? First, it's very easy to overlook them. They usually are not part of the conversations you're having with your customers until it's too late to be functioned. No customer will start a conversation with you with, I really need a product which is highly available. They would rather need a product that helps them with their jobs to be done. That's until your product is not working in the most important moment for them. Then it's also easy to over-engineer or over-invest in non-functional requirements. I have been part of products where a great amount of time, effort and resources were spent in making them robust, high-performing and secure to find out that no customer wants to use it. Finally, NFRs are hard to be observed in most cases, again until it's too late and you're observing on production. While developing the product, you cannot help open the homepage or start the application and check how secure it is or how many concurrent users it can handle. It requires deliberate attention and strategy in order to be able to assess the product's readiness to cover those requirements. This makes it easy to discover problems only when it's too late and at this stage the team might not be set up to address them successfully. Now let's go over a few non-functional requirements, which at least in my experience pop up most frequently in order to better understand what are NFRs and how to work with them. Starting with availability. The definition of availability is the probability that a system will operate successfully at a given point in time when used under given conditions and in an ideal support environment. If we get back to the car example, what are the chances of you being able to use your car when you need it? In your family of two adults with one family car, statistically there is a 50% chance that your car won't be there when you need it. That's the availability of your car and it's very simple with the availability of your web application as well. What are the chances of your website not behaving as expected? Availability is measured by dividing the total uptime by the sum of the uptime and the downtime or the whole period, usually excluding the maintenance. In most cases, it's a number pretty close to one and it's represented in percentages. For the standard web application, anywhere between 99.9% and 99.99% would be considered a greater availability, resulting in only several hours of downtime per year. Achieving higher availability than that usually is associated with higher cost and more complicated system architecture which needs to be justified by your business case in order to make sense. There are certainly cases in which 99.99% or even higher availability is a requirement, maybe if you're building a software for spaceships or autonomous cars, but in most cases the time and resources spent in achieving it would better be spent on other non-functional requirements or implementing functional requirements. Moving on to reliability. Reliability is tightly connected to availability. It is defined as the probability that the system will operate for a specified time interval. Getting back to the car analogy, how often your car will not be available due to flat tire, regular maintenance, or your partner using it. It can be measured in different ways, but probably the most straightforward one is dividing the total time in service by the number of failures. Think about this. Availability speaks about the total amount of downtime you have for a year, for example. Availability speaks about how this downtime is distributed throughout this year. It can be one big chunk of downtime or multiple dispersed smaller downtimes. Depending on what your product is, one might be more favorable than the others. Consider your users having to make long synchronous operation with your product and even the smallest downtime will reset the long operation. This would virtually make it impossible to complete it at all. In this case, one bigger downtime followed by a big save time span can be favorable. Jumping to the next non-functional requirement, which is performance. This time, this is the time it takes to perform a certain operation. In our car analogy, this is probably the most intuitive one. What is your car's top speed, acceleration from 0 to 100 km per hour, torque, etc. Similar to that, your product will have different aspects of performance you might be interested in and things to measure. For a website, it might be the world time of your homepage. Even that has different aspects to be measured. The time it takes to submit a purchase order might be another thing you are interested in or the time it takes to process a credit card. Usually, we are measuring whether a certain percentage of your users falls below or above a given threshold. This is because it's usually hard and impractical to try to meet a performance goal for 100% of your users. Some of them would have older hardware, shake internet connection or running another computational intensive software. The product I work on in Coursera is a hands-on learning product which provides a virtual workspace to practice for our learning. A key performance matrix is the latency of the workspace connection or the delay measured in milliseconds between the learner interacting and the workspace acknowledging their command and vice versa. Setting the baseline in our case comes from what is the minimal delay that the human brain can recognize which is usually around 150 and 200 milliseconds. Everything below that doesn't really matter as our brains cannot catch it. Everything above that will feel chunky, irritating and when close to this threshold may even fall into the uncanny valley making the user experience really irritating without knowing why. Performance is probably one of the most subjective non-functional requirements as it's primary based on the user's perception and expectations. There are famous experiments showing that you can effectively improve the perception of the performance of a slow operation by distracting the user in some way in this way achieving improvement in your perceived performance without improving the operation itself which might be expensive or even impossible. Just consider that specific performance and times for achieving some operations which were perfectly okay 10 years ago in appropriate or even unacceptable especially when we were talking about browsing the web application or waiting for processing a credit card. The last non-functional requirement we will cover today is scalability. It measures how quickly a system can adapt to a significant change in the processing demands both up and down scale. Here is where my car analogy breaks down a little bit but there will be. In this case scalability would be how fast you work and provide transportation for me if our family car is busy. Scalability is much easier and arguably cheaper to achieve nowadays than 10 years ago of course with the rise of the cloud providers. With one movement of the slider you can double, quadruple or multiply by 100 the resources powering your application to handle a search in the traffic and then down scale it when you no longer live it. This can even be an automated process based on some triggers in your environment. What really exciting times you are living in. But your system needs to be architected in a scalable manner. Early design decisions can be the difference between easily scalable product and nearly impossible to scale product. The magnitude of the scalability matters as well. Different managers will work a whole new set of challenges to solve. So we need to think deliberately about the realistic amount of load that we expect now and probably down the road. One example from the past year from Coursera the Covid pandemic forced many people to turn to online education to improve their current skills switch careers or simply learn something new while staying at home. This caused unprecedented surges in the traffic that was sustained for months and was unimaginable just a few months ago. Although our infrastructure team definitely had some sleepless nights architecting the system in a way that it can easily make use of additional resources that were spawned into the data center made it possible to serve all those learners who were in demand for education. We handled five times built in 2020 without major refactoring or changes in the system which wouldn't happen if we haven't started with this end goal in mind. Hopefully by now you're seeing a common pattern for working with non-functional requirements. First we need to understand how they are defined and especially in the context of our product because scalability for one product can be totally different from scalability for another one. While some products would gradually increase their needs for resources over time others might have certain spikes in the traffic that completely go away after a week or day or even minutes. Those two scenarios will go for different scalability strategies and probably for different system architecture decisions that we need to take. Then we define how to measure it and put in place measurement mechanisms. As we solve with the performance different products will focus on different aspects of their performance for product targeting carriers and for internet connection, smaller traffic volume would be very important. While for ours this might be not important at all. Third we need to set the right targets based on our users and business needs. The level of security needed for a blog would be completely different from the requirements for a system managing health records. And finally we take actions in order to achieve the targets we have set. Following this scheme, you can address most of the non-functional requirements you need to tackle. Sounds easy, but taking actions to achieve your goals at the right time is not always the most obvious thing to do. So, now I want to briefly talk about a concept called technical depth which often goes hand in hand with non-functional requirements. Technical depth happens when we deliberately cut corners and take shortcuts in the implementation which results in faster feature development. However, this process accumulates deficiencies in the product which at some point can slow down the feature development. It can also limit the capabilities of the product to self-users and result in product not meeting other non-functional requirements like security, accessibility and many others. Technical depth is a powerful way to progress fast when needed, but every team needs to have a deliberate strategy for paying back that technical depth on a regular basis, so the depth is manageable. In the context of non-functional requirements, technical depth is important because accumulating it usually results in shortcomings when meeting those requirements. So, how do we know when to invest in non-functional requirements and how to prioritize them? Let's take a look at this diagram which hopefully will give us some answers. On the vertical axis we have how mature our product is and on the horizontal axis we have the time. In green are how we are tracking with functional requirements and in yellow we have how we are tracking with non-functional requirements. In blue we have the user's expectations for our product. Where the functional requirements meet the expectations of the users, we would call this point the product market feedpoint. Generally, unless non-functional requirements are a key value proposition for your product most probably it won't make sense for you to invest in non-functional requirements before the product market feedpoint. This means we would better invest our effort in making sure that the product does the right things and later when you know that you have the right product you can start investing into addressing non-functional requirements. However, this doesn't mean that we can completely ignore NFRs doing that may mean that product should be completely rewritten at later stage. On the contrary we always start with the end go in mind, keep our future non-functional requirements aside and make sure that even though we are not investing in them right now we are laying the foundation for a scalable performant and highly available product. If we don't start our product with these goals in mind chances are we will have to really hard we will have really hard time addressing them at later stage. There are some notable exceptions to this rule of thumb. If NFRs will be a part of your main value proposition you want to make sure that those are addressed even as part of the MVP. For example if you are building the fastest search engine in the world like Google did this is the essence of your product so naturally performance should be your main focus. Another exception would be if you are legally binded to be compliant with the regulations. For example when managing and storing great cars you need to be PCI compliant which will come at a serious cost for your engineering team. You can't afford not to do it from day 0. If possible I'll try to outsource or defer search features at the least latest possible point in order to allow me to focus on working on my main value proposition. But if this is your main value prop obviously this might not be an option. So to sum up everything that we have talked so far there is no one size fits our approach. The right non-functional requirements to focus on and the right targets and goals to set will greatly vary on your product and the business needs your serving grade. The point here is to be conscious about those requirements and have a plan for how and when to address them. Second there is no free lunch and when it comes to non-functional requirements and in general. Higher targets always come at a higher cost be it time or money and most often both. Overinvesting will result in lost opportunity so make sure you understand how your targets are associated with business impact. Lowering the targets can be dangerous for your business as well. One example from a previous team that I was part of. We were owning the shopping cart of our website and our company and this was the mainstream of the mainstream of revenue for the company. We had a very precise our amount lost for every minute in which the shopping cart or the website itself is not working. This can easily quantify the amount of money the company uses on early basis and it can justify the investment in high availability and reliability of this component. Using a similar approach you can try to associate the effort and the investment that you need to do in non-functional requirements with the impact that this requirement will have on your business or your users. And to make sure you're approaching your non-functional requirements the right way the engineers are your best partners. Work with them in order to provide them with the product context about the business objectives and the impacts that non-functional requirements will have on your product. And don't miss the opportunity for them to inform you about what is possible from a technical point of view and what would be the cost. After all, a product being performant, secure and reliable engineering doing their job the right way. It needs nurturing time and focus at the right doses. With that I want to thank you for staying with me. I hope that this content has been useful and we'll help you in making the right trade-offs between functional and non-functional requirements. Having that understanding has been helping me throughout the years to have healthy and constructive conversations with engineers I work with and better what is going to be our future for the product. I wish you tons of success in building your amazing products. Goodbye!