“A frog boiling in hot water.”

“‘Ball of spaghetti’ messes.”

“Death.”

Eric Miller, a staff software engineer, has quite a few animated metaphors for ignored non-functional requirements. Still, he has a point: if left unattended, NFRs can cause major problems in future code deployments. 

Miller and his team at church management software Church Community Builder consider NFRs to be “first-class citizens.” To start, traditional NFRs, like security and performance, are considered essential to development work, Miller said. They are built into the development process and require consensus before deploying features to production. Other NFRs are attached to functioning requirements so when those tickets are being addressed, those NFRs are as well.

But they are called non-functional for a reason. Sometimes NFRs are in conflict with functional requirements or aren’t relevant to the current project. Jason Waldrip, CTO at staffing solution company GigSmart, said engineers must put themselves in the shoes of stakeholders to ask, “Should I care?” If an extra week now will save time and money down the road, the answer is yes.

“Our focus often goes to what is right in front of us, but decisions made today in the code can impact how we work for months and years to come,” Waldrip said. We asked seven experts to share their insights into how to best prioritize non-functional requirements.

Tips for Prioritizing Non-Functional Requirements

  • Perform regular maintenance on components that you deem critical
  • Make sure you get team buy-in before deploying a feature to production
  • Code your NFRs by different priority levels, like "critical", "high", "medium" and "low"
  • Engineers should work with product managers to identify problems with an organization's NFRs
  • Define your organization's NFRs and clearly identify metrics you want to achieve with them

GigSmart

Jason Waldrip

CTO

jason waldrip

CTO Jason Waldrip compares NFRs to maintenance on a car. Sure, the bare minimum is cheap, but if you want the car to last, a little investment goes a long way. At staffing solution company GigSmart, he explains to stakeholders why addressing NFRs will result in better performance and productivity in the long run.

 

Why is it important to prioritize non-functional requirements throughout the development process? 

Non-functional requirements can be a tough sell to stakeholders outside of the development team and even sometimes to those in software development.

Throughout my career, I have on more than one occasion been described as a “code idealist,” due to how strongly I push for non-functional requirements to be given consideration and prioritized. Organizations are always looking to deliver value as fast and cost-effectively as possible, and when deadlines come looming NFRs are oftentimes the first place to look for cuts. 

In order to get buy-in and approval on NFRs as a software engineer, it is imperative to be able to put yourself in the shoes of various stakeholders and be able to answer the question of “Why do I care?” The answers to this question can vary by department, but in general, it boils down to advocating for long-term “ilities” across an organization. 

A common theme across them is a long-term benefit to the company. “Is buying a week now worth costing us a month down the road?” That is often the question I ask my team when we are discussing our roadmap and plans for the year. It is hard to do. Our focus often goes to what is right in front of us, but decisions made today in the code can impact how we work for months and years to come.

 

How do you prioritize each non-functional requirement? Who else is involved in this process? 

Focusing on NFRs should not be conflated with just working on things to make software engineers' lives easier but, instead, like taking your car to the shop for service. Sure, you can do the bare minimum and get out of there as quickly as possible with the lowest cost, and if you're planning on getting rid of the car in a year that's probably a fine strategy. But if you're planning on keeping the car for generations and want to avoid a massive overhaul or failure at some point, regular maintenance of critical components and services are absolutely recommended and required to do so. NFRs can and should be thought of in the same way.

 

Decisions made today in the code can impact how we work for months and years to come.”

 

In prioritizing NFRs, there can sometimes be trade-offs in which certain attributes either enhance or degrade others. How do you inform your decisions around what to prioritize and when?

Now the analogy of a car is helpful, but it takes more than just knowing that it's “recommended” oftentimes to convince people to invest in maintenance or upgrades. You have to put it in terms they can understand. So just like it is clear to everyone why having tires with enough tread to stop in a short amount of time is critical, it is important for software engineers to be able to explain how NFRs will result in confidence that the product is stable, future speed of production will be high and users will have a positive experience. If you can do this then you can confidently get support from your software engineer peers, product team members, finance and leadership team that working on NFRs is the right thing to do.

 

Church Community Builder, a division of Pushpay

Eric Miller

STAFF ENGINEER

eric miller

Eric Miller and his team hold weekly standups to address NFRs and upcoming work that might need special attention. While NFRs like security and performance are baked into the development process, NFRs like scalability and maintainability will get a consensus from the group on their priority in the current project at Church Community Builder.

 

Why is it important to prioritize non-functional requirements throughout the development process? 

Ignoring non-functional requirements is like slowly boiling a frog: if you ignore them too long, you end up in dangerously hot water. NFRs can often feel like they get in the way of functional progress, especially on smaller projects, but ignoring them leads to those “ball of spaghetti” messes no one wants to deal with.

One of the key NFRs we’ve focused on the past few years has been the performance of our software. A few years back, we began a code refactor of our monolith. The refactoring effort was desperately needed because our code base had become unwieldy and it was difficult to modify without breaking something. 

Unfortunately, as we began the months-long process of refactoring, all of our testing and goals were functional in nature, meaning if the software continued to function the same throughout the refactor, we shipped it. However, the performance was problematic. We tested on small datasets, not considering the fact that many of our customers’ data footprints had grown significantly since the code was written. 

We unwittingly introduced a large amount of inefficient queries as we attempted to accommodate greater reuse throughout the code base. Our server processing time skyrocketed, and we began to see intermittent outages as particular hosts would get overwhelmed by multiple simultaneous, long-running requests. We weren’t really aware of many of the issues until our customers started complaining about them. As the complaints grew, we decided to deploy a free trial of New Relic to gain insight into our production performance. Within hours, we saw with clarity just how inefficient things had become. It was a good reminder that performance requirements and constraints needed to be a first-class citizen alongside functional requirements in our development process.

 

We believe that some NFRs, like security and performance, are essential to all development work.”

 

How do you prioritize each non-functional requirement? Who else is involved in this process?

We believe that some NFRs, like security and performance, are essential to all development work. We’ve built them into our processes and require consensus before deploying a feature to production. For instance, we have performance tracking in place on our development playgrounds that give real-time performance feedback to developers as they work on a feature. These metrics are consolidated for peer review and require buy-in from both our development and infrastructure teams before work goes to production. Additionally, secure coding practices are typically handled through standards and practices built into our development methodology and code reviews.

Find out who's hiring.
See all Developer + Engineer jobs at top tech companies & startups
View 9642 Jobs

 

Other NFRs are not always relevant to every project we work on. To address those, we hold weekly standups with our site reliability engineers and our feature reliability developers to discuss upcoming work that may require special attention. Topics of conversation usually include issues of scalability, availability, privacy and maintainability from a cross-discipline perspective. 

Additionally, requirements around maintainability are handled at quarterly or annual planning meetings. We solicit feedback from stakeholders, estimate the work, prioritize it and decide what we’re going to get done for the next year on a quarterly basis.

 

In prioritizing NFRs, there can sometimes be trade-offs in which certain attributes either enhance or degrade others. How do you inform your decisions around what to prioritize and when?

When we have NFRs in conflict, we’ll typically get product management, software engineering and our SRE group in a room to investigate the trade-offs in detail. We look for false dichotomies, challenge preconceived notions, seek agreement on non-negotiables, detail risks, offer compromises and discuss solutions. With the right people in the room, a satisfactory solution always seems to present itself. We give higher priority to issues of security, and we favor solutions that meet the more immediate needs. We inconvenience ourselves rather than the customer, and we take a hard look at cost-to-value ratios.

 

Inspirant Group

Chris VanAvermaete

CHIEF TECHNOLOGY OFFICER

chris vanavermaete

In your opinion, why is it important to prioritize non-functional requirements throughout the development process?  

As an architect, I’ve always kept a placeholder for non-functional requirements to be completed before architecture or design tasks could be completed and encouraged continuous testing throughout the development process where possible. I have occasionally got bit by less-than-comprehensive NFRs that fail to take into account all use cases. 

For example, we built a system that was a series of microservices for inserting, updating and searching for records. The idea was that services would be used by both a user-centric web app for searches and updates and other systems that would invoke them through batch and real-time interfaces for inserts. We built the services, tested them using load-testing agents and determined that our system performance was both fast and scalable over what was needed. 

What we did not take into account is that while the system could handle a single transaction in less than 500 milliseconds as well as hundreds of transactions per second in parallel, most of the systems we integrated with would be sending hundreds of thousands of transactions per day into the system one at a time due to the nature of their mainframe batch technologies. While our load tests could push 100,000 transactions into the system in less than 10 minutes using multi-threading, it would take nearly 14 hours for the other systems to send in the transactions single-threaded. Fortunately, we discovered this during data load dress rehearsals and were able to build a process that would process the files on behalf of the other systems to meet timing needs.

 

I’ve always prioritized NFRs like I prioritize regular functional requirements.”

 

How do you prioritize each non-functional requirement? Who else is involved in this process? 

I’ve always prioritized NFRs like I prioritize regular functional requirements. Critical requirements are things the system can’t go live without and would damage the enterprise as a whole if not addressed, such as regulatory compliance or security requirements for systems that are outward-facing. 

High requirements are those that should not go live, but are more limited in scope to a certain user base and may have manual workarounds to address; this is normally about performance and scalability. 

Medium requirements tend to fall into the category of things that don’t comply with enterprise architecture guidelines and may affect total cost of ownership, supportability and maintainability. 

Low requirements are “nice-to-haves” that usually align with future technology directions or enterprise architecture next-gen initiatives that are not yet standards. All of these levels are important and implementation plans need to address each level, though not all may be implemented in a given release. Categorization of these levels is a joint effort by business stakeholders, product owners and managers and architects.

 

Related ReadingStop Arguing About Performance-Cost Tradeoffs

 

In prioritizing NFRs, there can sometimes be trade-offs in which certain attributes either enhance or degrade others. How do you inform your decisions around what to prioritize and when? 

By prioritizing the NFRs as noted above, you have a rough order of which requirements need to take precedence in the case of competition or constraints. Ultimately, when two very high requirements are conflicting, it’s usually the development or testing teams that need to quantify the trade-off. Then, it’s up to the architects and stakeholders to negotiate a reasonable compromise.

 

Versus Systems

Daniel Howard

DIRECTOR OF ENGINEERING

daniel howard

Why is it important to prioritize non-functional requirements throughout the development process? 

It all comes down to the user experience. You can have a ton of great features but still provide a terrible experience if they take forever to load, crash all the time or get hacked easily. You always prioritize things that will have the most significant impact, which might mean adding a new killer feature and improving response time or security.

When we were building out the first version of the Versus platform, we focused heavily on getting to a feature-complete state and then shipped the app without ever really testing performance under load. It was a huge relief to get the platform out the door, but then there was a very long period where we added no new functionality because everyone’s primary focus was on scalability. Now, load testing is woven tightly into our process.

 

We prioritize non-functional requirements the same way we prioritize features.”

 

How do you prioritize each non-functional requirement? Who else is involved in this process?

We prioritize non-functional requirements the same way we prioritize features. Each team has a grooming session before every sprint, where a product manager meets with engineers to prioritize work for the next cycle. At that point, feature requests are ranked alongside any NFRs that have arisen, and we generally end up with a mix of both in a given sprint. Larger non-functional initiatives may be broken out into their own projects with dedicated engineers.

I’d say the main difference between functional requirements and NFRs is that NFRs tend to originate from the engineering team rather than the product team, so they provide excellent opportunities for developers to be proactive in identifying problems and forming solutions. 

 

In prioritizing NFRs, there can sometimes be trade-offs in which certain attributes either enhance or degrade others. How do you identify and balance these types of trade-offs and how do they inform your decisions around what to prioritize and when?

Our software runs sweepstakes and free giveaways, which come with lots of legal restrictions. We need to know several things about the contestants to make sure they’re eligible to win, and when someone wins something big, there are special tax rules to follow. All of this can get in the way of us providing a streamlined UX design. In a certain sense, it’s easy to know where to strike the balance because we’re not going to do anything that breaks the law. It’s more about being creative within those guidelines and figuring out how to provide the best experience we can.

 

Fivetran

Aastha Kumar

SENIOR SOFTWARE ENGINEER

aastha kumar

Why is it important to prioritize non-functional requirements throughout the development process? 

Like many other software engineering professionals, I like to define the functional and non-functional requirements of the project when writing the project requirement document. Working in the tech industry for a few years now, I have learned that non-functional requirements, sometimes referred to as “quality requirements,” are equally as important as the functional requirements. Not prioritizing them may result in unusable software — even if your system delivers all the functional requirements right. 

Even though most engineers know the importance of attributes like software quality, performance, reliability, security and scalability, sometimes ambitious timelines and the pressure to deliver the project can result in ignoring non-functional requirements. As an engineer, I always thought of NFRs as implicit requirements and kept them in mind when developing software, but until recently, I considered them secondary to functional requirements.
 

Ambitious timelines and the pressure to deliver the project can result in ignoring non-functional requirements.”


I worked on a project that involved developing an API that provided data to all the internal systems at Fivetran. When developing the requirement document for that project, as always, I listed all the functional requirements in detail with a limited section describing the non-functional requirements. After completing all the functional requirements, I felt the system was ready and started testing. 

I quickly realized that sometimes the system takes more than 30 seconds to respond under heavy loads. Since the project catered data to all kinds of applications ranging from the user-facing websites, external APIs, long-running scheduled jobs to cron jobs that run every minute, a response time of 30 seconds was unacceptable to some of the applications. A cron job that runs every minute cannot use an API that takes 30 seconds to provide data. That was the moment I realized how important the performance was, because it made the system unusable for some of the applications. 

Even though the system met all the functional requirements, it was not ready to be pushed to production. I took a step back, spent some time thinking about the architecture and spent two weeks optimizing the system for the desired performance. That experience showed that if I concentrated equally on NFRs from the start, I would have delivered the project earlier.  

 

How do you prioritize each non-functional requirement? Who else is involved in this process?

Prioritizing all the NFRs are very important. Not prioritizing any one of them could result in an unusable system. I believe the entire engineering team working on the software should be involved in prioritizing the NFRs, along with the stakeholders from the client applications planning on using the software. 

Before the team can prioritize the NFRs, defining them clearly is very important. Specifying that the system should be fast, scalable, accurate and secure is very different from defining exact numbers, like the system should respond in less than 3 seconds or be able to handle 100,000 requests per second. Having a clear metric of what you are trying to achieve speeds up the development process and helps make the right architectural decision. 

Find out who's hiring.
See jobs at top tech companies & startups
View All Jobs

 

When prioritizing NFRs, how do you balance the trade-offs that enhance or degrade certain attributes?

Prioritizing NFRs comes with certain trade-offs, so finding the right balance is very important. For example, setting the performance expectation of the software to 1 second is very different than setting it to 3 seconds. Agreeing to 99.99 percent availability is very different from agreeing to 99.95 percent. When defining all these requirements, you need to spend some time discussing the business requirements with the team and stakeholders to see if you need 99.99 percent availability or if your business use case can work well with 99.95 percent. 

Keeping the requirement realistic is critical to finding a balance. For example, designing a system for 100 million users per day when you anticipate that your website will have 10,000 visitors per day for the next six months would not make sense. By the time you finish developing for this aggressive requirement, you might not even need this system, or the stakeholders might have figured out an alternative. The key to a successful project is finding a balance between the business requirements, quality attributes and time to market.

 

InfluxData

Ryan Betts

VICE PRESIDENT OF ENGINEERING

 

Why is it important to prioritize non-functional requirements throughout the development process? 

Customers care about quality, timeliness and product evolution. Of these, quality is the only one typically captured as a functional requirement. If a team ignores non-functional requirements, they will inevitably fall behind in their iteration velocity as code becomes brittle, entangled, poorly tested, and otherwise encumbered. As this happens, quality decreases, delivery dates slip and become less certain, and iteration speed falls. Each of these will cause more harm to a customer relationship. 
 

If a team ignores non-functional requirements, they will inevitably fall behind in their iteration velocity.”


As we built our Time Series cloud product, we ended up with an API gateway implementation that did not cleanly separate concerns. This part of the code base caused performance and reliability issues, almost all of which were directly attributable to code structure. The API itself met functional requirements, but creating new APIs, scaling API request capacity and managing deployment of new API code became fragile and frustrating. Taking the time to untangle this code, correct bad abstractions and improve observability and monitoring have all paid off in improved iteration speed and decreased defect rates.

 

BETTS’ FOUR STEPS TO PRIORITIZING NON-FUNCTIONAL REQUIREMENTS

  1. Observability is a feature and a core part of the product: Know how you are going to measure feature performance to understand the feature’s impact on users and adoption.
  2. Be a good consumer: Enable your peers to understand continuous integration dependencies and to trust that passing CI means your service will function. Provide a way for them to know their changes are safe.
  3. Be a good provider: When making changes that will affect callers of your service, be diligent in making those changes safe. Provide a clear API so that consumers understand your service's contracts.
  4. Use a definition of ‘done’ to control technical debt and quality: Use your team’s definition of done to enforce a standard of code review, unit testing, integration testing, observability, migration planning, feature-flagging/deployment planning, user documentation and operational runbooks.

 

When prioritizing NFRs, how do you balance the trade-offs that enhance or degrade certain attributes?

In my experience, complex trade-offs between NFRs often indicate a missing consensus around strategy. Deciding the shape of a product is an evolutionary and iterative process. As that vision evolves, NFRs also change. Often, conflict between NFRs happens in these gray areas where product strategy, positioning or pricing is being questioned and improved. 

If you find your team can’t reach a consensus on NFRs, it can be useful to widen the aperture and understand if they have a shared understanding of the product strategy.

 

Rippling

Tony Dong

ENGINEERING MANAGER

 

Why is it important to prioritize non-functional requirements throughout the development process? 

Rippling focuses on building very user-facing products. Non-functional requirements help us to focus on the  “what” and the “why” of the product we’re building. We really want to focus on building not just products that functionally work, but products that meet the user’s expectations. A lot of our NFRs focus on usability and user experience of the product and if it actually solves the user’s needs. This is something we continually prioritize in every project. 

 

A lot of our NFRs focus on usability and user experience of the product and if it actually solves the user’s needs.” 


An example of a project where we focused on NFRs is in our reports feature. This feature allows customers to slice and dice their data, performing complicated filtering and aggregations. A non-functional requirement was that we created a responsive interface for applying filters and aggregations. This requirement drove us to build drag-and-drop UI components and dynamic data previewing. These two features created a seamless experience for the user to preview the results of their selection in real time without operating over the entire dataset. It enabled users to gain a more in-depth understanding of the tool through continuous exploration and feedback.

 

How do you prioritize each non-functional requirement? Who else is involved in this process?

We start gathering NFRs as part of the project kick-off with engineering, product and design, as well as other stakeholders. We try to look holistically at what users are trying to accomplish and from there, determine both functional and non-functional requirements of the project. During the development of the project, we will have weekly syncs in place to help keep us aligned on our goals and make sure we’re building the product in a way that’s actually solving the user’s needs.

 

Related ReadingWhat You Should Know About Functional Programming

 

When prioritizing NFRs, how do you balance the trade-offs that enhance or degrade certain attributes?

We typically look at two different dimensions when it comes to NFRs: customer impact and building speed. We measure customer impact by looking at the frequency and intensity of the problem they have because we haven’t built the product yet. As with any startup, projects don’t happen in a vacuum. You're prioritizing against all of the other projects in your backlog, so we always try to maximize our output and impact. 

When we’re looking at NFRs within a project, we first make sure that it’s the most important thing we should be working on as a team. After that, we look at all of the possible things we could be building within this project and figure out how to maximize our development efforts to have the most customer impact.

 

Responses have been edited for length and clarity. Images via listed companies.

Great Companies Need Great People. That's Where We Come In.

Recruit With Us