Field Note 2 current
Engineering priority ordering
TL;DR
When engineering concerns conflict, prioritize security > correctness > availability > performance, and never trade a higher-ranked concern for a lower one. The rule applies the moment you must actually choose between them — finding a clever way to improve a lower-ranked concern without hurting a higher one is just engineering and isn’t constrained. In PRs, incident reviews, and design discussions, cite this ordering as the tiebreaker rather than re-arguing it. Business-level overrides (cost, deadlines, time-to-market) are deliberately out of scope and belong on leadership’s desk with the engineering trade-off documented — not quietly reordered in a PR.
Context
When engineering concerns are in conflict — when you can’t have all of security, correctness, availability, and performance at once — engineers need a shared tiebreaker. Without one, the argument is resolved by whoever has the loudest voice, the most political weight, or the deadline closest at hand. The outcome then varies team by team and incident by incident, which is the opposite of what you want.
You need a rule any engineer can apply on their own and reach the same answer as anyone else would — stable enough to be cited in reviews and postmortems without re-litigation.
Recommendation
When two or more of the following concerns conflict, the priority ordering is:
- Security — confidentiality, integrity, authentication, authorization, defense against malicious actors, data privacy.
- Correctness — produces the right answer; doesn’t silently lose, corrupt, or misrepresent data; behaves as documented.
- Availability — the system is up, responsive, and degrades gracefully under stress.
- Performance — latency, throughput, and resource efficiency.
Never trade a higher priority for a lower one. If a change improves performance at the cost of availability, don’t ship it. If it improves availability at the cost of correctness, don’t ship it. If it improves correctness at the cost of security, don’t ship it. The direction is one-way: higher wins.
What “trade” means here: a deliberate choice where satisfying one concern requires giving up some of another. Discovering a clever way to improve a lower-ranked concern without hurting higher ones isn’t a trade — it’s just engineering, and it’s encouraged. The rule binds only at the moment you must actually choose.
Worked examples:
- Security vs. availability — when an authentication or authorization dependency is degraded and a service can’t verify a request’s identity or permissions, the service rejects the request rather than serve it un- or under-authenticated. Some legitimate users see errors during the degradation; that’s preferable to letting through a request whose identity can’t be confirmed. (Same preference ZFN-3 encodes when it says authentication is never carved out.)
- Correctness vs. availability — a calculation produces wrong answers under load: fail closed
(return errors) rather than serve incorrect data. A
500is preferable to a confidently-wrong200. - Availability vs. performance — when a service handles multiple distinct workloads, partition the resources each one uses (separate thread pools, connection pools, queues — “bulkheads”) so one workload’s exhaustion can’t drag down the others. The partitioning costs efficiency: pools can’t share idle capacity and aggregate throughput is lower. Accept that cost, because a single shared pool means one runaway flow takes the rest of the service with it.
- No trade at all — a caching layer that improves latency without weakening any guarantee above it is unambiguously good. Ship it. Most performance work looks like this; the rule doesn’t constrain it.
Scope: this covers engineering decisions inside the systems you build. Business-level concerns (cost, time-to-market, strategic positioning) are deliberately out of scope. Those are decided at the leadership level and may legitimately override this ordering for specific product calls — but those overrides should be conscious decisions made at that level, not engineers quietly reordering in a PR.
Consequences
Easier:
- “Should we cut this corner?” has a fixed answer to refer to. The citation is the argument.
- Incident-response decisions (“ship the risky fix or wait?”) have a default direction.
- New engineers learn the trade-off bias in one place instead of absorbing it over months.
- Independent teams reach consistent answers without escalating routine trade-off calls.
Harder:
- The rule forces you to look harder for non-trading solutions when the obvious move would compromise a higher concern. That work is real.
- Some performance wins that would be easy with a small correctness or security relaxation are off the table. You sometimes ship slower software than you technically could.
- Drawing the line between “trade” and “no-trade-off engineering” takes judgment, and reviewers will sometimes disagree per change. That’s an honest argument worth having, not a reason to weaken the rule.
New obligations:
- Cite this ordering when rejecting changes that trade down; don’t re-derive the rule each time.
- A deliberate engineering exception requires amending this note or superseding it. “We need to ship by Friday” is not an exception — that’s a business-level override that belongs on leadership’s desk with the engineering trade-off documented.
References
- ZFN-1 — the directional-record shape; this is a canonical instance.
- ZFN-3 — applies this ordering (security-first) to transport.
Changelog
- 2026-06-12: First published as a Field Note.