A non-functional requirement (NFR) is realized by the architecture and the implementation. The balance can vary. Sometimes the architecture does the most part, e.g. by providing a real-time OS and fixed priorities for critical threads; sometimes the implementation, e.g. by following coding conventions scrupulously to ensure code maintainability. And sometimes the balance is off.
One example I remember was durability for long operation times. Memory leaks were the main problem and we just played whack-a-mole with them all the time in the implementation. The architecture didn’t provide any means to isolate or measure memory consumption, nor a way to recover from memory leaks by providing a reset capability or something similar.
Another example was real-time wireless communication. Wireless medium has a very unstable characteristic. But our architecture didn’t provide any means to isolate this unstable part from the rest of the system and did not allow us to monitor it separately. Therefore we had to inspect irrelevant parts of the system in case of delays in the communication, although it was the wireless medium that caused the problem.
Compatibility was another example. When the architecture doesn’t limit number and breadth of the critical interfaces relevant for compatibility, implementation has to carry the burden of always making compatible changes over a large set of complex interfaces; which becomes a very cumbersome and imprecise job, since the impact assessment for compatibility grows exponentially more difficult with complicated interfaces.
Yet another example was modifiability. When we often had modifications that needed a shotgun surgery throughout the system, architecture was again not doing its part for satisfying a modifiability NFR. It should have provided a single place to modify.
However, we should be careful not to tip the balance in the other direction too much, e.g. by supporting an unnecessarily large set of modifiability requirements in the architecture. Because that would then result in increased complexity in the architecture; harming performance, usability and maintainability. Few critical modifiability NFRs should be supported by the architecture, while the rest by the implementation.
The lesson is similar to the point of the post BAPO imbalance: architecture and implementation are both needed to fulfill an NFR, and each have a home turf where they are the most efficient. When you see that the architecture is going into too many details, or you are spreading too thin in the implementation to satisfy NFRs, an imbalance might be the case.