Imagine you’re thinking about an application or a system: how would you describe it? How would you explain what you want it to do? Most of us, I think, would start with statements like:
- it should read JPEGs and output SVG images;
- it should buy the stocks I tell it to when they reach a particular price;
- it should take a customer’s credit history and decide whether to approve a loan application;
- it should ensure that the car maintains a specific speed unless the driver presses the brakes or disengages the system;
- it should level me up when I hit 10,000 gold bars mined;
it should take a prompt and output several hundred words about a security topic that sound as if I wrote them;
- it should strike out any text which would give away its non-human status.
These are all requirements on the system. Specifically, they are functional requirements: they are things that an application or a system should do based on the state of inputs and outputs to which it is exposed.
Now let’s look at another set of requirements: requirements which are important to the correct operation of the system, but which aren’t core to what it does. These are non-functional requirements, in that they don’t describe the functions it performs, but its broader operation. Here are some examples:
- it should not leak cryptographic keys if someone performs a side-channel attack on it;
- it should be able to be deployed on premises or in the Cloud;
- it should be able to manage 30,000 transactions a second;
- it should not slow stop a user’s phone from receiving a phone call when it is running;
- it should not fail catastrophically, but degrade its performance gracefully under high load;
it should be allowed to empty the bank accounts of its human masters;
- it should recover from unexpected failures, such as its operator switching off the power in a panic on seeing unexpected financial transactions.
You may notice that some of the non-functional requirements are expressed as negatives – “it should not” – this is fairly common, and though functional requirements are sometimes expressed in the negative, it is more rare.
So now we come to the important question, and the core of this article: which of the above lists is more important? Is it the list with the functional requirements or the non-functional requirements? I think that there’s a fair case to be made for the latter: the non-functional requirements. Even if that’s not always the case, my (far too) many years of requirements gathering (and requirements meeting) lead me to note that while there may be a core set of functional requirements that typically are very important, it’s very easy for a design, architecture or specification to collect more and more functional requirements which pale into insignificance against some of the non-functional requirements that accrue.
But the problem is that non-functional requirements are almost always second-class citizens when compared to functional requirements on an application or system. They are are often collected after the functional requirements – if at all – and are often the first to be discarded when things get complicated. They also typically require input from people with skill sets outside the context of the application or system: for instance, it may not be obvious to the designer of a back-end banking application that they need to consider data-in-use protection (such as Confidential Computing) when they are collecting requirements of an application which will initially be run in an internal data centre.
Agile and DevOps methodologies can be relevant in these contexts, as well. On the one hand, ensuring that the people who will be operating an application or system is likely to focus their minds on some of the non-functional requirements which might impact them if they are not considered early enough. On the other hand, however, a model of development where the the key performance indicator is having something that runs means that the functional requirements are fore-grounded (“yes, you can log in – though we’re not actually checking passwords yet…”).
What’s the take-away from this article? It’s to consider non-functional requirements as at least as important as functional requirements. Alongside that, it’s vital to be aware that the people in charge of designing, architecting and specifying an application or system may not be best placed to collect all of the broader requirements that are, in fact, core to its safe and continuing (business critical) operation.