<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Thinking through the Cloud]]></title><description><![CDATA[Taking cloud professionalism to new rigor and depths]]></description><link>https://tech.ngperrin.com</link><image><url>https://substackcdn.com/image/fetch/$s_!hJkW!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5ce81b0-f183-4bbd-a2b4-78bc2ac0c6ac_144x144.png</url><title>Thinking through the Cloud</title><link>https://tech.ngperrin.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 30 Apr 2026 15:16:20 GMT</lastBuildDate><atom:link href="https://tech.ngperrin.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Nathaniel Perrin]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[ngperrintech@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[ngperrintech@substack.com]]></itunes:email><itunes:name><![CDATA[Thinking through the Cloud]]></itunes:name></itunes:owner><itunes:author><![CDATA[Thinking through the Cloud]]></itunes:author><googleplay:owner><![CDATA[ngperrintech@substack.com]]></googleplay:owner><googleplay:email><![CDATA[ngperrintech@substack.com]]></googleplay:email><googleplay:author><![CDATA[Thinking through the Cloud]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Whatever happened to GraphQL?]]></title><description><![CDATA[The ascendant, next-gen API that never quite took over]]></description><link>https://tech.ngperrin.com/p/whatever-happened-to-graphql</link><guid isPermaLink="false">https://tech.ngperrin.com/p/whatever-happened-to-graphql</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Wed, 21 Jan 2026 23:01:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hJkW!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5ce81b0-f183-4bbd-a2b4-78bc2ac0c6ac_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For those who remember, there was a period of time roughly between 2018-2021 when GraphQL was all the rage, so to speak.</p><p>It was a hot item in the technology world at a time when all the market gaps SaaS could theoretically fill were being plugged as rapidly as possible which in turn incentivized heavy investment into simplified, standardized tooling to reduce that time-to-market metric as far as possible.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>While some technology strategies veered off into no-code solutions, others pushed forward in the evolution of software engineering toward reusable patterns and frameworks that reduced the need for every startup to re-invent the wheel on common technology implementation questions.</p><p>React offered a relatively small but powerful abstraction that would reduce the learning curve for newcomers and rookies to be able to build web apps all on their own.</p><p>Coding bootcamps became a supposed one-way ticket into the lavish payscale of technology jobs with many touting their credentials as MERN or PERN full-stack engineers after a month or two of training.</p><p>Next.js would build off React to offer even further abstraction to make rapid prototyping even more effortless. Few acknowledge that the mixed to relative success of LLMs to &#8220;vibe code&#8221; web applications is due in large to how simple this has become through platforms like Vercel and Next.js.</p><p>It is easy to tie together the strands of success in the train of evolution.</p><p>But GraphQL is something else.</p><p>During the peak of its hype train, GraphQL was going to displace RESTful API development as the universal solution. REST APIs were going to become obsolete. GraphQL would revolutionize the whole philosophy of middleware. At least by some accounts.</p><p>But this did not happen.</p><p>It has been adopted at a large scale as a solution for some of the time, but certainly not all of the time.</p><p>There was not a decisive push to integrate it universally in the same way that generative AI has since the GraphQL craze.</p><p>Why is that?</p><p>Let us find out. We are barely going to even touch the nuts and bolts of GraphQL here, but rather look at its history and reception.</p><h1>What is GraphQL?</h1><p>No proper post-mortem can begin without an account of the history and origins of its subject. </p><p>Like React, GraphQL is a baby of Facebook/Meta. Also like React, it was born to solve the same penumbra of problems around standardization and consistency.</p><p>In 2011 and 2012, smart phone adoption was close to solidified, and the world of mobile apps was about to explode. </p><p>Facebook was consolidating its leadership over the social media market on desktop and needed a firm way to entrench itself in the mobile app experience as well.</p><p>How does one build an application that can interface with Facebook&#8217;s vast troves of data from the limited power and performance of an early smartphone?</p><p>What React was on the software side, GraphQL was on the query language side.</p><p>As described in <a href="https://engineering.fb.com/2015/09/14/core-infra/graphql-a-data-query-language/">GraphQL&#8217;s 2015 prospectus when it became open source</a>, the Facebook teams needed to find a consolidated, centralized interface for delivering feature like News Feed without the complexity of data shape transformation required between the client and server.</p><p>This document details several advantages toward the GraphQL way:</p><ul><li><p>Data shape: The query response mirrors the shape of the request</p></li><li><p>Hierarchy: Embedded objects in one single query without multiple queries</p></li><li><p>Strongly typed: Each level of the GraphQL query has strong typing to validate query structure and types before execution.</p></li><li><p>Protocol: It is a stateless middleware, not a storage backend to manage</p></li><li><p>Introspective: It can be queried about itself rather than needing to go review a spec elsewhere</p></li><li><p>Version-light: The returned data&#8217;s shape is determined by the client not the server</p><p></p></li></ul><p>Given these points, those with enough REST API heartburn could see the appeal of such a revolutionary approach, especially when it brands itself as <a href="https://graphql.org/">&#8220;product-centric&#8221;</a>, highly suitable for the rise of rapid SaaS development.</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://tech.ngperrin.com/subscribe?"><span>Subscribe now</span></a></p><h1>But Why GraphQL?</h1><p>The developers and maintainers had their own reasons for suggesting that GraphQL was &#8220;better&#8221;, but let us dive into some points from the broader online discourse about this new technology, particularly its apologists.</p><p></p><h2>1. RESTful Is Not Modern</h2><p>This is a subjective claim to be sure, but it is one that has been asserted by those who would rather see GraphQL displace REST API.</p><p>There are several common areas of complaint here.</p><ul><li><p>REST produces a sprawl of endpoints at scale. Each new capability requires a new endpoint. Every new resource requires a whole new set of endpoints for all its associated verbs. The growing surface area introduces overhead, risk of inconsistencies, and dependencies between endpoints.</p></li><li><p>REST couples resources with teams which does not align with modern enterprise domain-driven design. To maintain a comprehensive Enterprise REST API requires complete and total coordination between teams on resources, including cross-domain calls and versioning. At least so critics claim.</p></li><li><p>RESTful routes mirror the page-based implementation of early web applications, not modern single page applications which are component-driven. This leads REST to consistent over and under fetching of data with the client jumping through hoops to get what it needs from the server.</p></li><li><p>REST does not offer type safety for API queries. If we have TypeScript for JavaScripts and ORMs for database transactions, the lack of type safety is a significant weakness.</p></li></ul><p>More could be said here on the nature of these issues, including a defense of REST and it has evolved in recent years, but our main focus here is the sentiments which drove GraphQL proselytization.</p><p>At the very least, many of these are certainly understandable complaints for those trying to build with REST in a modern world and more than sufficient justification to seek to build something better.</p><h2>2. Strong Contracts</h2><p>If there is one positive thing which GraphQL advocates unanimously praise about this framework, it is the type safety.</p><p>In the world of client-server calls, strong contracts and type safety offer guarantees that eliminate a whole range of errors around what can be quite simply labeled &#8220;miscommunication&#8221; between two different systems.</p><p>The contract guarantees that a server will receive an object of a valid shape and type (enforced from the client side), while the client will receive a valid response object from the server (enforced before the response is sent).</p><p>Additionally, GraphQL offers resolvers with the intelligence to filter and pare down fields just to what is needed, a far cry from the data dumps one could easily find in a REST JSON response body. Where REST is verbose, GraphQL is clean and minimal.</p><p>Furthermore, GraphQL decouples the API contract from a backend implementation without exposing an entire DB implementation or schema to a client, a common antipattern that can emerge when DB schemas are treated as an API interface.</p><p>Critics would of course counter that OpenAPI offers the same kind of contract guarantees or one could opt for less over-engineered solutions for this kind of type safety, but this is still one broadly defended point around the advantage of GraphQL.</p><h2>3. Decentralized Ownership</h2><p>As noted above, scaling RESTful APIs is not necessarily easy, considering how resources and routes are coupled in awkward ways with their backend teams.</p><p>GraphQL offers far more flexibility and clarity for the delegation of subgraphs or namespacing of the graph to backend teams so that different departments or teams can still expose their data in a shared enterprise GraphQL endpoint but without the clumsiness involved with such schema maintenace.</p><p>Put simple, the subgraph is far more suited to microservices, as teams seek to evolve away from monolithic implementations.</p><h2>4. Cloud Infrastructure</h2><p>While decoupling subgraphs from a single maintainer, GraphQL&#8217;s philosophy of encapsulation behind one single API surface blends very well with modern cloud infrastructure as well.</p><p>And because it is decoupled from backend implementation, it can simultaneously route requests to various microservice backends, including serverless functions such as AWS Lambda with far more sophistication and flexibility than other traditional API implementations.</p><p>This in addition to managed CSP offerings for GraphQL such as AWS AppSync or simply throwing together a containerized Apollo server is cited as a reason many prefer GraphQL.</p><p>On the flip side, this advantage is somewhat neutralized by the fact that many serverless or cloud-native frameworks exist around the RESTful model. Serverless and AWS SAM, for example. It is not clear when GraphQL developers cite this advantage what these other frameworks lack on the cloud infrastructure front.</p><h2>5. General Developer Experience</h2><p>A few other miscellaneous points to be put under DevEx, in favor of GraphQL.</p><p>The schema evolution is much more flexible and clean, particularly in that GraphQL avoids versioning as much as possible. Versioning of course is required to account for the limited controls around API endpoints particularly when there are weak contracts.</p><p>The implementation philosophy behind GraphQL focuses on only returning the data that is explicitly requested. Fields will always resolve the way they need to by the client, without needing to jump through the hoops of server-side requirements in the way that REST implementations demand.</p><p>Additionally, data can be composed with considerable ease through the graph approach which makes data population in UI flows much cleaner and easier to develop. These can be whipped together in a single query rather than needing to juggle a set of queries and/or transforms based on the server-side logic.</p><p>Colocation of data is a developer experience positive that is hard to overlook when one has experienced it &#8220;done right&#8221;.</p><p>This all ties into a modern web-app style approach which is component-level driven, at its very root. It integrates natively with much of the UI web app ecosystem, for example in its helpers for pagination, suspense/defer fragments, and even an eslint plugin to offer guardrails.</p><p>Much of the &#8220;it just works&#8221; which drives modern software development, finds a well-matched companion in the world of GraphQL.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://tech.ngperrin.com/subscribe?"><span>Subscribe now</span></a></p><h2>But then&#8230; Why Not GraphQL?</h2><p>We could go much deeper into the terminology and protocols and patterns of GraphQL. It was difficult enough to avoid this in speaking of its advantages, but that is not the drive of this piece, and there are better places to consider its technical underpinnings and internal technical dialogue more in depth.</p><p>Again, we are considering the broad sentiments which led to its rise and normalization, rather than its anticipated universalization.</p><p>So while we have seen many of the reasons put forth in favor of GraphQL adoption, particularly in that hype phase, I would like to present some of the arguments presented against GraphQL adoption in the years since then.</p><h2>1. Overengineering</h2><p>The risk of any new technology that purports to be a solution is the possibility that the cognitive load or overhead it takes for (1) humans to learn as practitioners, (2) it to be integrated within a larger technical ecosystem, or (3) LLMs to interface with it relatively intelligently can outweight the benefits it ostensibly brings.</p><p>The risk of overengineering, more or less.</p><p>And this seems to be one of the most common complaints more or less in the developer community around GraphQL.</p><p>The advantages that GraphQL offers in terms of type safety and strong contracts, many REST developers claim they can easily solve through the allegedly more minimal implementation of OpenAPI and/or TypeScript.</p><p>These previous downsides are purportedly solved through minor alterations or layering without needing the full paradigm shift of GraphQL.</p><p>Of course, many GraphQL are equally convinced that OpenAPI is hardly a less verbose and simpler alternative.</p><p>Whether one goes implementation first or specification first, it seems REST offers its own modern suite of solutions that does not require the GraphQL jump.</p><p>These criticisms extend also to AuthZ overhead, schema evolution, and more. But this is the fundamental principle.</p><h2>2. Security Considerations</h2><p>Aside from what are arguably more subjective contentions around GraphQL as an overengineered solution, there are more objective concerns about it from a security perspective.</p><p>By minimizing client overhead and shifting the logic to server-side orchestration, by allowing a single logical endpoint to fetch any number of permutations of data and data shapes from various backends, the question becomes how one can properly AuthZ (i.e. that you are authorized to receive the data you are asking about).</p><p>REST APIs have generally solved for this through integration with OAuth, identity tokens, access tokens, scopes, claims, etc. These are applied at the endpoint level though.</p><p>If GraphQL boasts a single endpoint per environment, how can AuthZ be engineered or implemented within a single endpoint?</p><p>Additionally, the hyper-flexible nature of GraphQL queries lead to a variety of security vulnerabilities, not least of all disclosing broad swathes of one&#8217;s schema to potential bad actors if they simply invoke the <a href="https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/12-API_Testing/01-Testing_GraphQL#introspection-queries">Introspection Query</a>.</p><p>This could further be exacerbated by malicious actors who could easily execute a DoS attack by hitting the GraphQL server with expensive queries, including cyclical or recursive queries depending on the complexity and internal relationships of the data shape.</p><p>Which leads us into the next issue.</p><h2>3. Performance and Rate Limiting</h2><p>Depending on how deeply nested the data shape is, overly broad GraphQL queries can not only be computationally expensive to perform but also have high latency as they solve both horizontally for various data backend providers (hitting each of them individually or even redundantly perhaps) or vertically with increasingly deeply nested layers of data.</p><p>This is further compounded by trying to layer AuthZ on top of deeply nested queries.</p><p>The computational lift to not only resolve all data fields but determine AuthZ for each and individual fields introduces another N+1 problem on the performance side.</p><p>So ironically while many argue GraphQL is overengineered for simple use cases and small developer teams, it actually struggles to scale elegantly in enterprise data environments.</p><p>By offsetting so much of the logic to the GraphQL resolver server, what should in theory just be a minimal, centralized controller becomes a monolithic bottleneck even in microservice-driven architectures.</p><p>Of course, a counter argument would be that one could mitigate this through proper federation and gateway implementation and that this is simply the result of GraphQL antipatterns rather than the GraphQL philosophy.</p><p></p><h2>4. Maintenance Complexity</h2><p>But in any case, Any experienced owner-operator can begin to imagine the onslaught of complexity that these considerations bring into view.</p><p>Beyond what has been mentioned above, other GraphQL maintainers are rather critical of schema evolution and management as well. </p><p>Since GraphQL&#8217;s philosophy is that there should <em>never</em> be a breaking change and thus versioning is not needed, many are compelled to go through inordinate level of effort or gymnastics to fulfill such a contractual promise.</p><p>Versioning is a critical tool in a world of finite operational resources to meet one's contractual agreements as a service provider within a specific window while accepting the iterative nature of software or API development.</p><p>To commit a service provider to support any and all iterations of not only a middleware to meet the needs of both clients and server backends can prove quite a miserable vow to live through in the long run.</p><p>This in addition to the fact that modern enterprise teams are not quite coupled in the ways that GraphQL presumes can add to the disconnect and enteprise acrobatics that it was originally supposed to mitigate.</p><p>It is understandable in this way how many could be burnt out on the GraphQL option if this is their primary experience with it.</p><h1>Conclusion</h1><p>What are we to make of us all this?</p><p>Although such criticisms are rather serious, this does not mean that GraphQL is dead. It remains quite popular as <strong>one solution</strong> among many, but it is not the universal displacer that many heralded it to be even as recently as a few years ago.</p><p>It will remain a popular, well-supported technology for some time, barring any paradigm-shifting developments which may either render it obsolete or reinvigorate it, such as the <a href="https://hygraph.com/blog/why-the-future-of-ai-is-graphql">purported third wave of GraphQL</a> in light of agentic AI.</p><p>It seems that GraphQL is one of those overly celebrated even if at least somewhat ingenious technologies that succeeded on some level but not without some degree of failure. </p><p>A failure (if it can be called so) to have the luck or foresight to identify developments in the cloud and IT world as well as its own logic at scale. Both of which are divergences from the original intent of GraphQL&#8217;s design in the early 2010s that substantially undermined its universal adoption and made REST API a framework that faded as definitively as SOAP.</p><p>In its defense, one could argue that it was not meant to be applied or implemented universally, this was merely the <em>zeitgeist</em> of the hype train which overplayed its use cases. Even so, it remains a curious case study.</p><p>That is why we explore new technologies and ideas, and why things fail. Whether through failure of design or implementation.</p><p>So that we ourselves can iterate upon the past and build better, build smarter.</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://tech.ngperrin.com/subscribe?"><span>Subscribe now</span></a></p><h1>Sources</h1><p>Acjay. <em>&#8220;GraphQL Was Not the Future.&#8221;</em> August 14, 2024. acjay.com/2024/08/14/graphql-was-not-the-future/.</p><p>Bessey, Matt. <em>&#8220;Why, after 6 Years, I&#8217;m Over GraphQL.&#8221;</em> May 24, 2024. bessey.dev/blog/2024/05/24/why-im-over-graphql/.</p><p>Giroux, Marc-Andre. <em>&#8220;Why, after 8 Years, I Still Like GraphQL Sometimes in the Right Context.&#8221;</em> May 31, 2024. magiroux.com/eight-years-of-graphql.</p><p>Hygraph. <em>&#8220;Why the Future of AI Is GraphQL.&#8221;</em> Hygraph Blog, November 24, 2025. hygraph.com/blog/why-the-future-of-ai-is-graphql.</p><p><em>&#8220;Eight Years of GraphQL.&#8221;</em> Discussion on Hacker News, July 17, 2024. news.ycombinator.com/item?id=46264704.</p><p>Grafbase, Inc. <em>&#8220;Why GraphQL Is Eating the API World.&#8221;</em> May 29, 2025. grafbase.com/blog/why-graphql-is-eating-the-api-world.</p><p>GraphQL Steering Group. <em>GraphQL: A query language for your API.</em> graphql.org.</p><p>GraphQL Project. <em>&#8220;GraphQL: A data query language.&#8221;</em> graphql.org/blog/2015-09-14-graphql. Published September 14, 2015. https://graphql.org/blog/2015-09-14-graphql.</p><p>WunderGraph. <em>&#8220;Six-Year GraphQL Recap.&#8221;</em> Wundergraph Blog, December 3, 2025. wundergraph.com/blog/six-year-graphql-recap.</p><p>WunderGraph. <em>&#8220;GraphQL, REST, and OpenAPI Trend Analysis 2023.&#8221;</em> Wundergraph Blog. wundergraph.com/blog/graphql_rest_openapi_trend_analysis_2023.</p><p>OWASP Foundation. <em>&#8220;Testing GraphQL.&#8221;</em> In <em>Web Security Testing Guide (WSTG) v4.2, API Testing.</em> OWASP.org. owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/12-API_Testing/01-Testing_GraphQL.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[5 Considerations for Multi-Tenant Architectures]]></title><description><![CDATA[Designing multi-tenant environments for isolation and co-location]]></description><link>https://tech.ngperrin.com/p/5-considerations-for-multi-tenant</link><guid isPermaLink="false">https://tech.ngperrin.com/p/5-considerations-for-multi-tenant</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Sun, 02 Nov 2025 20:39:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mJD6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So you want to build yourself a multi-tenant ecosystem.</p><p>And you want to commit to it, all the way through production.</p><p>If you do, know that is a lift.</p><p>Today we will consider some of the most critical factors in the planning and evolution of multi-tenant architectures from my experience doing so for several companies at this point, and what I have learned along the way.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Terminology</h1><p>First, a note on terminology.</p><p>Multi-tenant architecture can be terminologically confusing, particularly because assumptions are often built into these words, assumptions that are just as often not shared by everyone talking about it.</p><p>This can lead to confusion.</p><p>For example, if you are hosting an application with four hundred different commercial users, one could argue this is a multi-tenant application as each user is an independent &#8220;tenant&#8221; living inside the application.</p><p>This same person would then look at another application which consists of five near-identical deployments, with one customer group per deployment, and they would call this a single-tenant architecture.</p><p>On the flip side, someone could look at that application with four hundred users and say it is single-tenant, as there is one deployment that corresponds to the production environment.</p><p>They would then look at the five-deployments application and say it is multi-tenant, as the production environment has five tenants for the one environment.</p><p>The key distinction here is what &#8220;tenant&#8221; refers to. Both views are arguably valid but have very different understandings of what it is multi- with respect to.</p><p>We will define &#8220;tenant&#8221; as an infrastructurally-isolated instantiation of an application deployment for purposes of data or functional isolation.</p><p>This assumes that a &#8220;tenant&#8221; is a more granular subdivision of infrastructure beneath the &#8220;environment&#8221; layer (e.g. dev, qa, prod).</p><p>It also means that highly available (HA) environment architecture perhaps with an Active/Active or Active/Passive configuration would not necessarily introduce multi-tenancy, since the data or compute is not strictly bounded into one or the other.</p><p>Therefore a single-tenant deployment would mean one instantiation of an application in prod.</p><p>If there is one deployment per customer, that would entail a multi-tenant architecture. At least for our intents and purposes here.</p><p></p><h1>1. Do You Really Need Multi-Tenancy?</h1><p>This should be the architect&#8217;s go-to question when facing any net-new consideration: &#8220;Do you really need ______?&#8221; </p><p>If less truly is more, then is multi-tenancy really adding more than it will cost you?</p><p>This really does depend. </p><p>And it can be incredibly hard to forecast these variables if you have not lived through the growing pains of multi-tenant production ownership before.</p><p>Let us take into account some common reasons why companies push for multi-tenancy.</p><p></p><h2>A. Data Isolation</h2><p>Data isolation can be a very good reason for adoption a multi-tenant architecture, but it can also be an unnecessary one.</p><p>It can provide extremely secure safeguards to isolate the entire lifecycle of a single customer&#8217;s data if you instantiate separate tenants for each customer organization or BU you are working with.</p><p>But &#8220;data isolation&#8221; on its own is too broad and imprecise to be useful for a technologist in the way that it is for sales.</p><p>One must ask <em>what types of data need to be isolated and to what extent and for what reasons</em>?</p><p>The typical working assumption here is persisted application data such as in a PostgresDB.</p><p>But why is this necessary?</p><p>This requirement is most often driven by compliance or infosec teams, either internally or the customers&#8217;.</p><p>If it is compliance, then the question is which compliance frameworks are in scope for the application stack, or better yet, for individual application components.</p><p>If it falls under an information security program, then the question is which policies, standards, and baselines are in scope for the solution you are architecting.</p><p>Often enough, precisely mapping controls to components can lead to a relieving level of descoping.</p><p>It may be possible to achieve SOC 2 Type 2 certified compliance without needing multi-tenant PostgreSQL, if you can properly implement Postgres access controls and guardrails.</p><p>The minimum viable requirements for isolation may also shape the multi-tenant model you adopt. Perhaps separate Postgres databases are needed but can live in a shared cluster.</p><p>Multi-tenancy is not a one-size-fits-all approach as we shall see below.</p><p>Aside from the question of requirements scoping and mapping, another easy-to-miss possibility is whether the application stack itself already provides sufficient data isolation and guardrails, or is within a sprint&#8217;s distance of doing so.</p><p>This is a question of resourcing. For underresourced application teams it may simply be more viable to shift the load to infrastructure.</p><p>That is not a problem in itself, but it does come at a cost, a cost that runs with interest.</p><p></p><h2>B. Noisy Neighbor</h2><p>Some workloads are more intensive than others.</p><p>If customers are working inside a shared instance, particularly in an application without effective load testing or related protections, a power user may cause performance degradation for other users either through memory or CPU exhaustion, 3rd party API rate limiting, or exorbitant LLM token consumption.</p><p>Again the question may come down to (1) how well-designed or well-implemented the application itself is around handling load and putting in appropriate checks and balances or (2) what measures of vertical and horizontal scaling are in place to provide elasticity to support bursty compute requirements.</p><p>Sometimes that or a concerted refactoring effort may solve it.</p><p>Or if there is a special customer organization with heavy usage of the application, it may make the most sense across the board to provide them with a designated, isolated environment, so the blast radius of their system degradation is rather limited.</p><p>In this case it is more of a stopgap measure from a SRE perspective, but thinking beyond the pure technical architecture, it is a fairly effective customer relations move for those willing to pay or go along with it. </p><p>Where infosec teams are not involved, perhaps the power user wants the comfort of knowing they are using your SaaS offering in their own dedicated environment. Any slowdown is related to their heavy usage, not someone else&#8217;s.</p><p>An upsell to a premium isolated environment may boost ARR, particularly for larger customers, and this SKU approach is a valid business justification for supporting a multi-tenant architecture.</p><p></p><h2>C. Easier Lifecycle Management</h2><p>Perhaps there are not strict data isolation or performance considerations involved but for whatever reasons the application itself does not have robust data lifecycle management for users, groups, or workspaces.</p><p>If you happen to operate in a model with strict customer data deletion requirements and an application data model that really cannot service those needs, and no resourcing to implement such a procedure yourself, you may be backed into needing a multi-tenant solution here.</p><p>However this is overall a strategically weak reason for multi-tenancy if it is only one, and it behooves the technology strategy stakeholder to take a good, long look in the mirror and assess how committed they are to an application which cannot handle data lifecycle management well, and how long until that will be mitigated.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://tech.ngperrin.com/subscribe?"><span>Subscribe now</span></a></p><h1>2. Choose Your Multi-Tenancy Model</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mJD6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mJD6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 424w, https://substackcdn.com/image/fetch/$s_!mJD6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 848w, https://substackcdn.com/image/fetch/$s_!mJD6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 1272w, https://substackcdn.com/image/fetch/$s_!mJD6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mJD6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png" width="1260" height="709" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:709,&quot;width&quot;:1260,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:253743,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/177571606?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mJD6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 424w, https://substackcdn.com/image/fetch/$s_!mJD6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 848w, https://substackcdn.com/image/fetch/$s_!mJD6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 1272w, https://substackcdn.com/image/fetch/$s_!mJD6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb75c0316-4d63-40d2-adb5-35a3dfa9010b_1260x709.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://d1.awsstatic.com/onedam/marketing-channels/website/aws/en_US/solutions/approved/documents/architecture-diagrams/multi-tenant-architectures-on-aws.pdf">AWS Reference Architecture</a></p><p>If you do in fact decide to move forward with the multi-tenant architecture, the next question is the layer at which segmentation occurs.</p><p>This is a very broad spectrum and depends on the use case.</p><p>As the AWS example demonstrates above, you could theoretically have a multi-tenant architecture where the application tier is shared, but an individual RDS table is partitioned.</p><p>Or perhaps in the database tier it is the schema that is the partition layer, or the logical database, or the database instance.</p><p>In a silo model, you have dedicated application and database for each tenant, but this could be extended to the networking layer (VPC for each customer), or even beyond that to an AWS account per customer (leveraging Account Factory).</p><p>There are multiple dimensions to this, not just the single axis around the application stack itself.</p><p>If you have multi-tenancy, how do you then strategically group or partition:</p><ul><li><p>Telemetry data</p></li><li><p>Audit logs</p></li><li><p>Big Data Analytics (OLAP)</p></li><li><p>SIEM/XDR and other security artifacts</p></li></ul><p>Just to name a few.</p><p>This may or may not be complicated, again depending on the original requirements driving multi-tenancy in the first place.</p><p>But if for instance you require multi-tenancy for data isolation purposes, but your tracing or analytics tooling ends up piping sensitive data to a shared provider anyway, then you may need to think strategically about your analytics strategy.</p><p>The same goes if you have LLM models interface with sensitive data. If you depending upon embeddings, does your vector data store meet the criteria of data isolation? Or even with just inferential workloads, does your LLM observability tooling merely pipe all user prompts and context to a shared repository?</p><p>Anything that is tied to a driving component for multi-tenancy becomes a factor to consider.</p><p>This is part of the cognitive burden and potential complexity you must accept when moving forward with a multi-tenant architecture.</p><h1>3. Change Management</h1><p>Multi-tenancy introduces a fair degree of complication in the processes and procedures of change management.</p><p>Whereas in single-tenancy architectures change or patch management occurs once per environment (thus providing a very focused arena for change control), multi-tenancy often entails release management for each individual tenant</p><p>Let me provide just a few examples of where the complexity comes into play.</p><h2>A. Fleet Deployments</h2><p>The most obvious complicator is of course the deployment to each and every tenant in an environment for each release.</p><p>If you have N tenants in an environment, you will need to run the release playbook at least N times.</p><p>Automation is of course the compensating factor here. </p><p>But this really necessitates a robust CI/CD mechanism, one that can handle the nuances of multi-tenant change management.</p><p>GitOps pipelines are key here but again need to be robust for this to be a viable solution.</p><p>If you do not have the platform maturity to adopt full GitOps, then it is best to devise strategic patterns and guidelines for streamlining manual change operations as much as possible.</p><p>Bash and PowerShell can be a safety net in these situations, to account for gaps in your infrastructure-as-code or GitOps ecosystem, but they need to be handled astutely and with good judgment.</p><p>For instance, if the change request ticket includes a manual work item that is tied to a specific release, then there should be a concomitant effort by the ITSM, DevOps, or equivalent team to build out an automation of that manual work item which can then be run against the fleet during the release window.</p><p>Again, it&#8217;s a bit old-schooley, but the tradeoff of multi-tenancy is that most things change-management just become a heavier lift.</p><p>Whereas in smaller application ecosystems it may fully well be possible to have a polished GitHub flow and CI/CD pipeline that issues a new release for each approved commit, this may not be possible for multi-tenancy.</p><p>If you have a heavyweight, tightly coupled tenant architecture with a rolling restart deployment strategy, this would entail a lot of compute pressure to essentially reboot all the servers or containers tied to all tenants.</p><p>It is easy to identify solutions for this problem of course, but the fact that you do need a solution for it, does make it heavier than if you had single-tenant to begin with.</p><h2>B. QA Strategy</h2><p>QA and UAT rehash the same problems of manual versus automated testing.</p><p>With multi-tenancy, any number of manual QA tasks would need to be multiplied by N number of tenants. Unless you compromise your QA standards on this front and resort to strategic spot checking.</p><p>If you are able to invest in and achieve near 100% level of QA automation for a single environment, that is all well and good, but you may need to temper your expectations by recognizing just how feasible it is to run compute-intensive testing automations against an entire fleet of tenants, especially if you deploy a release more than once a day.</p><p>Furthermore, the engineering around such QA automation much also take into account multi-tenancy too, such as in how the headless QA tooling authenticates to each individual tenant, assuming there is not a shared admin user across the tenant environments (bad!).</p><p>Not unsolvable just more of a lift.</p><p>More than this, you have to account for the variability of QA results between different tenant environments.</p><p>What if QA testing succeeds in all but one tenant? What if it succeeds in 80 percent? 50 percent?</p><p>What are the criteria for a rollback? Do all environments get rolled back or just a few?Will the complexity of multiple live versions be accepted simply because of the urgency of the release or because the lift is not feasible?</p><p>Not all regressions are equal either, and if nearly all tenants are healthy but one or two have the equivalent of a Sev1/P1 release-introduced failure, there has to be tactical consideration on whether you rollback for all, for some, or try to fail the few forward and then patch the rest later.</p><h2>C. Version Control</h2><p>This of course leads into the aspects of version control which the multi-tenant stakeholder must account for as well, whether they like it nor not.</p><p>If we start off most simply with a monolithic single version for the entire tenant SaaS application stack, you have to identify your versioning strategy <em>for the fleet</em>.</p><p>Are there circumstances in which particular tenants may upgrade before others?</p><p>We noted just now the demands of the rollback strategy, but as is very common, various customers may have differing demands on their release cadence.</p><p>Some may prefer &#8220;move fast and break things&#8221; to opt in for new features while others may simply want their SaaS offering to work as expected all the time, regardless of bells and whistles.</p><p>This may lead to a business driven requirement for different release streams.</p><p>The advantage of multi-tenancy and leveraging Infrastructure-as-Code is that you can have very granular management of individual tenants&#8217; versions without too much difficulty. </p><p>Sometimes it&#8217;s as simple as a Helm chart values.</p><p>But you have to account for the compatibility and version support of all deployed versions in the tenant fleet. If you need a critical security hotfix, you must be prepared to patch multiple different versions.</p><p>Additionally, if there is some feature flag tooling at play as well, this can quickly lead to a matrix of headaches around how to line up individual tenant versions with the suite of feature flags and their operational lifecycle.</p><p>Now take two dimensions of that matrix and add on the third dimension of microservice versioning.</p><p>If you have a microservices ecosystem, then each microservice ostensibly has its own versioning cycle and change management system.</p><p>If some microservices live within the multi-tenant offering while others live outside it but integrate directly with it, how do you orchestrate the versioning of shared versus tenant services for all tenants across all the versions for all the services currently supported?</p><p>This is another example of how multi-tenancy may not seem intimidating at first but can quickly become more than a thought problem as an organization or platform scales outward and upward.</p><h2>D. New Workloads</h2><p>On the note, of outward scaling, you can become fairly adept at accounting for multi-tenancy in your regular change management or release process, given you have a well-defined set of changes you are working with.</p><p>But an organization is not growing or thriving if it is not evolving. And the same goes for application architecture.</p><p>The development and integration of new workloads whether a Redis queue, a proxy server, a data warehouse, all need their rollout plans strategically aligned with the multi-tenant architecture.</p><p>To put it simply, it is simple enough to issue and mount a 3rd party API key for a single prod environment, but if requirements demand it, you may need to be able to programmatically generate and mount these for each individual tenant in scope.</p><p>What was relatively simple in single-tenancy becomes a thornier thing to solution for once you have N number of tenants to manage.</p><h1>4. Other Operational Complexity</h1><p>Outside the realm of change management, there are other additional considerations revolving around the ongoing operational complexity of managing multi-tenant workloads.</p><h2>A. Snowflake State Management</h2><p>The beauty of the customer is that they are not all the same.</p><p>Each have their own preferences and interests, and demands for custom-tailored solutions.</p><p>This is not inherently harmful but does pose a risk particularly when multi-tenant architecture becomes a vehicle for snowflake deployments.</p><p>Perhaps one customer wants a particular 3rd party integration disabled for security reasons, or another wants different caps set on file or data limits.</p><p>The beauty of multi-tenant architecture paired with infrastructure-as-code is that such granularity is in fact not only feasible but often easy to manage.</p><p>At least at first.</p><p>In a well-design multi-tenant platform, the actual implementation of snowflake state management can be a breeze.</p><p>But it comes at the cost of application coherence.</p><p>Product and engineering stakeholders may add feature on top of feature over time. More often than not these building blocks may have dependencies upon one another.</p><p>In a one-size-fits-all this is not as complicated to manage.</p><p>Yet if each tenant has their own bespoke configuration patterns, and the consistency of such configuration is not rigorously reviewed and maintained, it is only a matter of time before the snowballing of these snowflakes produces a reliability avalanche. </p><p>It is impossible for QA to catch these in pre-production environments unless you commit to some level of multi-tenant QA environment to account for the bespoke deployments of production tenants.</p><p>SRE stakeholders are fighting a losing battle of trying to corral in every possible permutation of config pattern that may cause regressions.</p><p>If any of this makes it way back to product and engineering, they themselves can express frustration because in their view they should not be required to account for each individual customer deployment&#8217;s requirements.</p><p>And so, without strategic coordinated effort, the multi-tenant bespoke deployments can devolve into a quagmire of both technical and personnel friction. High drag, low velocity.</p><p>While it is a well known adage that &#8220;config is cheap&#8221;, one must beware the force of compound interest. What once was cheap may quickly become taxing at scale.</p><p></p><h2>B. Multiplied Incident Response </h2><p>The same kind of operational complexity extends to incident response as well.</p><p>The classification of severity levels for incidents now has to factor in the probable occurrence where individual tenants may experience severe degradation but other tenants may have zero degradation.</p><p>How does this impact your SLI metrics? Do you take the same KPI hit for degradation in a few environments as you would for the whole tenant fleet? If these are accounted for differently, how do you properly distinguish between isolated downtime versus fleet-wide? What is the criterion for this threshold?</p><p>When an incident does occur in multi-tenancy, one must accurately assess and determine the scope of such an outage. One cannot merely say a particular degradation to the prod environment in most cases. Some tenants may be impacted while others are not.</p><p>Containment and remediation in turn follows this law of operational overhead. If the incident is tied to the tenant level, the lift to implement the fix in one tenant needs to be multiplied by the number of tenants.</p><p>In time-sensitive situations you are largely dependent upon the skills of your incident response team to create automated scripted remediations that can be run programmatically that will not negatively impact unaffected tenants, or introduce other regressions due to variation between tenants.</p><p>Institutional knowledge becomes a chief asset in these cases as those who know the ins-and-outs of your garden of multi-tenant peculiarities can often best assess the path of least resistance. Those with a documentation-based, or worse AI assistant-based, understanding of the application ecosystem may blindly step into the traps of bespoke deployments.</p><p>Often enough, a step or two of additional discovery is needed, and in general makes IR a bit heavier in both theory and practice.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://tech.ngperrin.com/subscribe?"><span>Subscribe now</span></a></p><p></p><h1>5. The Cost</h1><p>Out of all the above reasons, the multiplier factor of hosting multi-tenant environments should be the most acutely felt by the business line.</p><p>This is heavily dependent upon your application architecture, but if the silo consists of isolated web servers or databases or datastores or for some reason stateless API server can make all the difference in your hosting costs.</p><p>But in those cases where you do have to multiply a small chunk of CPU, memory, or storage per customer, this can very quickly be felt in the ultimate P&amp;L statement.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> </p><p>If you have slow customer acceptance this may be gradually accounted for.</p><p>But if you have fast customer acceptance, lowball the license fees to maximize market capture, and are committed to the multi-tenant architecture, the preparer for your financial statements may be surprised to learn that the cloud operating costs are a greater debit than the credit of customer revenue.</p><p>That is more of a worst case scenario in an early startup setting, but the same principle applies.</p><p>Many server-based solutions simply have that base level overhead to run N number of servers. Serverless and scale to zero may mitigate this to some level, at least for compute costs, but you may still have to reckon with any duplicated storage overhead for supporting individual tenant environments.</p><p>If you are a stakeholder trying to steer your organization away from adopting a multi-tenant architecture for a new solution, it may be through the rigorous arithmetic of computing cloud spend that you may be able to get buy-in to avoid or at least mitigate such an approach. If the other reasons fail to be persuasive.</p><p></p><p></p><div><hr></div><h1>Conclusion</h1><p>While this may seem likely a largely negative assessment of multi-tenant architecture, this is not to say multi-tenant architecture is inherently &#8220;bad&#8221;.</p><p>There are many cases that justify the leap to this kind of approach.</p><p>It is just that many orgs who are bought into the multi-tenant approach for one reason or another may not fully know what they are getting themselves into.</p><p>And that is why these thoughts are merely presented here as a cautionary tale.</p><p>Multi-tenant environments introduce an additional layer of challenge. </p><p>These are not insurmountable.</p><p>But they increase that slope of uphill battle technologies teams are often engaged in, to fight the ongoing skirmishes of technology operations.</p><p>To build things that work. And stay working for the long haul. Hopefully without getting burnt out.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Not to mention this can often be masked for early startups by the generous credits their CSP may provide them with for initial vendor lock-in.</p></div></div>]]></content:encoded></item><item><title><![CDATA[8 Myths of Building "Lean"]]></title><description><![CDATA[The Art of Requirements II: Balancing alignment and leanness in digital architecture and engineering]]></description><link>https://tech.ngperrin.com/p/the-art-of-requirements-ii-the-myths</link><guid isPermaLink="false">https://tech.ngperrin.com/p/the-art-of-requirements-ii-the-myths</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Mon, 13 Oct 2025 19:00:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hJkW!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5ce81b0-f183-4bbd-a2b4-78bc2ac0c6ac_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Like Agile, &#8220;lean&#8221; has become something of a meme or cliche in the business and technical world. This is no fault of Eric Ries or whoever may be deemed responsible for revitalizing the term, but it does require us to exercise some thinking muscles to recover the original idea here.</p><p>Let us first restate what &#8220;lean&#8221; is, then what is not, before we consider general principles to build lean from a technical design perspective.</p><h1>The Lean MVP</h1><p>We will take Eric Ries&#8217; <em>The Lean Startup</em> as our starting point on this subject.</p><p>The startup, or more broadly the initiative, is concerned with building something new to fill a gap. If there is a gap, then there necessarily is uncertainty around how to fill that gap.</p><p>The core business proposition or objective should not be primarily locked into filling the gap with <em>this particular solution </em>but rather commit itself to solving a particular problem through hypothesis testing various solution.</p><p>Thus the core loop of building lean is to identify a business hypothesis with metrics to measure the success, and even more importantly the failure of said hypothesis. From there, the MVP is the smallest possible test that addresses the riskiest, most uncertain assumption. The MVP provides actionable information to inform the initiative which can pivot and iterate upon such findings.</p><p>It is validated learning that directs innovations in an auditable way to provide growth.</p><p></p><h1>What Lean Is Not</h1><p>Like waterfall in Agile's clothing, many business and technical professional like to attribute this positive buzzword &#8220;lean&#8221; to many things that are decidedly not lean.</p><p>Any initial prototype is deemed an MVP even if there is no consciously articulated business hypothesis being tested.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>Here are some common ways un-lean thinking can disguise itself as &#8220;lean&#8221;.</p><h2>1. Avoiding Planning</h2><p>This is perhaps one of the most common misuses of &#8220;lean&#8221; I encounter across organizations, particularly in startup culture.</p><p>Building technology is not easy. </p><p>The advance of time has led to the proliferation of technologies, their terms, their mappings, and their use cases. Things are not getting simpler.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>However if you are a decision maker on digital products, platforms, or applications, especially for a freshly-minted start-up, you may struggle to wrap your mind around <em>all the options </em>that are out there and confront you, whether through vendors or opinionated engineers you work with.</p><p>Taking each on their own may be simple enough but then they need to be reckoned altogether, and the complexity balloons the more factors you take into consideration.</p><p>Given such difficulty and a desire to &#8220;move fast&#8221; or &#8220;just build&#8221;, the temptation is to adopt a &#8220;lean&#8221; methodology and forego any and all considerations around system architecture whether it is the application you are building or the company&#8217;s operations itself.</p><p>However this can quickly turn into a let&#8217;s-throw-everything-at-the-wall-and-see-what-sticks mentality.</p><p>This can work, much like you can win at Russian roulette, but it is risky and more often than not <em>costly.</em></p><p>Again this aversion to systems planning or enterprise architecture is not unfounded.</p><p>Plan-avoidance can take precedence as a gut reaction to the endless meeting chains of Waterfall. Talking everything through <em>ad nauseam </em>before one could even start doing anything at all.</p><p>Startup founders exiting corporate environments may feel liberated from QBRs and Scrum-of-Scrums and use this newfound freedom to instill a culture of technical anarchy in their startup.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p><p>But as any technology professional is well aware, once there is the glimmer of gold in a dev, sandbox, or even local environment, the immediate question is how soon can we get this into production.</p><p>So if various individual contributors (ICs) are working on projects or features in their siloes, whatever shows the slightest signs of fruit, may face intense pressure to find its way to a production environment, with minimal other considerations.</p><p>Unless the IC is a master class contributor, then this is where things can get hairy, in trying to find this path to production. Some complicating factors includes but are not limited to:</p><ul><li><p>How to build or deploy this across environments</p></li><li><p>How are secrets/keys managed</p></li><li><p>How secure is the application</p></li><li><p>Can it scale and/or handle load</p></li><li><p>Is it reliable and sustainable</p></li><li><p>Can it be extended for other features or patterns</p></li><li><p>Is it costly to run with a live user base</p></li><li><p>Can other ICs work on the application without an immense learning curve</p></li><li><p>If AI was used, how much bloat or inconsistent patterns are present (along with all the other gaps AI-driven coding can introduce)</p></li></ul><p></p><p>The prototype first, plan later mindset inevitably puts the cart before the horse and can lead to serious delays, frustrations, and costs, simply because basic considerations around the <em>operations </em>of the workload were never considered, out of a desire to &#8220;think lean&#8221;.</p><p>This is not to say that one should overplan either.</p><p>Planning should take into account the tradeoffs. How much time do you validate hypotheses or engage in systems design rather than proceeding with caution?</p><p>Ideally you would be working with the production stakeholders to identify the factors that go into the &#8220;pipeline to prod&#8221; so that you do not face hang-ups before you get there.</p><p></p><h2>2. Avoiding Thinking</h2><p>This is similar to the first, but slightly different.</p><p>While planning-avoidance prematurely waves off systems planning, environment management, compliance etc. as &#8220;too heavy&#8221;, thinking-avoidance simply will take the most immediate, presented solution or idea as the best one.</p><p>This arises when there is a known problem or set of tradeoffs to consider either in the technology or operational structure of an organization.</p><p>You know there is a problem, but identifying the proper solution to that problem may require critical thinking or hypothesis testing.</p><p>The human temptation is to eschew that kind of hard work or hard thinking in favor of taking either the first solution recommended by their particular AI assistant or by saying &#8220;we&#8217;ll figure it out later&#8221;.</p><p>Many will quote design principles of minimalism or again call it &#8220;lean&#8221; to simply not worry about the problem and cross that bridge when we get to it.</p><p>But again this can end up being very costly and regrettable in retrospect, when a day or two of consideration could have saved the firm five or six figures of cloud or personnel spend or lost sales revenue.</p><p>This leads to deferring the answer to whatever is proposed first and following the chain of developments, eyes half shut, to see where it goes.</p><p>&#8220;Lean&#8221; is about actively prioritizing hypothesis testing using data and critical judgment, but like plan-avoidance, thinking-avoidance can often take on the label of lean minimalism to justify passivity or our own human tendency toward laziness.</p><p></p><h2>3. Find the Case to Justify the Assumption</h2><p>Another far too easy trap to fall into is shifting the purpose of the MVP or the lean prototype away from solving a question and toward proving an answer.</p><p>Technologists in startup and corporate environments often have a keen interest in their intelligence optics.</p><p>Because intelligence is immaterial and intangible, it becomes an ongoing site of competition around the players who claim to be technical, and even some who deny being technical but will reserve the right to enter technical debates.</p><p>The rivalries and various episodes that emerge from this can be dramatic enough, but it can also engender behavior that is costly to the company or the particular initiative.</p><p>People can attach their ego to this or that proposal. This or that solution they propose.</p><p>Then they feel the need to protect them, like their own children.</p><p>This is when thinking lean becomes about finding the right test that will prove the pre-selected answer.</p><p>It is the mindset that says, I know what is most lean, but I need to justify it so everything can see it.</p><p>So MVP hypothesis testing is oriented primarily around reinforcing the credentials of the one who authored the hypothesis rather than an honest assessment of its value delivery.</p><p>A problem not limited to technologists either but can range across a wide range of personalities and roles.</p><p>But it is how one can claim to be lean by finding the minimal acceptable evidence to advance a theory that they have already set in stone.</p><p></p><h2>4. High Velocity, High Volume</h2><p>One of the most appetizing facets of a lean methodology is the purported ability to &#8220;move fast&#8221;.</p><p>High developer velocity.</p><p>Low time to market.</p><p>This paves the way for more&#8230; features, features, features.</p><p>Imaginative and more visionary personalities can often struggle to balance the influx of new ideas against discipline, focus, and keeping it minimal.</p><p>They can take the &#8220;lean methodology&#8221; to mean that it&#8217;s got the metabolism to absorb a glut of caloric features without gaining weight.</p><p>Even the most scalable and extensible systems architecture can enable and support feature overloading, but at the cost of UX.</p><p>This can tie into plan avoidance, as the stakeholder may simply want to see if such and such a feature works or gains acceptance.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a></p><p>If the technology counterparts can keep up, the number of features is itself taken as the definitive success metric, regardless of its impact.</p><p>The trick with &#8220;lean&#8221; is to find the test that can kill a feature before it proves costly to the company, if it should prove not to be worth the effort. Not to create a runway to load up on features <em>ad infinitum</em>.</p><p></p><h2>5. High Velocity, Low Quality</h2><p>A cousin of the previous mentality is the implicit acceptance of low quality work, particularly technical implementation, just in the interest of getting things out the door.</p><p>This can emerge in a variety of ways.</p><p>One, for the business line that operates out of a sense of constant urgency and last-minuteness, the technical IC is compelled to cut corners on their work, even though they know better. They hold their breath and finish the user story, knowing they have introduced technical.</p><p>Two, perhaps the business line is somewhat patient, but an engineer has mis-estimated the work. They have gone through several iterations, and now it is getting down to the wire, so when they stumble across something that barely works, the engineer will sprint toward that solution and pat themselves on the back for delivering at the eleventh hour.</p><p>Or let us say the product owner or equivalent business stakeholder takes a holistic, architectural mindset to iterative development. In other words, they are sharp and know they need to leave room for systems decisions.</p><p>This can also backfire, particularly in environments where the IC helps draft their own technical requirements.</p><p>Three, the technical IC who wants to minimize the amount of work they need to complete in the short-term will enumerate a long list of reasons or justifications for why they cannot meet certain additional acceptance criteria or systems requirements.</p><p>In their words, it is too darn complicated or difficult, and all the technical gobbedly-gook frightens off the product owner from pushing them any further on it, settling for whatever minimal quality the IC feels like accomplishing.</p><p>Long-winded pushback of this kind can successfully trick managers out of basic technical standards evaluation (e.g. idempotent migrations, retry logic, consistent React state), all because the IC will argue that the low quality technical work is the &#8220;lean&#8221; option.</p><p>Four, on the other end of the spectrum an overzealous engineer can propose an incredibly sophisticated and powerful piece of machinery for their feature, and on the off chance they estimate it somewhat accurately, it seems incredibly expensive and over-extended for them to complete any of these tasks.</p><p>In the interest of being lean, a manager or other stakeholder will thus descope any and all systems considerations to avoid the overengineered approach they are presented with, simply because often those same overzealous ICs have a very hard time self-selecting or prioritizing what is properly most important for systems design or scalability.</p><p>Thus the engineer is overruled because they could not constraint their production-readiness expectations to something acceptable to the business line.</p><p>In all of these, as some of you may be able to tell, a large part of the problem is perhaps due to org structure, roles, responsibilities, and separation of concerns, but all the same, it is easy to see how ostensible concerns about being &#8220;too heavy&#8221; can be used to ignore considerations around quality, sustainability, reliability, or scalability.</p><h2>6. Pennywise</h2><p>When budgets or seed round money are a concern, the myth of building &#8220;lean&#8221; can often find a way to justify saving pennies at the expense of pounds.</p><p>These are often the founders or startup cultures least amenable to the idea of &#8220;you have to spend money to make money&#8221;, perhaps because they have seen that line used to burn entire investor rounds.</p><p>But the idea of building lean can often be used to unnecessarily constrain the technology and talent pool budget in ways that can prove costly in the long-run.</p><p>Hiring junior or nearshore engineers has its benefits, especially when getting off the ground, but it also has its downsides if you want a scalable application with sustainable development velocity.</p><p>Going all in on the managed services for prototyping may seem the cheapest, smart move for avoiding hosting costs, but sticker shock at a minimal Kubernetes cluster may very soon be outweighed by the costs of getting off AWS Amplify or Vercel.</p><p>There is of course a virtue to fiscal discipline that can be lost on many startup executives with a starry-eyed vision and flush with investor cash, but the other extreme may constrain the startup or initiative&#8217;s potential for growth out of a rhetorical to be &#8220;lean&#8221;, when this is a misapplication of what is meant by a process focused on surgical, scientific precision to solve business questions.</p><p></p><h2>7. The Lean Contortionist</h2><p>All of the above myths come out of some sense of reducing or subtracting complexity in order to help build something &#8220;lean&#8221;, even if they misapply the original idea.</p><p>However, there is an entire separate category which has found a way to reinvent something &#8220;heavy&#8221; by virtue of the lean methodology.</p><p>This can arise out of a demand to be &#8220;lean&#8221; enough to be extensible in any and every direction.</p><p>You end up getting buried in a morass of requirements around portability, observability, HA, BC/DR, scalability, OS support, security, compliance, and anything else that can be thought of.</p><p>These can come from senior technical manager or architects who are unable to properly limit the field of vision or constrain their requirements in the traditional MVP sense and thus burden any new digital initiative with a potpourri of non-negotiables so that it is &#8220;lean&#8221; enough to change course to fit any requirements. Another way of just being heavy.</p><p></p><h2>8. Silencing Stakeholders</h2><p>This last one overlaps with many of the above but depending on how evolved or mature an organization is, this is when one feels there are simply too many competing voices in the room, and they feel it drowns out startup focus on rapid iteration and product velocity.</p><p>This can lead executives and managers to unilaterally exclude particular stakeholders from the iteration process, just so the time-to-market doesn&#8217;t have to be bogged down by meetings and perspectives.</p><p>It is not entirely unsympathetic if your governance, regulation, compliance (GRC) stakeholders multiply your iteration cycle by a factor of three or five with very untargeted, generic feedback.</p><p>Or if your infrastructure team is complaining about competing priorities and they will not be able to get around to it until next quarter. And you just want it done.</p><p>Thus the temptation to just opt not to invite those folks to this or that meeting, and tell them you did not want to bother them since you know how busy they are.</p><p>You want a lean, tight, small team to help get your feature or product to production, and the stakeholder bandwagon can get in the way of that sometimes.</p><p>But that is not what lean was proposed to accomplish. </p><p></p><h2>Epilogue: Lean + Platform</h2><p>Some of you may have experience with these species of pseudo-lean, or perhaps others besides those listed above.</p><p>There is no one size fits all to preventing or alleviating these.</p><p>Some of it comes down to properly weighing tradeoffs. Perhaps you do need to go in blind on some things.</p><p>Perhaps it is an issue of org structure and skillsets.</p><p>One way to provide a foundation to build &#8220;lean&#8221; is the premise of <em>platform engineering</em>.</p><p>Out of the hundred or thousand various considerations that can swim around any technologists&#8217; eyes, the IC should be able to work with surgical focus that optimizes the value-delivery of their work while minimizing their need to &#8220;reinvent the wheel&#8221;.</p><p>This is why enterprise architecture, baselines, patterns, self-service infrastructure, platform bootstrapping, all of these provide the ingredients to abstract away many sources of noise or secondary concerns from the developer.</p><p>The security, compliance, infrastructure, and whatever else requirements are moved out of their field of vision and distraction.</p><p>This can help them hit the keyboard running. And build it.</p><p>Lean.</p><h2></h2><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>That of course does not prevent someone stumbling upon such hypotheses or findings by accident, even if they are not strictly following the MVP model.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p> Even if generative AI advances may abstract away the day-to-day complexity of writing software or managing config files, under-the-hood, that complexity is still very much there.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self">3</a><div class="footnote-content"><p>Alternatively, on the other end of the spectrum, a CTO or technical CEO may be so opinionated that there may be no room for discussion at all. The best of these will document and communicate their technical vision to individual team members, but there is often an inverse relationship between technical and communication/management skills.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-4" href="#footnote-anchor-4" class="footnote-number" contenteditable="false" target="_self">4</a><div class="footnote-content"><p>Or worse they may presume that feature will have to be popular and do everything it takes to make that feature gain user acceptance.</p><p></p></div></div>]]></content:encoded></item><item><title><![CDATA[A History of Storage: Database (DBMS)]]></title><description><![CDATA[A survey of database history and its various paradigms]]></description><link>https://tech.ngperrin.com/p/history-of-storage-database-dbms</link><guid isPermaLink="false">https://tech.ngperrin.com/p/history-of-storage-database-dbms</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Thu, 02 Oct 2025 15:51:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mZGN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As we continue this series, looking from a high level at the evolution of persistent storage technologies, we arrive now at the database. More precisely the database management system (DBMS).</p><p>Because of the wide array of systems that can fall under the DBMS, our focus here today is largely on the &#8220;paradigm shifts&#8221; in the field of DBMS technology. Again at a very high level, for those wanting to dip their toes in the water.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h1>CODASYL: The Data Base Task Group</h1><p>For those who have read with us before, <a href="https://tech.ngperrin.com/p/a-history-of-block-storage-mainframe">the introduction of magnetic disks in the 1960s</a> paved the way for many other revolutionary developments in storage technology.</p><p>As data stores scaled, so too did the need to access such data efficiently.</p><p>Traditional block storage access was characterized by physical disk addresses. Memory pointers. Relationships between data were identified by where they lived.</p><p>The management overhead around address management increasingly introduced difficulties that became a priority to remediate.</p><p>In 1959, the Conference on Data Systems Languages (CODASYL) has formed to address technical standardization and developing a common computer programming language.</p><p><a href="https://www.ibm.com/think/topics/cobol">COBOL arose out of this.</a></p><p>The development of COBOL reignited the question of data processing and access standards.</p><p>As part of CODASYL, the Data Base Task Group was formed to invent a new model.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mZGN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mZGN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 424w, https://substackcdn.com/image/fetch/$s_!mZGN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 848w, https://substackcdn.com/image/fetch/$s_!mZGN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 1272w, https://substackcdn.com/image/fetch/$s_!mZGN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mZGN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png" width="850" height="493" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:493,&quot;width&quot;:850,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:63883,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/175102439?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mZGN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 424w, https://substackcdn.com/image/fetch/$s_!mZGN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 848w, https://substackcdn.com/image/fetch/$s_!mZGN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 1272w, https://substackcdn.com/image/fetch/$s_!mZGN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f7191cb-7401-401e-ac94-d228ff5d13e3_850x493.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>By I, Jbw, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=15230892</p><p></p><p>They came up with the <a href="https://www.scribd.com/document/141109399/Network-CODASYL-Data-Model#:~:text=The%20document%20discusses%20the%20Network,of%20complex%20relationships%20between%20records.">Network Data Model</a>.</p><p>The primary idea behind this data model was to replace the hierarchical tree-like structure of traditional data modeling with a more graph-like approach where parent and child records had a many-to-many relationship rather than a one-to-many.</p><p>This would offer low-level power for data access and processing.</p><p>However this model never took off in its own right for a variety of reasons. Foremost though was its rival we will consider next.</p><p>One item worthy of note here is that the CODASYL Network Model was the first to introduce the distinction between a DDL (Data Definition Language) and a DML (Data Manipulation Language) which is so common in the DBMS landscape today.</p><p></p><h1>Origins of the Relational Database</h1><p>The network approach was not the only proposed solution to data processing needs.</p><p>At IBM, in response to concerns about data scaling, a certain Edgar Codd authored a paper <a href="https://www.seas.upenn.edu/~zives/03f/cis550/codd.pdf">&#8220;A Relational Model of Data for Large Shared Data Banks&#8221;</a> in 1970 which proposed representing &#8220;collections of relationships&#8221; that could be accessed independently of memory addressing.</p><p>This concern with the user-friendliness of data access patterns is stated most succinctly here:</p><blockquote><p>Users should not normally be burdened with remembering the domain ordering of any relation (for example, the ordering supplier, then part, then project, then quantity in the relation supply). Accordingly, we propose that users deal, not with relations which are domain-ordered, but with relationships which are their domain-unordered counterparts. To accomplish this, domains must be uniquely identifiable at least within any given relation, without using position. (Codd, 380)</p><p></p></blockquote><p>Codd describes the previous model like this. If there was a data set on cars and their attributes, and if one wanted details on an individual car, they would need to perform address lookups to:</p><ul><li><p>Use an address reference to find the particular Model in a section of addresses assigned to car models</p></li><li><p>Use an address reference to find the particular Make in a section of addresses assigned to makes of the various cars</p></li><li><p>Use an address reference to find the particular Color in a section of addresses assigned to the colors of various cars</p></li><li><p>Etc.</p></li></ul><p>Instead the user should only be required to perform one lookup for the particular car which would then provide a collection of relationships including Model, Make, and Color, etc.</p><p>The practical advantages of this are self-evident. This is Data Modeling 101.</p><p>While Codd propounded &#8220;time-varying&#8221; relationships as the secret ingredient of relational modeling, the more significant proposal was the application of relation theory to computer storage access, i.e. storage access independent of memory addressing.</p><p>From here could emerge the concept of data tables with identifying links between them.</p><p>This offers a greater degree of logical abstraction and flexibility than the CODASYL Network Data Model could. Its favorability increased in conjunction to hardware and networking advances that offset the comparative advantages of &#8220;low-level&#8221; power the Network Data Model had offered.</p><p>Relational data would define the landscape for decades, even to this day.</p><p></p><h1>The Introduction of SQL</h1><p>Codd had introduced an idea, but ideas like a relational data model need to find a way into practical implementation.</p><p>How does one build this new relational database (RDBMS)? How do we get past an index-based addressing system?</p><p>IBM though slow at first on the uptake answered with Structured Query Language (SQL).</p><p>Standardized in 1986/1987, particularly with <a href="https://www.iso.org/obp/ui/en/#iso:std:iso-iec:9075:-1:ed-6:v1:en">ISO/IEC 9075:1987</a>, SQL attempted to accomplish several new things.</p><p>First, it provided an abstraction that allowed the user to access multiple records with one command without needing the address for those records.</p><p>Second, it went beyond the DDL and DML segmentation introduced by CODASYL and identified Data Query Language (DQL) and Data Control Language (DCL) as well.</p><p>Ironically while SQL made great strides in standardization and hardware interoperability, there remains considerable incompatibility between the particular flavors of SQL which themselves may or may not align completely with the SQL standard itself.</p><p>A few of the main household names we will go over now. More depth could be provided perhaps in a future post.</p><ul><li><p><a href="https://www.postgresql.org/docs/current/history.html">PostgreSQL</a> was developed initially in the 1980s at Berkeley to replace the Ingres project that came before it (hence post-gres). Ironically it was not originally a SQL project and went through several name changes and functional changes over the years. In 1994, however it gained its first SQL interpreter and has standardized around it sense. It remains completely free and open source.</p></li><li><p><a href="https://dev.mysql.com/doc/refman/8.4/en/history.html">MySQL</a> was developed by a Swedish company (MySQL AB) around the same time with a release in 1995. Based on the InnoDB storage engine, it would eventually be swallowed up by Oracle in 2010. While MySQL is open source it also does offer proprietary licenses. (MariaDB was an offshoot of MySQL before Oracle&#8217;s acquisition as well.)</p></li><li><p>In the last 1980s, Microsoft sought to establish their own proprietary implementation of SQL, launching <a href="https://winworldpc.com/product/sql-server/10">SQL Server 1.x in 1989</a> targeting Microsoft&#8217;s enterprise customer base while offering editions for other kinds of users and business as well.</p><p></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://tech.ngperrin.com/subscribe?"><span>Subscribe now</span></a></p><p></p><h1>The NoSQL Umbrella</h1><p>SQL was the rage of the 90s.</p><p>But as technology changes, so too do its needs.</p><p>It a testament to the robustness of the SQL and relational model that is remained so definitive and comprehensive for as long as it did.</p><p>In point of fact, needing to categorize very distinct database types such as graph and document under the NoSQL label shows the extent to which the SQL mindset dominated the field.</p><p>By the 2000s, database technologies are moving rapidly in divergent directions.</p><p>We will name a few of the alternative paradigms that emerged and have since become fairly established in the technology world.</p><p></p><h2>Embedded (Key-Value)</h2><p>The embedded database is built around tight coupling with application or hardware logic. It is simple, linear, with low latency. </p><p>As its name indicate, the key-value table features one key mapped to a &#8220;value&#8221; which could include either a very boolean or complex, nested data. In this sense, it is <em>semi-structured </em>data.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fk9g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fk9g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 424w, https://substackcdn.com/image/fetch/$s_!Fk9g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 848w, https://substackcdn.com/image/fetch/$s_!Fk9g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 1272w, https://substackcdn.com/image/fetch/$s_!Fk9g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fk9g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png" width="300" height="203" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:203,&quot;width&quot;:300,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6679,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/175102439?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Fk9g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 424w, https://substackcdn.com/image/fetch/$s_!Fk9g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 848w, https://substackcdn.com/image/fetch/$s_!Fk9g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 1272w, https://substackcdn.com/image/fetch/$s_!Fk9g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d17da0-f552-4f40-9d9a-e5e675dbbfe6_300x203.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Clescop, CC BY-SA 4.0 &lt;https://creativecommons.org/licenses/by-sa/4.0&gt;, via Wikimedia Commons</p><p></p><p>One common design pattern is a &#8220;Single Table&#8221; design which allows the user to forego multiple table lookups for more high performant queries, given the table&#8217;s data model is properly architected.</p><p>The embedded KV had existed in various forms even before the primary SQL vendors.</p><p>One could argue it was first standardized in its own right by Berkeley DB (BDB) which was released in 1994 as part of Berkeley&#8217;s own Unix derivative operating under BSD. While it is difficult to track down primary sources around its launch, <a href="https://www.usenix.org/legacy/events/usenix99/full_papers/olson/olson.pdf">here is a presentation of its logic</a> from 1999.</p><p>BDB was acquired by Oracle in 2006, but its model paved the way for many competitors to develop their own ACID-compliant, high-powered DBMS systems.</p><p>Amazon DynamoDB was one such answer, <a href="https://www.allthingsdistributed.com/2012/01/amazon-dynamodb.html">announced by then CTO Werner Vogels in 2012</a>.</p><p>Each of the major cloud providers has come up with their own proprietary implementation in the years since.</p><p></p><h2>Document</h2><p>The document database is a more nuanced approach to <em>semi-structured </em>data, further defining the key-value model.</p><p>The document database (not to be confused with a file server that stores document files) consists of a very particular sense of <em>document</em>.</p><p>This is tricky to define, because there are no generally accepted vendor-agnostic standards or protocols around this form of database.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> This ambiguity can turn this category more into a catch-all than one with hard-and-fast boundaries.</p><p>What is common across the major product families such as MongoDB, DocumentDB, CosmosDB, and Firestore are a few key dimensions:</p><ul><li><p>A document is a standalone JSON-esque aggregation of data.</p></li><li><p>A document is the unit of both storage writes and storage retrieval with a unique address inside a larger set.</p></li><li><p>A document is schema flexible yet also indexable by fields.</p></li></ul><p>Its primary strength lies in its fast iteration, particularly through hierarchical data. All the data attributes associated with an individual customer for example can be coalesced into a single document unit.</p><p>This provides for stronger horizontal scaling but also richer query power than traditional Key-Value offers.</p><p>However this does come at the expense of low performance for cross-document constraints and queries, but it works fairly well when a document can function as a self-contained microcosm.</p><p>To trace out its history, we can find antecedents in <a href="https://web.archive.org/web/20050112024610/http://www-128.ibm.com/developerworks/lotus/library/ls-NDHistory/">Lotus Notes (1989)</a> and XML DBs like <a href="https://exist-db.org/exist/apps/homepage/timetunnel.html">eXist-db (2000)</a>.</p><p>One Lotus Notes developer left IBM to create a self-funded instantiation of what is generally considered the modern document database: Apache CouchDB.</p><p>From here, the major vendors would kickstart their own versions, but CouchDB has seen widespread success and adoption, even as the backend for the npm registry, <a href="https://blog.npmjs.org/post/167524001790/couchdb-vulnerabilities-and-the-npm-registry.html">vulnerabilities notwithstanding</a>.</p><p></p><h2>Graph</h2><p>While the network data model was set aside in favor of relational data in the 1980s, in the early 2010s graph data, would see a revival under the auspices of widespread social network adoption and the need to think in more network-based data persistence and access.</p><p><a href="https://neo4j.com/news/the-origin-of-neo4j/">Neo4j</a> paved the way for graph data technology by storing data elements as nodes, connected through edges.</p><p>Like DocumentDB there are no official standards around graph database technology, however efforts have been made to define these through <a href="https://www.gqlstandards.org/">Graph Query Language</a> and the <a href="https://www.w3.org/TR/rdf11-concepts/">graph model</a> which articulates the graph relationship through RDF (subject-predicate-object) language.</p><p>While Graph is not necessarily built to handle bulk OLAP workloads it does remain very powerful in terms of its first-class relationships, low-latency queries (at least when well architected), and allows for remarkably flexible schema evolution.</p><p></p><h2>Vector</h2><p>Vector databases are currently extremely hot with the genAI bubble dominating the market at the moment.</p><p>Vector data is unique in that it is not a formal protocol or query language but rather mathematically and algorithmically defined in how it handles the dimensionality of data.</p><p>So it is not possible to say that SQL and Vector databases are alternative options, as vector database implementations can live for example in Postgres with <code>pgvector</code>.</p><p>This goes back further than one would expect to the suggestion of <a href="https://dl.acm.org/doi/10.1145/276698.276876">Approximate Nearest Neighbor (ANN)</a> searches back in 1998. The basic idea of ANN is that it provides criteria for how &#8220;close to the mark&#8221; the query is rather than demanding total precision in what is returned.</p><p>This combined with mathematical representations of data as <em>vectors</em> where each dimension (of which there can be very many) is considered a <em>feature </em>of the data.</p><p>The tech giants each took their stab at this in the mid 2010s with Spotify&#8217;s Annoy for example or Facebook&#8217;s FAISS. But <a href="https://arxiv.org/abs/1603.09320">Hierarchical navigable small world (HNSW)</a> would define the stage of these small graphs</p><p>There are of course other similarity search techniques, but HNSW is the basis for many vector data implementations across major vendors to this day, including Elasticsearch, MongoDB Atlas, and others.</p><p>This combined with the latest generation of LLMs has produced in large part the AI revolution that is currently underway.</p><h1>Futures in DBMS</h1><p>DBMS has come a long way since its introduction alongside the magnetic tape.</p><p>As data continues to grow horizontally, vertically, and in dimensionality, technology will of course innovate to meet the demands impressed upon it.</p><p>There are many different considerations to take into account here, but one interesting prospect is the advent of the <a href="https://arxiv.org/html/2408.03013v1">AI Autonomous DB</a> to further abstract the human from the loop of database development, consumption, and administration.</p><p>As with all things AI at the moment, we will see if we continue to approach the asymptotic curve as the major vendors fine-tune their models, or if another paradigm shift is in the cards to upset the playing field.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to Think further in the Cloud</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>At least that I could find publicly available, please send to me if there are.</p></div></div>]]></content:encoded></item><item><title><![CDATA[Planning Technology Delivery: Thinking it through Backwards]]></title><description><![CDATA[What distinguishes technology delivery from software engineering]]></description><link>https://tech.ngperrin.com/p/planning-technology-delivery-thinking</link><guid isPermaLink="false">https://tech.ngperrin.com/p/planning-technology-delivery-thinking</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Wed, 24 Sep 2025 16:31:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XQiW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XQiW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XQiW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 424w, https://substackcdn.com/image/fetch/$s_!XQiW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 848w, https://substackcdn.com/image/fetch/$s_!XQiW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 1272w, https://substackcdn.com/image/fetch/$s_!XQiW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XQiW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp" width="1200" height="833" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:833,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:50746,&quot;alt&quot;:&quot;Reverse waterfall&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/174441878?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Reverse waterfall" title="Reverse waterfall" srcset="https://substackcdn.com/image/fetch/$s_!XQiW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 424w, https://substackcdn.com/image/fetch/$s_!XQiW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 848w, https://substackcdn.com/image/fetch/$s_!XQiW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 1272w, https://substackcdn.com/image/fetch/$s_!XQiW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b8ae7da-7086-443e-839e-8eb00370e8dc_1200x833.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A reverse waterfall in action</figcaption></figure></div><p>(Image credit: 7NEWS Sydney)</p><p></p><p>Technology delivery is if nothing else, the traversal of that tricky gap between the current state and the desired state of technology operations.</p><p>Of course to even have a desired state presumes that you have invested sufficient time and resources in <em>discovery </em>to identify both what that current and desired state to enough people involved.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> You have pursued that identification to the necessary extent that allows you to establish a broadly accepted &#8220;Definition of Done&#8221;.</p><p>Let us say you have arrived at a reasonable initial expectation of desired state with acceptance from your stakeholders. And you have a sufficiently strong grasp on the current realities of the organization, its teams, vendors, etc. to begin to plan that journey from start to finish.</p><p>One of the marks that distinguishes the architect or technical delivery manager from the software engineer is their ability to think over what this entails, and to exercise it in practice.</p><p>They make things happen.</p><p></p><h2>Environment Management</h2><p>One starting point for thinking over technology delivery is the question of environment management.</p><p>Many who write software, even with years under their belt and enviable comp packages, have simply spent their entire career in localhost.</p><p>When they have met their acceptance criteria locally and pass PR review, they consider their work finished.</p><p>Whatever goes wrong after localhost is someone else&#8217;s problem because it worked locally. A position often reiterated by their business stakeholders.</p><p>But this is a radical limitation of software engineering.</p><p>To think software development in the lens of only one environment.</p><p>Whether the mindset itself is good or bad, to ignore the multi-environment dimensions of cloud applications is debilitating from a systems engineering perspective.</p><p>And there quite a few environments out there sometimes.</p><p>sandbox, rnd, dev, qa, staging, nonprod, preprod, uat, prod-a, prod-b, bobs-env-do-not-delete</p><p>Depending on the organization, the path from local to production can turn out to be a marathon, whose procedures may or may not be documented or socialized.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>It is this gap which can stall projects for months. When the question &#8220;How do we get it to production?&#8221; was asked at the end rather than the beginning.</p><p>Every organization has a process whether they know it or not, if they have something running in production.</p><p>For every environment the organization has between local and production you will need to identify:</p><ul><li><p>Source code/build artifact release process</p></li><li><p>Cloud resource management</p></li><li><p>Environment variable/secret management</p></li><li><p>Credential/key management</p></li><li><p>Domains</p></li><li><p>QA process</p></li><li><p>GRC requirements</p></li><li><p>Approval chain and change management.<br></p></li></ul><p>Organizations with a robust platform strategy can significantly minimize and abstract away the overhead for all these criteria, with mature architecture and service delivery patterns for you to extend.</p><p>Other times, organizations can be rather disheveled when handling this, whether they are new or old. This is especially true if the organization is migrating between IT service delivery strategies or cloud providers while also introducing new workloads at the same time.</p><p></p><p>If you are working through a project one step at a time, perhaps an Agile flow with rapid, narrow, iterative development, you do this at the cost of potentially deferring large, expensive questions around architecture and technology delivery.</p><p>The complexity and time required to corral stakeholders and release requirements and the input of QA, security, infrastructure, or a Change Advisory Board can crush initiatives that are code complete but have nowhere to go.</p><p>Questions that don&#8217;t occur to someone until the end should have been posed at the very beginning. This is one point which Waterfall gets over Agile (at least in practice, if not in theory).</p><p>Hence a key tenet of technology delivery excellence is thinking through it backwards, so to speak.</p><p>You need to be able to envision not just <em>what </em>it needs to be, but <em>where </em>it needs to be and <em>how </em>it gets there.</p><p></p><h3>Thinking it through Backwards</h3><p></p><p>It is simple enough to offer this phrase &#8220;think it through backwards&#8221;, but what does it look like to think in this way?</p><p>The key is that this is a mindset rather than a set of knowledge that can simply be listed.</p><p>Environment management is one of the most generic, comprehensive examples of how technology delivery needs to be thought through from finish to start as well as from start to finish.</p><p>But you can extend this any number of directions.</p><p>The possibilities are infinite, and this itself also tends to confuse professionals.</p><p>What are all the requirements that we need to engineer for to ensure technology delivery to a sufficient degree?</p><p>To reiterate a basic truism: you simply cannot check all the theoretical boxes.</p><p>There is no such thing as the infinite, perfect app.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p><p>The application is a set of finite instructions and requirements.</p><p>Well-engineered technology depends upon embracing the cliche that design is the adjudication of competing trade-offs.</p><p>To be able think through it backwards you must have a very clear sense of what that desired end state is and architect the software or platform accordingly.</p><p>This is something acquired naturally and iteratively through work experience, if you are willing to pay attention and learn from your missteps.</p><p>For some organizations TCO (total cost of ownership) is critical to accepting a new workloads. Other organizations, startups in particular, waive this as a non-material concern until an investor or board flags the OpEx.</p><p>GRC can be a primary concern in some organizations, a secondary or tertiary consideration in others.</p><p>QA and SRE may have right to veto release in some companies, or live in perpetual reactive mode in others.</p><p>The stakeholders you are working with as well as your project sponsor, and their chain to leadership, should most directly inform the prioritization of these factors not only in architecting the application but in gaining stakeholder consensus to ensure its delivery.</p><p>You can extend past experience to inform these questions, but you should not trust it completely. Things change between and within organizations. Stakeholders move around or out. Budgets change. Technology trends, vendors, and market forces can impact the stakes of your technology delivery.</p><p>This is why even if one were to catalog all of the various possible &#8220;finish line&#8221; items you should think about, it would not remain clear which are material or relevant for your use case.</p><p>Technology delivery is a continuous learning and planning cycle. You have to stay up to date on what is going on among people and process and technology. Losing sight of these can invalidate your whole plan.</p><p>You must spin a spider&#8217;s web to lightly but tightly tie together often vastly different departments. And that web must be maintained as requirements shift, turnover occurs, and even if project sponsors change. So long as you remain committed to your mission of executing delivery.</p><p>Keep asking yourself, where your north star is for your project and how you can reverse engineer your path to getting there.</p><p></p><h3>Questions to Ask Yourself</h3><p>To provide at least some specificity to this mindset, here are some questions you could consider as part of adopting this mindset:</p><ul><li><p>What is the most immediate step that would come before this final objective?</p></li><li><p>Who or what is a gatekeeper to my ability to cross a delivery milestone?</p></li><li><p>Are there comparable examples to my initiative, a tale of success that provides a clear chain of execution for technology delivery?</p></li><li><p>Are there lessons learned from that comparable example have other material factors changed? </p></li><li><p>Conversely have there been any comparable earlier initiatives like this one that have failed or been suspended? For what reasons?</p></li><li><p>Based on the friction or time investment certain questions face, which considerations are worth deferring until the &#8220;rubber hits the road&#8221;? To what extent can I carry out a best effort analysis and document decision making here?</p></li><li><p>Which stakeholders do I need to involve now to minimize later delays? What stakeholders even want to be involved now? How do I document this?</p></li><li><p>Who is most knowledgeable in this organization or BU about getting things done? Seek the high signal-to-noise ratio individuals who can convey accurate information efficiently and forthrightly.</p></li><li><p>If working with a new technology library or provider, what open source information is available around production bugs (e.g. GitHub issues), which ones are most material for my use case?</p></li><li><p>Based on team and personnel resources, how they are allocated, and the business sponsors of that allocation, what will be the relative velocity of various teams in completion of their objectives. Will some drag behind others? How can this be remediated or documented?</p></li><li><p>What teams and which team personnel need which level of detail on architecture, delivery particulars, etc. ? Do not inundate the junior dev with timelines. Do not flood the product owner with architecture. Know the audience and consider which items of information is crucial for individual personnel to meet their work commitments. Technical verbosity can lead more often to losing someone&#8217;s ear than gaining it.</p></li></ul><div><hr></div><p>These may come as obvious questions to some, but it is easy to forget these in practice.</p><p>Waste emerges in many forms across technology spend.</p><p>Lack of delivery alignment is one of the most common and preventable contributors to waste and delays I have observed in my time. </p><p>A robust and clear-headed sense of how to get X to Y is not an easy thing to communicate and learn, but such a capacity can save organizations immensely.</p><p></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Desired state is of course also fairly difficult to discern. Practitioners know how hard it is to get multiple stakeholders to align on an end state, or for that matter even for a single stakeholder to stick to the same picture for more than one meeting.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>There is an irony that while so much of computing technology has been standardized over the decades, there is not a single, definitive framework or model for environment management in depth. No RFC, no NIST standards. ITIL and of course NIST SP 800-53 explicitly require a separation between &#8220;prod&#8221; and &#8220;non-prod&#8221; but that is the extent of the control.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self">3</a><div class="footnote-content"><p>One example of such a rabbit hole: Is your document processing microservice able to reconstruct corrupted document payloads with non-UTF encodings for a dead language with readily configurable integrations for Amazon Kinesis, Kafka, RabbitMQ, and IBM MQ all while developing its own post-quantum encryption algorithm to secure data? (With an in-process, automated counter-pentest agent)</p><p></p></div></div>]]></content:encoded></item><item><title><![CDATA[Notes after Passing All 12 AWS Certification Exams]]></title><description><![CDATA[Guides, hints, tips on general methods for passing all AWS certification exams]]></description><link>https://tech.ngperrin.com/p/notes-after-passing-all-12-aws-certification</link><guid isPermaLink="false">https://tech.ngperrin.com/p/notes-after-passing-all-12-aws-certification</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Fri, 15 Aug 2025 03:06:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!lTW1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lTW1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lTW1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 424w, https://substackcdn.com/image/fetch/$s_!lTW1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 848w, https://substackcdn.com/image/fetch/$s_!lTW1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 1272w, https://substackcdn.com/image/fetch/$s_!lTW1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lTW1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png" width="845" height="531" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:531,&quot;width&quot;:845,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:22112,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/169317253?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lTW1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 424w, https://substackcdn.com/image/fetch/$s_!lTW1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 848w, https://substackcdn.com/image/fetch/$s_!lTW1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 1272w, https://substackcdn.com/image/fetch/$s_!lTW1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9aa9d08-3521-4947-9ca7-f4979cb4a12a_845x531.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>I recently had the dubious pleasure of passing through the gauntlet of AWS exams and emerging certified in all 12 AWS certifications (plus some other retired ones).<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> I am fortunate enough to have passed them all on the first take, though the Networking Specialty was a close call.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://tech.ngperrin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>While the Internet may off you an abundance of material on the <strong>subject matter </strong>of these exams, I do hope to provide some thoughts and reflections from my own experience that may guide your path as you embark on this struggle with the AWS certifications process.</p><p>Jump to a question of interest to you, and I hope it proves helpful. Good luck.</p><p></p><h1>Why are you taking an AWS exam?</h1><p>SEO content farms have sections with this title as well, but there is a point to asking this question here.</p><p>You must weigh the cost of these exams.</p><p>Unless your employer can bankroll the exam process, you must weigh the cost of the exam(s) you are planning to take. Even if they are paying for the exam fee, you must still invest time, and not just time in a general sense, but that valuable quotient of highly-focused and highly-energized mental state that can be hard to come by.</p><p>If you are cognitively drained or worn out, you simply will not be able to prepare for or take the exams, even if you engage with AWS services on a daily basis.</p><p>Furthermore, if you do pass the exam, the AWS certification will last three years. In most cases, you will need to sit the exam again and pay the exact same fee in three years time, just to hold on to the title. This is the AWS version of Continuing Education Credits.</p><p>There are at least five distinct, general reasons to take the exam:</p><h3>1. Career Launch</h3><p>This is in my view the most justified reason to take the AWS exams.</p><p>If you are needing some form of resume bump to initiate a career transition into technology, this is a legitimate strategy. It was mine.</p><p>I was a humanities major with a few years of professional experience in nonprofit operations. I had taught myself a few programming languages in this time.</p><p>But the critical push that enabled my true technology career launch was having freshly minted AWS certifications to decorate my resume and profile.</p><p>It started with small upwork.com projects and escalated from there.</p><p>However, to repeat commonly iterated advice, certifications do not get you the job, but they do get you the interview. And that is the crucial step often enough.</p><p>So one should not expect to be handed a job or comfortable contract upon earning their AWS laurels, but it can smooth your path.</p><p></p><h3>2. Career Advancement</h3><p>Let&#8217;s say you have landed, so to speak, in your desired career track that can afford you progression to your professional north star.</p><p>There can be an impression that AWS certifications can provide you the opportunity for a promotion or vertical move.</p><p>From my point of view, I do not think this is true, unless the position you are aiming for specifically and explicitly names the AWS certification in the JD.</p><p>I say this from two vantage points.</p><p>First, in my experience from dozens of interviews for client projects or job roles, it is very rare for the initial screener, the second round, or the round table to ask about certifications. The only occasions it has come up is when third-party recruiters remark a specific certification is on the JD. There is not a general interest for cert collectors.</p><p>Second, I have had a number of conversations with various online HR experts and accounts who have deep history with recruiting pipelines. None of them indicated that certifications played a decisive role in their hiring hierarchy.</p><p>Experience, societies &amp; publications, and even degrees play a far greater role on that front.</p><p>So if you are already &#8220;in&#8221; technology, it is in many cases far more strategic to invest in resume-building projects or society memberships than AWS or other cloud certifications.</p><h3>3. Learn AWS Better</h3><p>One might want to leverage the AWS certification process as a way to learn AWS better.</p><p>This is probably the least efficient justification for taking an AWS exam.</p><p>You are far better off exploring the plethora of AWS-provided workshops and resources or the equally bountiful array of challenges and puzzles published by individuals or communities.</p><p>The AWS documentation even offer example use cases for just about every facet of the platform. And you can evolve off their &#8220;hello world&#8221; scenarios with ease.</p><h3>4. APN or Sales Benefits</h3><p>The Amazon Partner Network (APN) offers special tiers and branding for those partners who have more certified individuals. An internal incentive to push the certifications program.</p><p>If acquiring an AWS certification advances your sales machine, that is fine. As long as you understand the inputs you are providing to make that happen.</p><h3>5. For the challenge</h3><p>This was my reason for this most recent gauntlet.</p><p>I floated a while between 5 and 7 AWS certs before letting them lapse.</p><p>But after concluding my previous role and needing a productive outlet while new prospects emerged, I decided upon pursuing all 12 AWS certifications.</p><p>This is truly a challenge, but a great discipline builder. Knowing that you are investing dozens of hours in preparation for a somewhat arbitrary exam that is not connected to hands-on experience. Preparation that drains your mind and inhibits your ability to be productive on other things.</p><p>Exams that cost money, even if potentially tax-deductible.</p><p>I will be honest and say that I do not plan to renew these certifications outside the Professional level unless the incentive structure changes in some way.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a> </p><p>For myself at least. You may feel differently in considering your path.</p><p></p><h2>Which AWS exams do you plan to take?</h2><p>There are several considerations worth thinking through with this.</p><p>Like I mentioned above, HR and recruiters are very targeted about the certifications they are looking for, if any at all. Certification collecting is the equivalent of putting buckets out in the rain to collect water.</p><p>It is better to be focused and strategic about which AWS exams you choose. Even an individual one is fine. Or you could do targeted combinations like:</p><ul><li><p>Solutions Architect Associate + Professional</p></li><li><p>AI Practitioner + Machine Learning Associate + Machine Learning Specialty</p></li><li><p>CloudOps Associate + Developer Associate + DevOps Professional</p></li></ul><p>This can be advantageous for a couple reasons.</p><h3>1. Renewals</h3><p>When Professional Certifications renew, their Associate counterparts renew as well. Unlike Azure certifications, AWS will make you pay up and take the whole exam to renew your certification. However, if you stick with a particular bundle, like the ones listed above, you would only need to renew the one Professional-level to hold on to the Associate level.</p><h3>2. Content Overlap</h3><p>If you are taking particular exams in rapid succession, this is also useful.</p><p>While it occurs less frequently than you&#8217;d expect, closely coupled AWS exams will feature near-identical questions.</p><p>I took the Machine Learning Associate and Specialty back-to-back, and I was surprised by how much the two exams had in common. (More on that later.)</p><p>Because the exams are more-or-less focused on your ability to recall AWS best practices and patterns, this can reduce the amount you need to learn during preparation.</p><h3>3. Certification Shelf Life</h3><p>There is a running joke that Google likes to shut down products and services nearly as often as they start them.</p><p>AWS has in the past few years seemed to adopt this methodology, not least of all to its AWS certifications.</p><p>In 2022, I had taken and passed the AWS Database Specialty and AWS Data Analytics Specialty, both of which have since been decommissioned. The AWS SAP and AWS Alexa Specialty exams have also both been shut down since I first started exploring AWS certifications.</p><p>It is mid-2025, and I am convinced that AWS Machine Learning Specialty will be put down soon as well.</p><p>Some certifications are simply more forward-facing than others. In 2025, AI Practitioner is one of those. The SysOps Administrator is getting rebranded as CloudOps Administrator.</p><p>You can also tell in the exams themselves which one is newer. While the curators who review AWS certification questions do a remarkably good job making sure outmoded services or approaches do not linger on in exam question, you can still tell when an exam iteration was launched.</p><p>The Data Engineer Associate and Machine Learning Associate exams though at the Associate level have a far more up-to-date of AWS offerings and cloud strategy than their Specialty counterparts.</p><p>Pay attention to that when deciding which ones to take. If you like.</p><p></p><h2>Venue: How do you plan to take the exam?</h2><p>This is more important than it sounds.</p><p>At this time, you can take an AWS exam either from a Pearson VUE testing center or from the comfort of your home.</p><p>I am honestly on the fence which of these two is better.</p><p>The online option can be a hassle because the Pearson VUE proctors are radically stringent on protocol in extremely arbitrary ways.</p><p>If you take the exam from your workstation, you will have to dismantle much of your desk to clear it off, remove extra monitors, and make sure no &#8220;content&#8221; is visible from any angle in the room.</p><p>The first time I had taken the DevOps Professional exam, the proctor noticed a painting I on the back wall and demanded I take it down, even though it was nailed in. This was all the more surprising because I had taken three other AWS exams from that same room where that was not a concern.</p><p>Beyond the initial screening, you are monitored rather closely. They will interrupt your exam and call you if you have your hand over your mouth during the two to three hour exam window.</p><p>But most importantly, you are not allowed to leave the room whatsoever. Restroom breaks are not permitted whatsoever if you are doing the online proctoring option.</p><p>This becomes far more obtrusive during the three hour examinations (which include another thirty minutes for check-in), and I have had to rush to finish exams early because of this.</p><p>By contrast, the in-person test centers can vary rather dramatically. If you live in a metropolitan area you can see for yourself how much this can be the case. Some are in basements, while others have windows. Some have sound machines. The proctors can have varying dispositions, ranging from conciliatory to neutral to DMV hostile.</p><p>The main factor for me are your neighbors in the shared exam room. </p><p>You will most likely be in a room with other exam takers sitting close beside you.</p><p>For whatever reason, these professional certification exams tend to attract individuals who are unable to resist making strange noises or talking to themselves during the exams. This was distracting for me for the examinations I took in person, to the extent I could not help looking over to see if the individual&#8217;s unusually punctuated breathing was a faint request for medical assistance.</p><p>But you do get restroom breaks at these testing centers, and you far less at risk for having your exam disqualified for arbitrary reasons than if you take them from your residence.</p><p>So weigh that in mind.</p><p></p><h1>Strategies</h1><p>Now that we have taken into account a few preliminary questions, I would like to suggest a few strategies for preparing for and taking these AWS certifications.</p><h2>Test Prep - AI Assistants</h2><p>First I would like to say that Tutorials Dojo is by far the gold standard when it comes to AWS certification practice exams. They offer the most rigorous and realistic simulation of the AWS exam experience, to the point that I am surprised they are allowed to simulate such an accurate reflection of exam content.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a> </p><p>Beyond that though, I am deeply indebted to AI assistant tools for helping prepare me for the most difficult Specialty exams. If you supply the appropriate AI assistant with the exam content guide and give it a few sample questions, it does a profoundly excellent job of generating practice questions for you.</p><p>I have done this to help identify general preparedness, then to isolate areas of improvement, then to cover specific domains or services or service features I needed to brush up on.</p><p>I will not provide the prompts or context I used to achieve this, but if you are interested, you can invest some time in identifying this yourself.</p><p>However, this does come with a strong caveat. If you provide it with practice questions yourself, it has a moderate chance of hallucination.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a></p><p>But if you are verifying the answers yourself and continuing to feed it documentation, you will find it is a strong partner to coach you question-by-question to prepare you on the knowledge required for the exam.</p><h2>The Exams Play Favorites</h2><p>With any professional certification, there is an ongoing debate over how much that certification really does equate to &#8220;real life experience&#8221;. In my eclectic experience across developer, DevOps, cybersecurity, and management roles, I will say the AWS certification exams really do very little to prepare you for the real world.</p><p>Part of this is because (like most exams), the real world gives you free access to the Internet, documentation, and now for the most part AI assistants.</p><p>But another part of this is because the multiple-choice structure of the exam lends itself to a fairly opinionated outlook on what constitutes the &#8220;right&#8221; answer. This can be a world of a difference depending on the exam you are taking.</p><p>The most overt example of this is the AWS Data Engineer Associate and AWS Machine Learning Associate exams.</p><p>In the AWS Data Engineer Associate Exam, the answer that names AWS Glue is nearly always the right answer. That service is the gold standard for that exam.</p><p>In the AWS Machine Learning Associate Exam, the answer that names a SageMaker tool is nearly always the right answer, especially if AWS Glue is an alternative choice. It is actually fairly tricky how some questions will make AWS Glue sound appealing in the ML exam, but only to trick you. The answer explanations on those practice exams explain why SageMaker &#8220;is a better fit&#8221;.</p><p>So get to know the community of your exam, because it actually does consist of a fairly opinionated set of tools. Even on the wide-ranging Solutions Architect Professional, there is a gamut of AWS service that will simply never be mentioned from virtue of being too obscure to be noteworthy.</p><h3>The Types of Questions</h3><p>Aside from subject domain, there are a number of different kinds of AWS questions. You can actually identify the answer to the question based off a few &#8220;meta&#8221; considerations, without knowing anything about the subject matter or content of the question.</p><p>You can categorize 90% of AWS questions as:</p><ol><li><p>Do you know AWS basics?</p></li></ol><p>There is a question about IAM and S3 in just about every exam.</p><ol start="2"><li><p>Do you know the most AWS managed approach?</p></li></ol><p>AWS wants vendor lock-in. Therefore your answer should also be the most conducive to vendor lock-in. The custom, roll-your-own solutions are almost always the wrong answer. Picking the most AWS-managed option is a very likely right answer, excepting a few edge cases.</p><ol start="3"><li><p>Do you know which suggested approach aligns with the key priority for this question</p></li></ol><p>Many of the intermediate to expert level difficulty questions will have a paragraph or two introducing the situation, but it always best to start with the one sentence closer at the end of the question. This will identify the key priority for the question:</p><ul><li><p>&#8220;What is the MOST cost efficient approach?&#8221;</p></li><li><p>&#8220;What is the MOST operationally efficient approach?&#8221;</p></li><li><p>&#8220;What is the MOST secure option?&#8221;</p></li></ul><p>It is absolutely critical to use this lens when scanning both the questions and answers. There are a handful of cases in exam questions, when a generally acceptable answer is actually incorrect because the question is looking for more very specific priority.</p><ol start="4"><li><p>Do you know this technical domain independently of AWS</p></li></ol><p>There are a handful of questions surrounding encryption or DNS or machine learning algorithms which you will immediately have an answer to if you have a theoretical or practical grasp of its underlying concepts.</p><p>Technical knowledge irrespective of AWS will give you a shortcut to the answer.</p><ol start="4"><li><p>Have you lived through this very specific scenario. If so, when does the AWS UI show at step 3?</p></li></ol><p>There are a small handful of edge case questions which you can tell are supposed to be the most difficult ones out there. Unless you have battlefield experience with that specific item they are asking about, you will not know the very specific thing they are asking for.</p><p>If you in fact have had that experience, you will feel rather clever for knowing the answer.</p><p>But these are a small proportion and you do not need all of these to pass the exam, unless you are struggling on basic or intermediate items.</p><h3>Miscellaneous</h3><p>A few other test-taking strategies I would like to note for the exam-taker</p><ul><li><p>If the question is particularly long, it is worth starting by reading the answer choices. Sometimes the answer choices are also long and nearly identical, but this is a good thing. You can use to identify what makes each answer choice *different* from one another, and this makes it easier to eliminate the incorrect options.</p></li><li><p>If you are struggling with a question, it is generally best to try to eliminate the answer choices down to two options (or sets of options) then review the question and see either if (1) you can identify a key architectural concern like cost optimization or security or (2) if you can visualize the technical specific steps because there is often a trick that can eliminate the wrong answers.</p></li><li><p>Depending on your pace and time remaining, it is okay to skip questions without reading them and then return to them later. If I was two-thirds through an exam and encountered a three paragraph question, I would invariably flag it and come back at the very end when I knew I could focus on it. Not all questions are equal in difficulty and it may be worth sitting on the most difficult ones until there are no others remaining.</p></li><li><p>Remember that you do not need to get every question right, and also remember that roughly ten questions on your exam are not even scored. Be familiar with the estimated pass rate metrics for your exam so you have a comfortable sense of how many questions you can miss. Aiming for 100% accuracy will do more to obstruct your psychologically than to help you hit your goals. Think in terms of 80:20 Pareto optimization to be able to reach a threshold to pass the exam.</p></li><li><p>Sometimes the answer to one question may accidentally be revealed in another exam question, further down the line. This has happened to me more than once. If you realize during the exam, you have gaps, try to construct answers from the knowledge base provided to you in the exam questions.</p></li><li><p>Know your reading speed. The word counts on these exam are heavy, especially if you are on the Professional exams. That is honestly one of the largest contributors to the cognitive difficulty of the exam experience (and also why the Cloud Practitioner exam is a breath of fresh air by contrast). If you are a fast reader, that certainly works to your advantage. If English is not your first language, make sure to exercise the testing accommodation for extended time. Regardless, reading the end of the question and answers first before reading the bulk of the question can help save you some time and reading energy on each individual question.</p></li><li><p>Unless you are taking a Foundational exam, you will not be told your results immediately upon finishing the exam. So do not expect to find out right away. However, for all the exams I took this year, I got the results in about 12 hours or so, depending on if I took the exam online or in a practice center.</p></li></ul><p></p><h1>Conclusion</h1><p>These words are offered up in the hopes that they may prove useful or advisory for those considering AWS certification exams or preparing for them.</p><p>My experience is my own, and I cannot pretend that you will have the same experience if you choose to go through a gauntlet of twelve, three, or even one individual exam.</p><p>I merely wish you the best of luck on your endeavor as you build your cloud career.</p><p></p><p></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>A screenshot of my AWS IQ profile. AWS IQ is a platform for third-party freelancers and agencies to connect on specific projects.</p><p>AWS IQ is an excellent venue to advertise services as an IC, and it does provide an ostentatious view of AWS certifications. Yet, see footnote 2.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cE0e!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cE0e!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 424w, https://substackcdn.com/image/fetch/$s_!cE0e!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 848w, https://substackcdn.com/image/fetch/$s_!cE0e!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!cE0e!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cE0e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png" width="668" height="694.4180790960452" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1104,&quot;width&quot;:1062,&quot;resizeWidth&quot;:668,&quot;bytes&quot;:213008,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/169317253?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cE0e!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 424w, https://substackcdn.com/image/fetch/$s_!cE0e!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 848w, https://substackcdn.com/image/fetch/$s_!cE0e!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!cE0e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb841d51d-6f01-448a-a279-e1bce43c6904_1062x1104.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You will note the two Foundational exams do not display here, but this is made up for by the discontinued Database and Data Analytics Specialty exams which I had taken previously.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>I was planning on expanding my consulting leads pipeline through AWS IQ&#8212;their official service for third-party experts. However, while I was in the midst of passing these exams, I discovered that AWS announced its intent to shut down the platform. So that motive was rendered nugatory.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self">3</a><div class="footnote-content"><p>That said, in 2025, their practice exams are starting to show their age. I do not blame them for being unable to keep up with the AWS question machine, but you do notice the practice tests they have for older AWS exams are loaded with questions that no longer make sense or line up to the modern AWS experience.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-4" href="#footnote-anchor-4" class="footnote-number" contenteditable="false" target="_self">4</a><div class="footnote-content"><p>There are tricky questions in the AWS exams, but for example I was surprised not only that `o3` failed to identify what envelope encryption is, but when I pulled the same question up today, `GPT 5`failed in the exact same way, selecting the answer which indicated the top level key should be encrypted.</p></div></div>]]></content:encoded></item><item><title><![CDATA[The Purpose of the Prototype]]></title><description><![CDATA[The Art of Requirements I - Pet Projects vs. POC]]></description><link>https://tech.ngperrin.com/p/the-art-of-requirements-gathering</link><guid isPermaLink="false">https://tech.ngperrin.com/p/the-art-of-requirements-gathering</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Sat, 28 Jun 2025 21:20:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hJkW!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5ce81b0-f183-4bbd-a2b4-78bc2ac0c6ac_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Recent advances in LLM technology have raised the perennial specter of job displacement for those knowledge workers concerned with the development of new software platforms and technologies.</p><p>Yet unless such AI agents can break past the asymptotic boundary of their current intelligence and move a gradation or two closer to the threshold of AGI, the development and maintenance of software systems may be assisted but not fully usurped by agentic workflows.</p><p>Generative AI can perform a variety of low level tasks to an acceptable level within a condensed amount of time, but one dimension that even the latest and greatest models at this time are nowhere near managing is architecture, software and otherwise.</p><div><hr></div><p>Solutions architecture is concerned not with the building of technology for its own sake or to satisfy the tinkering itch of its engineer,  nor with the isolated perfected piece of technology to live and exist in an isolated cell, nor even to prototype a MVP to force the hand of stakeholders into technology adoption.</p><p>Each of these can and often do happen.</p><p>Solutions architecture ought however to be charged with the responsibility of building not just well in the abstract but in the concrete. Just as a building cannot be erected without considering the slope or stability of the ground or the surrounding buildings, so too digital solutions must pay a nearly obsessive attention to context.</p><p>That is why the first step of solutions architecture is to understand the organization as it exists now and in the future.</p><p>Even the most greenfield of projects&#8212;freed of seemingly ever constraint to roam free in the name of prototype or R&amp;D&#8212;must still be embedded in a <em>field</em> of some kind, if its seeds are going to take root.</p><p>If your solution is part of a brand new LOB or BU, you will still be constrained by IT governance.</p><p>If your solutions is part of a dedicated Rapid Prototyping team with a direct line to the CEO, even your silo must prepare to accommodate compliance, SLA&#8217;s, and the hasty innovator&#8217;s worst nightmare: Site Reliability Engineering.</p><p>If your solution is part of a brand new company with zero tech debt and seed money for a brand-new totally from scratch green-as-the-grass first-time prototype, your solution will still be constrained by CEO and investor expectations and the criteria by which your product can with sufficient truthfulness be labeled a MVP that has reached the market.</p><p>Any development initiative without a distinct and laser-focused vision of that <em>rubber hits the road</em> moment of integration, when something becomes &#8220;production&#8221;, will likely founder even in the hands of the most skilled technicians and product owners. </p><p>Many will not see the light of day, or enough of that daylight to be considered a living, breathing, viable system.</p><p>Pet projects, prototypes, proof-of-concepts remain what they are, not &#8220;Ready for Production&#8221;.</p><p>This is not to say that such tinkering toys or half-baked projects are without value.</p><p>They are in fact very instrumental.</p><p>The greatest masterpieces of visual and literary art are often the successors of many sketches or &#8220;stillbirth&#8221; pieces. The crumpled up pieces of paper that are discarded become like rungs of a ladder. They have served their heuristic purpose in helping sharpen and hone the vision and focus of the artist or technicians to accomplish the final task.</p><p>Prototypes and proof-of-concepts are immensely powerful tools to advance the mission, to build solutions without the weight of overthinking. To try by doing and advance past the tempting dance of navel-gazing among opinionated stakeholders.</p><p>But the point is, if there are aspirations that your solution, your prototype is going to become something more, you must aggressively wrestle with the question of what you are prototyping toward.</p><p>As simple and glib as it may sound, you must ask what is the problem your solution will solve and <em>how </em>it will come to do so.</p><p>What makes a solution effective is that it does come into effect. It produces. It makes things happen.</p><p>So to build a solution requires the marrying of the future and present. It requires an upfront wrestling with properly contextualized questions: what does it mean to be production ready <em>here</em>? What does it mean to be production ready in light of general principles and best practice? What is the concrete roadmap to launch? To iterate? Who pays the bills? Who are the stakeholders?</p><p>That kernel of novelty your solution will introduce, that must be sown in light of these questions. If you want to be smart about it.</p><p>Of course, many can get away with a Series X investment round or a chain of promotions without really bothering with these considerations. Many battles in history have been won by the less-than-perfect, simply by virtue of right place, right time. Or by hanging around long enough.</p><p>But there is a difference to doing something and doing something <em>well</em>. The art of solution architecture is concerned with doing the thing well. And that requires forethought and planning.</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[A History of Storage: Files]]></title><description><![CDATA[From Multics to NFS and beyond]]></description><link>https://tech.ngperrin.com/p/a-history-of-storage-files</link><guid isPermaLink="false">https://tech.ngperrin.com/p/a-history-of-storage-files</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Thu, 24 Apr 2025 22:00:39 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1a6c4f7f-52f9-42e5-9508-d32de122042d_1440x956.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is a series exploring the history of persistent storage systems in the world of computing. Previously, <a href="https://tech.ngperrin.com/p/a-history-of-block-storage-mainframe">we covered block storage</a>.</p><p>Today we go into the world of files.</p><p>Files are an interesting choice in how the world of computing evolved. A useful abstraction on one level that is yet simultaneously a notorious agent in complexity for technologists to interact with.</p><p>The world is driven by files. Some have said &#8220;Everything is a file&#8221;.</p><p>We shall follow this journey.</p><p></p><h1>The First Files</h1><p>Like many digital-focused terms, files have their start in the tangible world.</p><p>In Latin, <em>filum </em>can refer to a thread or string, or more ominously a cord of fate. In the fifteenth century <a href="https://www.etymonline.com/word/file">legal professionals would sometimes use </a><em><a href="https://www.etymonline.com/word/file">filing</a></em><a href="https://www.etymonline.com/word/file"> strings</a> to keep track of their documents, hanging them up for ease of reference.</p><p>The file is not merely attached to a document but as a sorting technology for preserving and maintaining the organization of information, particularly for future reference by the user or others.</p><p>As punch card computing was developed in the 1940s, the term &#8220;file&#8221; quickly came to be used in reference to how the punch cards themselves were organized as files inside filing cabinets.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WBqg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WBqg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 424w, https://substackcdn.com/image/fetch/$s_!WBqg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 848w, https://substackcdn.com/image/fetch/$s_!WBqg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 1272w, https://substackcdn.com/image/fetch/$s_!WBqg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WBqg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png" width="704" height="972" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:972,&quot;width&quot;:704,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:317695,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161930109?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WBqg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 424w, https://substackcdn.com/image/fetch/$s_!WBqg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 848w, https://substackcdn.com/image/fetch/$s_!WBqg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 1272w, https://substackcdn.com/image/fetch/$s_!WBqg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20fa082a-decb-4a41-abe7-4ca3dbd6cc07_704x972.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Eckert, W.J. <em>Punched card methods in scientific computation. <a href="https://hdl.handle.net/2027/mdp.39015075955537?urlappend=%3Bseq=16%3Bownerid=13510798895635973-20">Link</a>. </em></p><p>By 1956, <a href="https://ed-thelen.org/comp-hist/BRL61-ibm03.html">documentation for the IBM 305 RAMAC</a> referred to its hardware as containing &#8220;disk files&#8221;.</p><p>However, the advent of a computer file system did not come in full force until the development of Multics.</p><p></p><h1>File System Pioneering: Multics EFS</h1><p>Multics was an MIT project that began in the 1960s and was the first computer architecture to take a serious stab at developing a files system. Before its release, EPL developers were given documentation to begin building with Multics &#8220;logic&#8221;.</p><p>The 3000 page Multics System Programmers&#8217; Manual (MSPM), section BE.10.00 &#8220;<a href="https://multicians.org/mspm/be-10-00.660510.elementary-file-system.pdf">The Elementary File System (EFS)</a>&#8221; documents the first proposals around such a preliminary file system, supplanted by a revision BE.10.01 the following month.</p><p>Before this point, block storage with tapes and disks was the primary storage mechanism that computers could work with. This was raw addressable chunks of memory without much abstraction.</p><p>Block addresses needed to be manually managed and were coupled to the hardware, a fairly error prone process.</p><p>No abstraction meant no file metadata, no I/O coordination, no lifecycle management, or access controls.</p><p>EFS introduced several important innovations which would become staples in the world of files:</p><ul><li><p>Hierarchical structure for files and file metadata via pointers.</p></li><li><p>Logical records and word-level addressing for random/sequential access and offset support, abstracting out the physical layout of the drive.</p></li><li><p>I/O Mode flagging to declare files as permanent, foreign, or temporary using bit-flags, an early form of file attributes</p></li><li><p>A unified read/write model with Open/Write/Read/Close operations clearly defined.</p></li><li><p>Bit flags for EOF (end of file), EOR (end of record), or error reporting</p></li></ul><p>Now we begin to see file type semantics that speak to lifecycle (Temporary, Permanent, Foreign) and more abstraction and interoperability that are central to the &#8220;files&#8221; package.</p><p></p><h2>A Second Take: Multics Basic File System</h2><p>The EFS was merely a prototype in the end. Multics ended up taking these preliminary elements and building out a far more comprehensive file management solution in their final Multics solution.</p><p>We see in BG.0 &#8220;<a href="https://multicians.org/mspm/bg-0.661213.basic-file-system-overview.pdf">Overview of the Basic File System</a>&#8221; the unpacking of this new paradigm.</p><p>The Multics Basic File System consists of segments (files) and memory-resident page and segment tables. This is paired with a multi-level storage management system for infrequently accessed data or for backup data that would be sent to offline devices.</p><p>The segment is the heart of the novelty here. It is a linear array of data that can be accessed with implicit memory references (like block storage) or explicitly with read/write system calls (like file addressing).</p><p>It also added a number of controllers that managed the segments, directories (symbolic naming), access controls, page control, core (memory) control, and device interface modules (DIMs) to abstract I/O interactions.</p><p>But from a long-term perspective we see two other key ideas implemented here.</p><p>First, concurrency and fault handling. For the first time an abstracted layer of locking mechanisms, page faults, and segment faults were implemented to protect the file systems from concurrent writes or handle for other potential errors.</p><p>Second, we see user-based Access Control Lists (ACLs), a model we will dig into a bit further here. </p><p>As specified in <a href="https://multicians.org/mspm/bg-9-00.680116.access-control.pdf">BG.9.00</a>, when a user attempts to access a directory branch, the Access Control &#8220;determines the [effective access] mode of the user with respect to this branch and returns this mode and the ring brackets&#8221; to the Directory Control.</p><p>There is an apparent mode and an effective mode.</p><p>The apparent mode is concerned with the read, write, or execute permissions available to the user or group (generic user).</p><p>The effective mode governs access itself and is produced through the ring brackets.</p><p>The ring brackets define the range of privilege levels under which the segment may be accessed or called. It is composed of three integers:</p><ul><li><p>The first two integers are the low and high bounds of the access bracket, specifying the rings allowed to directly access the segment based on the user&#8217;s effective mode. They are named <code>access_low </code>and<code> access_high.</code></p></li><li><p>The third integer is the high bound of the call bracket, identifying the highest ring that may attempt to execute the segment via a controlled gate crossing. It is named <code>call_high</code></p></li></ul><p>These are hardware-enforced privilege rings but they do introduce a mechanism for ring crossing via a gate which is referred to as the call bracket. In other words, a call bracket is where a segment cannot be accessed as belonging to another privilege ring, but a ring crossing through a gate mechanism can allow the user to execute the segment.</p><p>Put more simply, this allows for fine-grained privilege escalations, and it is the foundation of hardware kernel escalation and UNIX&#8217;s <code>setuid.</code></p><p></p><h1>Unix: Everything is a File</h1><p>Multics was theoretically impressive and provided groundbreaking implementation of secure, fault-tolerant systems even outside the innovations around files, but we are still one step away from the foundation of modern operating systems today.</p><p>The all too famous Ken Thompson and Dennis Ritchie, both contributors to Multics, left for Bell Laboratories. <a href="https://en.wikipedia.org/wiki/Ken_Thompson">The editors at Wikipedia claim</a> Thompson did so in part to build an OS that could support his video game <em>Space Travel</em> he was developing. The result of this effort being Unix.</p><p>Whatever its origins may be, Unix was when files came into form in their own right. Extending Multics&#8217; directory tree model, Unix implemented a hierarchical file system that not only managed content provided by users for storage or reference but a <a href="http://ftp.okass.net/pub/mirror/minnie.tuhs.org/Distributions/Research/Dennis_v1/UNIX_ProgrammersManual_Nov71.pdf#page=171">whole new philosophy</a>.</p><p>&#8220;Everything is a file.&#8221;</p><p>Now for the first time devices, sockets, directories, even processes are presented as files (at least in a heuristic sense).</p><p>This offers extreme advantages in interoperability, simplicity, and composability as now there is consistent I/O model for essentially everything a developer could need in the Operating System. There are caveats to this naturally but that is the gist behind Thompson and Ritchie&#8217;s design and it is impressively effective given Thompson himself worked alone on the first few versions of Unix.</p><p>Now even remote device mounts can be treated in a unified directory structure, and this opened up brand new horizons in the world of file storage.</p><p>Unix additionally stripped down much of the complexity around ACL, and privilege rings to decouple it from the hardware and make it far simpler for developers to build against.</p><p>By reducing the learning curve and creating radically extensible systems, Unix paved the way for MacOS and Linux systems that remain with us to this day.</p><p><em><strong>But how did file storage work into all this? </strong></em></p><p>This is where we can enter specifically into the question of file storage.</p><p>Again, up to this point all files were stored as block storage in magnetic disks and tape and Multics and Unix introduced <em>hierarchical storage, segmented memory, </em>and <em>access controls</em> abstracted from raw blocks.</p><p>By 1975, Unix V6 launched with V7 shortly to follow, introducing inodes. Each file is associated with an inode which stores metadata and points to data blocks. Directories in turn simply map names to inode numbers.</p><p>This decouples file metadata like ownership and the storage layout from the name of the item itself, access through a singular file API.</p><h1>Unix Evolved: BSD and UFS</h1><p>So where did files go from there? As the Unix ecosystem continued to evolve so did the systems undergirding files.</p><p>One major child of Unix is BSD (Berkeley Software Distribution) an open source project <a href="https://docs.freebsd.org/en/articles/explaining-bsd/">with a somewhat tendentious relationship with Unix proprietary licensing</a> but which yet still produced a number of innovations that could be incorporated further downstream into modern file systems.</p><p>With the release of BSD 4.2 in 1983 came a far more robust file system called UFS (Unix File System) that included:</p><ul><li><p>Block size increases from 512 or 1024 bytes to 4096 and 8192 bytes.</p></li><li><p>Partial blocks were chunked into block fragments to save space</p></li><li><p>Metadata distributed across cylinders for better performance (lower seek time)</p></li><li><p>Linear scan performance of directories improved over time</p></li><li><p>Tunable inodes to adjust file system size as needed to balance storage needs and performance.</p></li></ul><p><br>Across the board, UFS introduced a very matured flavor of the Unix file system one that would become standard not just on BSDs but also for SunOS, Solaris, and others.</p><p>It would also set the the stage for Linux.</p><h1>ext: Linux and Modern File Systems</h1><p>Aside from Unix offshoots like BSD, <a href="https://minix1.woodhull.com/index1.html">MINIX</a> was launched in the late eighties for academic purposes with source code available for general use.</p><p>Linus Torvalds picked up on this free kernel and launched the Linux kernel in 1991, developing it off MINIX using the GNU C Compiler.</p><p>While the earliest versions of the kernel mirrored the MINIX file system, Remy Card implemented the first generation of <code>ext </code>(extended file system) in 1992 with<a href="https://kernel.googlesource.com/pub/scm/linux/kernel/git/nico/archive/+/v0.96c"> Linux 0.96c</a>. Unfortunately, this first generation did not offer much more than a Linux-native approach for file management.</p><p>However, this changed quickly when <code>ext2 </code>launched in 1993 with separate inode and data block bitmaps, fast symbolic links, and file attributes. This generation also suffered from problems around unclean shutdowns which required <code>fsck</code> to check and repair files after a large variety of system failures or even errors.</p><p>This was solved in <code>ext3 </code>with journaling. Journaling is the extended file system&#8217;s version of a write ahead log which records metadata operations before applying them to assist in clean transactions and rollbacks as required. This with backwards compatibility with <code>ext2 </code>created a clean upgrade path.</p><p>Yet this generation was limited by scale and performance. This led to <code>ext4 </code>which remains the default file system in the Linux kernel to this day.</p><p><code>ext4 </code>has <a href="https://www.kernel.org/doc/html/v6.1/filesystems/ext4/overview.html#blocks">new major features</a> such as extents that replace block maps to add efficiency for larger files, delayed allocation by batching writes, 64-bit blocks, journal checksums to provide integrity measures for the journal itself, and large max file and volume sizes.</p><h1>Networked Files for Distributed Systems</h1><p>While we&#8217;ve arrived at the modern implementation of file systems in Linux systems, we have bypassed many other offshoots along the way, such as Windows and SMB.</p><p>Let us refocus on another relevant historical strain for understanding files in the cloud: files and networking.</p><p>Much like with block storage where DAS evolved into NAS and SAN, a growing demand emerged for sharing files between UNIX systems across a LAN.</p><p>Sun Microsystems built NFS (Network File System) in 1984 to render remote files like they were local. It was formalized in a protocol in <a href="https://datatracker.ietf.org/doc/html/rfc1094">RFC 1094</a>.</p><p>NFSv2 was the first public release of the Network File System and was built on the principle of mountable remote directories. A client mounts a remote directory and can read and write those files like they were local.</p><p>Initially communication was carried over the stateless UDP protocol. It worked relatively well over LAN but not over WANs. And if a server failed, that introduced issues as well.</p><p>These problems were mitigated to some extent with NFSv3 in 1995 which introduced TCP, doubling to 64-bit file sizes and offsets, asynchronous writes, file attribute caching to reduce round trips, but yet remained stateless. Clients and servers for forced to rely on idempotent operations.</p><p>Nevertheless, by this time NFSv3 was becoming a fairly standard component of the Linux package, particularly in HPC clusters and data centers with distributed systems.</p><p><a href="https://datatracker.ietf.org/doc/html/rfc7530">NFSv4</a> finally introduced stateful protocols over TCP with open state, file locks, and delegations, alongside compound operations to increase performance.</p><p>Even more importantly, it introduced ACLs for fine-grained permissions across distributed systems, and authentication compatibility with TLS and Kerberos.</p><p>For the first time all exports also appeared under a single root directory for cleaner client side management of a global namespace.</p><p>NFSv4 is still the standard with minor versions such as NFSv4.1 and NFS4.2 for stability, parallelism, and other cloud-friendly features, but the architecture has largely been set in stone and seems to have matured fully.</p><h1>The Migration: Files in the Cloud</h1><p>A slight tangent before exploring the evolution of cloud service provider based files solutions.</p><p>The Unix model which we discussed above was not merely a <em>de facto </em>standard for operating systems but in some sense codified as <em>the </em>standard with the publication of POSIX compliance in <a href="https://standards.ieee.org/ieee/1003.1/1388/">IEEE 1003.1</a></p><p>Essentially, <a href="https://www.opengroup.org/austin/papers/posix_faq.html">POSIX is a designation</a> that identified whether various systems such as Linux were sufficiently interoperable with other operating systems by possessing the necessary criteria of Unix API compatibility, including around file and directory API calls such as <code>read(), write(), chmod().</code></p><p>POSIX-compliance has thus become a criterion for identifying if a service could be deemed sufficiently like a file server.</p><p>This is a primary distinction for <em><strong>object storage </strong></em>which more or less came to the forefront of persistent storage paradigms with the release of Amazon S3 in 2006.</p><p>We can cover object storage more in depth later but it is crucial to note that S3 and object storage is <strong>not </strong>POSIX-compliant even if it does have file and folder like semantics.</p><p>Many companies have since migrated from using file storage to object storage, but in time the cloud service providers have each in turn released their own POSIX-compliant NFS systems with Amazon EFS, Azure Files (which includes Windows SMB), and Google Filestore.</p><p>To this day there are several primary advantages around leveraging these POSIX-compliant cloud services versus object storage:</p><ul><li><p>Minimal replatforming: a suitable &#8220;lift and shift&#8221; option</p></li><li><p>Mountable storage that does not need accessed through an HTTP API</p></li><li><p>Much lower latency particularly on premium SKU offerings</p><p></p></li></ul><h1>The Future of Files and File Architecture</h1><p>All the same the cloud computing push toward &#8220;serverless&#8221; and managed service implementations has increasingly led to the deprecation of file servers for cloud-native engineering.</p><p>File content repositories like Microsoft&#8217;s SharePoint or OneDrive have increasingly usurped the role that local or self-hosted file storage solutions used to play. This is not to say that cloud-hosted file storage is now universal (the statistics on this are difficult to pinpoint with accuracy) but it is fair to say that it is at least fairly ubiquitous across SMBs and <a href="https://bigid.com/blog/cloud-migration-trends-and-statistics-2023">enterprise companies</a>.</p><p>Where could file storage advance from here?</p><p>A number of potential paths:</p><ul><li><p>Further performance improvements <a href="https://cioinfluence.com/it-and-devops/top-enterprise-data-storage-trends-of-2024/">through integration with NVMe-oF</a></p></li><li><p>The extension of <a href="https://nvlpubs.nist.gov/nistpubs/specialpublications/NIST.SP.800-207.pdf">Zero Trust Architecture</a> to file system access controls</p></li><li><p><a href="https://arxiv.org/abs/2409.18682">DAOS (Distributed Asynchronous Object Storage)</a> for high-performance computing and POSIX-compatibility.</p></li><li><p>An <a href="https://datatracker.ietf.org/doc/slides-interim-2020-dinrg-01-sessa-an-overview-of-the-interplanetary-file-system-ipfs/">IPFS (InterPlanetary File System)</a> designed for truly global file identification and access across the entire world.</p></li><li><p><a href="http://web.mit.edu/6.826/www/notes/HO13.pdf">Semantic file systems</a> that emphasize accessing files based on content rather than hierarchy. This is an old proposal but with the advent of generative AI has freshened interest in rethinking how data can be accessed.</p></li></ul><p>If one thing is for certain, files are no longer an innovation focus area in themselves, but they are likely to remain able to piggy back off the advancements around object storage and AI semantic searching as those continue to bring new possibilities around how we use data, and consequently the questions around how we store such data.</p>]]></content:encoded></item><item><title><![CDATA[AWS and Azure Well-Architected Framework Compared - Part I: Overview]]></title><description><![CDATA[Comparing Amazon and Microsoft's architecture frameworks]]></description><link>https://tech.ngperrin.com/p/aws-and-azure-well-architected-framework</link><guid isPermaLink="false">https://tech.ngperrin.com/p/aws-and-azure-well-architected-framework</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Sat, 19 Apr 2025 20:58:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gKYS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gKYS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gKYS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!gKYS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!gKYS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!gKYS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gKYS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1023896,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gKYS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!gKYS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!gKYS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!gKYS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84b23ce6-165b-4658-abe3-c8f225abeec9_1024x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Introduction</h1><p>Before we begin, what is architecture?</p><p>Architecture is concerned with the <a href="https://www.etymonline.com/word/architecture">&#8220;tasteful application of scientific and traditional rules of good construction to the materials at hand</a>&#8221;. And even in the term&#8217;s origins from Greek we find the sense of a craftsman weaving together disparate elements into a cohesive, unified whole. Such an idea is engrained directly into the etymology of &#8220;architecture&#8221;.</p><p>For most of its history in the English language, this term was of course applied to physical construction, but much like &#8220;engineering&#8221; and &#8220;infrastructure&#8221; these metaphors have evolved into an abstraction which applies just as much now to the digital landscape as it did to the material world before.</p><p>The quality of building can take a variety of forms.</p><p>You can build out of cheap necessity, hodge-podge ideas, a desire for experimentation, reckless urgency to meet a demand, or just to get by. But to build <em>well </em>is different than to build something at all.</p><p>This was well understood by the early pioneers of computing when architecture was applied to new things like software and networks.</p><p>At the core, you need architecture to undergird these complex, expensive, and massively scaled expanses of the digital fabric that clothes our world.</p><p>Cloud systems are no different in this regard.</p><p>Quality in cloud &#8220;construction&#8221; can vary widely as well.</p><p>When you wake up Day 1 in the AWS or Azure ecosystem, even if you are a fairly experienced software engineer, you can quite easily work yourself into a five or six digit monthly invoice.</p><p>Or something that breaks half the time.</p><p>Or something with a gaping security flaw.</p><p>You can build in the cloud, but to tastefully apply those rules of good construction using the materials at hand, is its own art and science, that of cloud architecture.</p><h1>The Advent of the Well-Architected Framework</h1><p>You do not need to go far to find a large pool of anecdotes from individuals and businesses over the past dozen years, who from some cost or configuration blunder, would never go back to the cloud again.</p><p>Like many new technologies, especially those that are neither foolproof nor user-friendly, it is easy for many with negative experiences with such technology to discount it because &#8220;it doesn&#8217;t work&#8221;.</p><p>For vendors like Amazon and Microsoft, you want long-term lock in from your customers.</p><p>This is why there was a concerted effort to both devise common architectural principles and designs and then to provide an educational system and robust credentialing (Solutions Architect) around new &#8220;roles&#8221; in the labor market earmarked to accelerate the advance of cloud migrations globally.</p><p>To this end, each cloud provider has published their own &#8220;Well-Architected Framework&#8221; to help consolidate in a holistic manner, all the consideration that should go into designing, implementing, and maintaining cloud systems within their specific ecosystems.</p><p>By paying attention to specific pillars such as Operational Excellence, Security, Reliability, Performance efficiency, Cost optimization, and (for AWS) Sustainability, each WAF provides a broad classificatory system that enables focus on particular key areas while maintaining a lens for the general big picture as well.</p><p>This post is the beginning of a series that will compare and contrast the AWS and Azure Well-Architected Frameworks (hereafter referred to as WAF). With <a href="https://cloud.google.com/architecture/framework">Google Cloud&#8217;s WAF</a> potentially at some future date.</p><p>We will look at not only the content but the format, the philosophy, and the structure of such frameworks and how they mesh with the opinionated ways each vendor cultivates their own offerings.</p><p></p><h1>Revision History</h1><h2>AWS</h2><p>Important to analyzing any publication is an assessment of its history. The differences here between the AWS and Azure WAF already appear quite stark.</p><p>AWS offers a designated &#8220;<a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/document-revisions.html">Document Revisions</a>&#8221; page which outlines both the history of the AWS WAF from its initial publication in October 1, 2015 with each subsequent update notated with a description and change date. Most recently, a &#8220;major update&#8221; refresh in November 6, 2024 to refresh many of the WAF pillars, particularly in light of the advanced around generative AI.</p><p>Alongside this are framework versions with the first specified as 2022-03-31 and the most recent one as 2024-06-27. Four in total are noted though without any description or title attached to these versions.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!R0iT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!R0iT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 424w, https://substackcdn.com/image/fetch/$s_!R0iT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 848w, https://substackcdn.com/image/fetch/$s_!R0iT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 1272w, https://substackcdn.com/image/fetch/$s_!R0iT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!R0iT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png" width="959" height="222" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:222,&quot;width&quot;:959,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12386,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!R0iT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 424w, https://substackcdn.com/image/fetch/$s_!R0iT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 848w, https://substackcdn.com/image/fetch/$s_!R0iT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 1272w, https://substackcdn.com/image/fetch/$s_!R0iT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F113abc0e-fce6-4e4e-80eb-9d92e1018f0a_959x222.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>What remains unclear from this view is what constitutes a change in framework versions versus the document revisions.</p><p>The first framework version 2022-03-31 does not even have a changelog entry for that date. </p><p>The subsequent three framework versions do have changelog notes that describe pillar refreshes or updates to best practices, but this does not alone seem to increment the framework version as the most recent changelog from November 6, 2024 has the most expansive description of changes but apparently does not constitute any change in the framework version.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OLJ-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OLJ-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 424w, https://substackcdn.com/image/fetch/$s_!OLJ-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 848w, https://substackcdn.com/image/fetch/$s_!OLJ-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 1272w, https://substackcdn.com/image/fetch/$s_!OLJ-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OLJ-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png" width="916" height="211" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c90d978b-fea2-4153-89e8-30652c2c809b_916x211.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:211,&quot;width&quot;:916,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:49377,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OLJ-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 424w, https://substackcdn.com/image/fetch/$s_!OLJ-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 848w, https://substackcdn.com/image/fetch/$s_!OLJ-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 1272w, https://substackcdn.com/image/fetch/$s_!OLJ-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc90d978b-fea2-4153-89e8-30652c2c809b_916x211.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><p>There is a level of irony that a document or framework exclusively concerned with architectural best practices should itself have an unclear and confusing versioning system, but this irony is all the deeper with the Azure WAF which has no explicit revision history whatsoever.</p><p></p><h2>Azure</h2><p>The closest Azure comes to this is a &#8220;<a href="https://learn.microsoft.com/en-us/azure/well-architected/whats-new">What&#8217;s new</a>&#8221; page which offers a month-by-month view of changes to the WAF up to the last 12 months.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sRZl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sRZl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 424w, https://substackcdn.com/image/fetch/$s_!sRZl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 848w, https://substackcdn.com/image/fetch/$s_!sRZl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 1272w, https://substackcdn.com/image/fetch/$s_!sRZl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sRZl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png" width="854" height="747" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:747,&quot;width&quot;:854,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:51399,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sRZl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 424w, https://substackcdn.com/image/fetch/$s_!sRZl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 848w, https://substackcdn.com/image/fetch/$s_!sRZl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 1272w, https://substackcdn.com/image/fetch/$s_!sRZl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1cbe969-129b-4d6c-9514-b0baec11d7c1_854x747.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>From a standpoint of comprehensive documentation, this is a fairly weak approach to documenting version history, particularly as the <a href="https://azure.microsoft.com/en-us/blog/introducing-the-microsoft-azure-wellarchitected-framework/">press release</a> announcing the Azure WAF is dated July 20, 2020, and the public GitHub repo attached to this documentation<a href="https://github.com/MicrosoftDocs/well-architected/commit/d9949e085519f12b04bc261759b28e9f6fa46f12"> received its first commit</a> on December 1, 2021. Even using the <a href="https://web.archive.org/web/20250000000000*/https://learn.microsoft.com/en-us/azure/well-architected/">Wayback Machine</a>, the current URL for the WAF home page had its first snapshot on April 23rd, 2023.</p><p>There simply has not been a dedicated effort by Azure to provide a systematic view of the evolution of architectural best practices in the way that AWS has.</p><p>This irony is further underscored by the Azure WAF&#8217;s explicit recommendation to provide <a href="https://learn.microsoft.com/en-us/azure/well-architected/architect-role/architecture-decision-record">architecture decision records (ADRs)</a> that provide an auditable tracking system for stakeholders to maintain accountability during architectural changes.</p><p>This is common sense in the profession and though it is applicable to all joint architectural decision, Microsoft does not seem to apply this principle to the WAF itself.</p><p></p><h2>Compared</h2><p>I think this truthfully reflects on the nature of the AWS and Azure ecosystems respectively around change control. At least from anecdotal practitioner experience, AWS has an at least somewhat clear process about AWS service changes and the ability to toggle between versions and UI interfaces in the AWS portal.</p><p>Azure is much more cluttered and opaque in this regard as services sometimes have preview options while at other times options and features get whisked in and out of the Azure portal. If you get really nitty-gritty you can use explicit API versioning to get Azure do what you want it to do, but it is often a moderate inconvenience at best when these changes do occur.</p><p></p><h1>Architecture Fundamentals</h1><p>Both WAF&#8217;s have a collection of pages in their overview sections concerned with the fundamentals of architecture, before it enters into the individual pillars. Here again we see broad differences between the AWS and Azure approach.</p><p></p><h2>AWS</h2><blockquote><p>&#8220;Good intentions never work, you need good mechanisms to make anything happen&#8221; &#8212; Jeff Bezos</p></blockquote><p></p><p>The AWS WAF focuses on architecture as a <strong>practice</strong>. Not in the sense of practicing piano before a recital, but in the sense that as a doctor practices medicine, so too will you practice architecture, as something between art and science.</p><p>For the AWS WAF, this begins with <a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/definitions.html">definitions</a> both of the WAF pillars as well as of the terms contained therein.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wqeH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wqeH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 424w, https://substackcdn.com/image/fetch/$s_!wqeH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 848w, https://substackcdn.com/image/fetch/$s_!wqeH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 1272w, https://substackcdn.com/image/fetch/$s_!wqeH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wqeH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png" width="948" height="530" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:530,&quot;width&quot;:948,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:126918,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wqeH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 424w, https://substackcdn.com/image/fetch/$s_!wqeH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 848w, https://substackcdn.com/image/fetch/$s_!wqeH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 1272w, https://substackcdn.com/image/fetch/$s_!wqeH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82efab1-db51-40c7-99c2-05a3c80f6745_948x530.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8S0O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8S0O!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 424w, https://substackcdn.com/image/fetch/$s_!8S0O!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 848w, https://substackcdn.com/image/fetch/$s_!8S0O!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 1272w, https://substackcdn.com/image/fetch/$s_!8S0O!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8S0O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png" width="954" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:954,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:140403,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8S0O!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 424w, https://substackcdn.com/image/fetch/$s_!8S0O!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 848w, https://substackcdn.com/image/fetch/$s_!8S0O!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 1272w, https://substackcdn.com/image/fetch/$s_!8S0O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a4b0243-9860-4338-9dcf-5422869960e5_954x500.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is an appropriate starting point as terminology often serves as an anchor to help plant the mind in the right kinds of words and concepts that are the most applicable to thinking through the problems of cloud architecture.</p><p></p><p>Following these definitions, come notes &#8220;<a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/on-architecture.html">On architecture</a>&#8221; which provide a definitive statement I would consider fundamental to the nuance of the AWS WAF.</p><p>This page begins by describing a traditional &#8220;on-prem&#8221; customer who centralizes technology architecture into a single team which operates as the gatekeeper working in conjunction with isolated product or feature teams. It explicitly calls out TOGAF and Zachman as operating under this paradigm.</p><p>Amazon rejects this approach.</p><p>&#8220;At AWS, we prefer to distribute capabilities into teams rather than having a centralized team with that capability.&#8221;</p><p>Of course the risk of this approach is having an independent voice that can judiciously ensure adherence to standards. However, AWS says that they are effectively able to mitigate insider bias from these individual service teams by holding them accountable to centralized <em>practices </em>and <em>mechanisms</em> that ensure standards continue to be met.</p><p></p><p>This and much of the AWS WAF in general, is an outworking of <a href="https://www.amazon.jobs/content/en/our-workplace/leadership-principles">Amazon&#8217;s famous leadership principles</a>.</p><p>It is this strongly opinionated view of how the business as a whole should be run (i.e. the Amazon philosophy) which has shaped and determined the best practices that AWS prescribes itself.</p><p>For example, &#8220;<a href="https://aws.amazon.com/executive-insights/content/how-amazon-defines-and-operationalizes-a-day-1-culture/">Every Day is Day 1</a>&#8221; emerges in how strongly AWS advocates for thinking in terms of cloud-<strong>native </strong>systems. Workloads need to continuously be reinvented so that they are not hampered by years of vestigial accrual. That is why cloud-native design is part and parcel of the AWS package.</p><p></p><p>This is further expounded upon in the next page &#8220;<a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/general-design-principles.html">general design principles</a>&#8221; which enumerates six general architectural principles:</p><ol><li><p>&#8220;Stop guessing your capacity needs&#8221; - Cloud enables on-demand elasticity</p></li><li><p>&#8220;Test systems at production scale&#8221; - Testing production scale is far easier with Pay-As-You-Go cloud computing costs.</p></li><li><p>&#8220;Automate with architectural experimentation in mind&#8221; - Automations should be build in such a way as to provide architectural extensibility and modification</p></li><li><p>&#8220;Consider evolutionary architectures&#8221; - Architecture is not an event but a process. Cloud-native thinking enables this kind of elastic evolution.</p></li><li><p>&#8220;Drive architectures using data&#8221; - Architectural choices can be judged quantitatively and this can be leveraged for continuous improvement</p></li><li><p>&#8220;Improve through game days&#8221; - Test and simulate various cases through game days to see how the architecture holds up.</p></li></ol><p></p><p>For the AWS WAF, architecture is not a theory or a science but a practice guided by general, flexible best-practice patterns which may evolve over time.</p><p></p><h2>Azure</h2><p>By contrast, the Azure WAF overview focuses on architecture as a <strong>role</strong>. The doctor may practice medicine, but what does that look like day-to-day? What is it to be a medical professional? What is it to be a professional cloud architect?</p><p>This is the anchor point for the Azure WAF.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!f3Uv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!f3Uv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 424w, https://substackcdn.com/image/fetch/$s_!f3Uv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 848w, https://substackcdn.com/image/fetch/$s_!f3Uv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 1272w, https://substackcdn.com/image/fetch/$s_!f3Uv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!f3Uv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png" width="853" height="384" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:384,&quot;width&quot;:853,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:55964,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!f3Uv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 424w, https://substackcdn.com/image/fetch/$s_!f3Uv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 848w, https://substackcdn.com/image/fetch/$s_!f3Uv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 1272w, https://substackcdn.com/image/fetch/$s_!f3Uv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d6c51-e14f-4c19-a298-191ccbdf6448_853x384.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>These responsibilities are listed in the <a href="https://learn.microsoft.com/en-us/azure/well-architected/architect-role/fundamentals">fundamentals of the solution architect</a>:</p><ol><li><p>&#8220;Have a decision-making framework&#8221;</p><ol><li><p>Identify expected decisions in advance.</p></li><li><p>Make informed decisions, considering limitations, constraints, tradeoffs, effort reversability, and risk.</p></li><li><p>Document decisions in an architecture decision record (ADR) along with the justification.</p></li><li><p>Follow up on implementation</p></li></ol></li><li><p>&#8220;Know cloud design patterns&#8221;</p><ol><li><p>Evaluate a workload&#8217;s functional and nonfunctional requirements to recognize patterns.</p></li></ol></li><li><p>&#8220;Be forward-thinking&#8221;</p><ol><li><p>Growth model, how will workloads scale</p></li><li><p>Compliance changes and the roadmap</p></li><li><p>Regional expansion for locally-based companies.</p></li><li><p>Product roadmaps. What will deprecate and what will expand</p></li></ol></li><li><p>&#8220;Design for supportability&#8221;</p><ol><li><p>Cloud provider support</p></li><li><p>Operational visibility</p></li><li><p>Customer support capabilities</p></li></ol></li><li><p>&#8220;Maintain and enhance your skills&#8221;</p><ol><li><p>Education</p></li><li><p>Community participation</p></li><li><p>Explanatory exercises</p></li></ol></li><li><p>&#8220;Collaborate for success&#8221;</p><ol><li><p>Maximize cloud provider and community leverage</p></li></ol></li><li><p>&#8220;Be methodical in your design approach&#8221;</p><ol><li><p>Combine frameworks such as the TOGAF with WAF.</p></li></ol></li></ol><p></p><p>All of these are geared toward <em>professionalism</em> in the cloud architect world.</p><p>Alongside these fundamentals, are sections detailing the <a href="https://learn.microsoft.com/en-us/azure/well-architected/architect-role/checklist">&#8220;Deliverables&#8221;</a> of the architect, wrapped up in a checklist format which is a core part of the Azure WAF&#8217;s structure in general. Each pillar of excellence will get its own checklist as well.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rSeh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rSeh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 424w, https://substackcdn.com/image/fetch/$s_!rSeh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 848w, https://substackcdn.com/image/fetch/$s_!rSeh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 1272w, https://substackcdn.com/image/fetch/$s_!rSeh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rSeh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png" width="845" height="667" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:667,&quot;width&quot;:845,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:96311,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://tech.ngperrin.com/i/161176520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rSeh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 424w, https://substackcdn.com/image/fetch/$s_!rSeh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 848w, https://substackcdn.com/image/fetch/$s_!rSeh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 1272w, https://substackcdn.com/image/fetch/$s_!rSeh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2fbdce0-3496-4339-8c85-2fe3dc152c59_845x667.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>This kind of list provides a far more concrete sense of what an architect does day-to-day. Meetings, presentations, reports, documentation. These are part and parcel of the architect lifestyle, most particularly in the corporate and enterprise environments where Microsoft is so deeply embedded, and Azure drew its initial customer base from.</p><p>I will not go into each of these deliverables individually here, but I do find the Azure WAF approach to be more robust in providing guidelines for how to document things like architecture decisions via the ADR (which again ironic as the WAF does not have a robust version history system).</p><h2>Compared</h2><p>These overview sections are particularly crafted to fit different audiences. </p><p>The AWS WAF is more focused on the technologist, how to speak to someone in technical leadership with the appropriate forms of abstraction to describe varying technology stacks.</p><p>By contrast, the Azure WAF explicitly notes that cloud architecture must comprise both the technical and the business dimension for it to work at all, which again makes sense based on Microsoft&#8217;s history of partnerships. </p><p>But beyond that, the Azure WAF is more helpful in this section because it specifically documents the architect&#8217;s <strong>role</strong> as a professional, which is sometimes the more difficult part in contrast to the more logical dimensions of architecture as a <strong>practice, </strong>in the way the AWS WAF focuses on it.</p><p>Perhaps most importantly when considering the foundations of the AWS and the Azure WAF in parallel, the AWS WAF exhorts their customers to partake fully in the Amazon model in order to thrive in the AWS ecosystem. This means decentralized architecture.</p><p>The Azure WAF explicitly calls attention to its compatibility with many architectural frameworks including TOGAF (see Fundamentals 7a above). </p><p>It does not aim to be a comprehensive philosophy that commandeers how the business is run. It rather seeks to negotiate with business stakeholders with where they are at and how they currently operate, something which enterprise management and leadership teams would probably prefer over the more abrasive Jeff Bezos/AWS tone.</p><p>This is a contrast that will appear even more clearly when considering how AWS and Azure respectively consider the first pillar of &#8220;Operational Excellence&#8221;.</p>]]></content:encoded></item><item><title><![CDATA[Breaking down OAuth 2.0]]></title><description><![CDATA[Running through OAuth 2.0 concepts, grant types, and more]]></description><link>https://tech.ngperrin.com/p/breaking-down-oauth-20</link><guid isPermaLink="false">https://tech.ngperrin.com/p/breaking-down-oauth-20</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Thu, 10 Apr 2025 22:01:22 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e48aecdf-0b72-4ac7-be77-5a336ba0d4d4_124x123.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><pre><code><code>&#8220;The OAuth protocol was originally created by a small community of web developers from a variety of websites and other Internet services who wanted to solve the common problem of enabling delegated access to protected resources.&#8221;
RFC 5849</code></code></pre></blockquote><p>Auth is an ambiguous shorthand which can refer to either authentication (AuthN) or authorization (AuthZ).</p><p>Today, we explore OAuth 2.0. But first, one cannot begin to understand OAuth 2.0 without understanding the context of why AuthN and AuthZ came to be decoupled.</p><h1>Fundamentals: AuthN and AuthZ</h1><p>Authentication is concerned with verifying that an entity is who they claim to be; authorization takes that authentication and then identifies what that agent should be entitled to access.</p><p>Authentication and authorization are logically distinct flows, and consequently it is generally preferable for them to be technically decoupled as well.</p><p>This was not the case for HTTP services for quite some time, prior to the advent of OAuth.</p><p>Some examples of tightly coupled AuthN/AuthZ:</p><ul><li><p>HTTP Basic Auth: adding the <code>Authorization</code> header as Base64-encoded &#8220;<code>username:password</code>&#8221;</p></li><li><p>API keys: static, long-lived keys passed in the HTTP header <code>x-api-key</code> or <code>Authorization: Bearer {key}</code></p></li><li><p>Cookies: server sets a session cookie after authentication that binds the user&#8217;s session to their authentication status.</p></li></ul><p>This is not to say all such couplings are inherently &#8220;bad&#8221;. </p><p>Cookies work well for same-origin web applications. However when the scope includes third-party integrations or mobile clients such coupling introduces problems.</p><p>Kerberos is designed to tightly couple authentication and authorization as well but is a fairly robust protocol when dealing with enterprise auth management. (It even back Microsoft Entra ID&#8217;s directory technology, from what I understand, to this day.)</p><p>But with the rise of third-party API integrations came a distinct need to decouple authentication and authorization.</p><p>Hence, OAuth.</p><h1>OAuth 1.0: A First Stab</h1><p>Web developers came together to find a solution that would abstract the authorization process out of authentication. <a href="https://oauth.net/core/1.0/">OAuth 1.0 was originally published</a> in October 2007 to solve this problem with <a href="https://datatracker.ietf.org/doc/html/rfc5849">RFC 5849</a> introduced in April 2010.</p><p>Although it came to be replaced fairly quickly with OAuth 2.0, this first OAuth protocol did lay a lot of the groundwork for its successor protocol.</p><p>As noted in RFC 5849, the traditional client-server authentication model depends on the client using its credentials to access server-hosted resources. However, the rise of cloud and distributed systems introduced requirements for third-party access at scale.</p><p>OAuth attempted to solve this by adding a third role to the client and server model: the resource owner.  In this new paradigm, a server may host resources that it may not necessarily own. Consequently, the client can request access from the resource owner and then proceed to where those resources are hosted to be provided access, all while verifying the identity of the requesting client.</p><p>It should be remembered that <strong>OAuth is purely an authorization protocol</strong>, as it can be too easy to mentally slip it up and consider it at least partially authentication-based.</p><p>Delving into the inner working of OAuth 1.0 may be a useful exercise but is not our intent here as it is largely obsolete. There are several reasons why OAuth 1.0 needed to be replaced by a successor within a short timeframe.</p><p>In brief, OAuth 1.0 suffered from these flaws:</p><ul><li><p>It required message-level security with signature-based verification. This is not intensive but also not layer properly with transport layer security technologies such as TLS or JWTs.</p></li><li><p>Every API request needed to be signed using either HMAC-SHA1 or RSA which is not only difficult to implement but can understandably introduce performance degradations.</p></li><li><p>Mobile clients and SPA&#8217;s cannot securely integrate with a signature-based flow</p></li><li><p>Low extensibility made it difficult to add token formats, transport mechanisms, or grant types, which is not ideal for a critical fast-moving technology.</p></li></ul><h1>OAuth 2.0 Fundamentals</h1><p>Lessons were learned and the developer community came up with a fully reimagined authorization protocol to replace OAuth 1.0. </p><p><a href="https://datatracker.ietf.org/doc/html/rfc6749">RFC 6749 emerged</a> in October 2012, defining and laying the groundwork for what remains to this day one of the most widespread authorization protocols in digital technology.</p><p>While OAuth 1.0 defined three roles of client, server, and resource owner, this was further expanded to four roles in OAuth 2.0 defined in this way</p><ol><li><p>Client: The application making requests for protected resources on authorized behalf of the resource owner</p></li><li><p>Resource Owner: The end-user or entity capable of granting access to a protected resource.</p></li><li><p>Authorization Server: The server that issues access tokens to the client authorized by the resource owner when that resource owner has been authenticated.</p></li><li><p>Resource Server: The server hosting the protected resources, responding to resource requests carrying valid access tokens.</p><p></p></li></ol><h2>Client Registration</h2><p>Before using OAuth 2.0, clients must register with the authorization server. Registration requirements vary by implementation but typically include:</p><ul><li><p>Client type (confidential or public)</p></li><li><p>Redirect URIs</p></li><li><p>Additional server-specific information</p></li></ul><p>Clients are categorized as:</p><ul><li><p>Confidential: Can securely store credentials (e.g. server-side applications)</p></li><li><p>Public: Cannot keep credentials confidential (e.g. SPAs, mobile apps)</p></li></ul><h2>Client Authentication</h2><p>Confidential clients or clients with credentials must authenticate with the authorization server when making requests to the token endpoint. This authentication serves several important purposes:</p><ul><li><p>Enforces the binding of refresh tokens and authorization codes to the correct client</p></li><li><p>Helps a compromised client recover by invalidating previous credentials</p></li><li><p>Implements periodic credential rotation for enhanced security</p></li></ul><p>The method of authentication can vary depending on the implementation, but typically involves the client ID and client secret.</p><h2>OAuth 2.0 Endpoints</h2><p>The OAuth 2.0 protocol utilizes three primary endpoints:</p><ol><li><p>Authorization Endpoint: Used for resource owner interaction and authorization grant issuance</p><ul><li><p>Returns <code>code</code> parameter for Authorization Code flow</p></li><li><p>Returns <code>token</code> parameter for Implicit flow</p></li><li><p>Must authenticate the resource owner before granting authorization</p></li></ul></li><li><p>Token Endpoint: Where clients exchange authorization grants for access tokens</p><ul><li><p>Requires client authentication for confidential clients</p></li><li><p>Issues access tokens and optional refresh tokens</p></li></ul></li><li><p>Redirect Endpoint: The client's endpoint where the authorization server redirects after authorization</p><ul><li><p>Must be registered during client setup</p></li><li><p>Should be protected by TLS</p></li></ul></li></ol><h2>OAuth 2.0 Tokens</h2><p>Before diving into the grant types, it's important to understand the tokens used in OAuth 2.0:</p><h3>Access Tokens</h3><ul><li><p>Credentials used to access protected resources</p></li><li><p>Represent specific authorization scopes and durations</p></li><li><p>Presented to resource servers when making API requests</p></li></ul><h3>Refresh Tokens</h3><ul><li><p>Used to obtain new access tokens when the current ones expire</p></li><li><p>Never sent to resource servers</p></li><li><p>Provide a way to maintain long-term access without requiring re-authentication</p></li></ul><p></p><h1>OAuth 2.0 Authorization Grant Types</h1><h2>1. Authorization Code Grant</h2><p>The Authorization Code grant is a user-based flow designed for server-side applications that can securely store client secrets.</p><p><strong>Flow</strong>:</p><ol><li><p>The client redirects the resource owner to the authorization server via the user's browser</p></li><li><p>The authorization server authenticates the resource owner</p></li><li><p>The authorization server redirects back to the client with an authorization code</p></li><li><p>The client exchanges this code for an access token through a secure back-channel request</p></li></ol><p><strong>Authorization Request Parameters</strong>:</p><ul><li><p><code>response_type</code>: Must be "code"</p></li><li><p><code>client_id</code>: Client identifier</p></li><li><p><code>redirect_uri</code>: (Optional) Where to send the response</p></li><li><p><code>scope</code>: (Optional) Requested access scope</p></li><li><p><code>state</code>: Recommended parameter to prevent CSRF attacks</p></li></ul><p><strong>Authorization Response</strong>:</p><ul><li><p><code>code</code>: The authorization code that will be used to request an access token</p></li><li><p><code>state</code>: Same value as in the request (if included)</p></li></ul><p><strong>Access Token Request Parameters</strong>:</p><ul><li><p><code>grant_type</code>: Must be "authorization_code"</p></li><li><p><code>code</code>: The authorization code received</p></li><li><p><code>redirect_uri</code>: Must match the original request URI (if included initially)</p></li><li><p><code>client_id</code>: Required if client does not authenticate</p></li></ul><p><strong>Access Token Response</strong>:</p><ul><li><p><code>access_token</code>: The access token</p></li><li><p><code>token_type</code>: Type of token (usually "Bearer")</p></li><li><p><code>expires_in</code>: Token lifetime in seconds (optional)</p></li><li><p><code>refresh_token</code>: Token to get a new access token (optional)</p></li><li><p><code>scope</code>: Scope of access token (optional)</p><p></p></li></ul><p>This grant flow has several advantages including the ability to use refresh tokens so that the user does not need to reauthenticate, the resource owner&#8217;s credentials are never exposed to the client, and access tokens are passed directly to the client without required exposure to other entities. This is one of the most secure OAuth 2.0 flows.</p><p></p><h2>2. Implicit Grant</h2><p>The Implicit grant is a simplified version of the Authorization Code flow, primarily designed for single-page applications (SPAs) and mobile clients that cannot make secure back-channel calls.</p><p><strong>Flow</strong>:</p><ol><li><p>The client redirects the user to the authorization endpoint</p></li><li><p>After authentication, the authorization server returns the access token directly in the URL fragment</p></li><li><p>The client application extracts the token from the URL</p></li></ol><p><strong>Authorization Request Parameters</strong>:</p><ul><li><p><code>response_type</code>: Must be "token"</p></li><li><p><code>client_id</code>: Client identifier</p></li><li><p><code>redirect_uri</code>: (Optional) Where to send the response</p></li><li><p><code>scope</code>: (Optional) Requested access scope</p></li><li><p><code>state</code>: Recommended parameter to prevent CSRF attacks</p></li></ul><p><strong>Authorization Response</strong> (in URL fragment):</p><ul><li><p><code>access_token</code>: The access token</p></li><li><p><code>token_type</code>: Type of token (usually "Bearer")</p></li><li><p><code>expires_in</code>: Token lifetime in seconds (optional)</p></li><li><p><code>scope</code>: Scope of access token (optional)</p></li><li><p><code>state</code>: Same value as in the request (if included)</p></li></ul><p></p><p>In contrast to Authorization Code, the Implicit flow does not allow the use of refresh tokens for security reasons. Furthermore, it is less secure as the tokens are exposed in browser URL fragments which can then be stored in browser history or accessible to any JavaScript running in the browser. It still has the advantage of skpipng the authorization code exchange and thus saving a round trip, but is relatively insecure.</p><p>Today, the Implicit flow has largely been deprecated in favor of Auth Code with PKCE (more on this below).</p><p></p><h2>3. Resource Owner Password Credentials Grant (ROPC)</h2><p>The ROPC grant is designed for scenarios where there is a high degree of trust between the resource owner and client.</p><p><strong>Flow</strong>:</p><ol><li><p>The client directly collects the resource owner's username and password</p></li><li><p>The client sends these credentials to the authorization server</p></li><li><p>The server validates and returns an access token</p></li></ol><p><strong>Access Token Request Parameters</strong>:</p><ul><li><p><code>grant_type</code>: Must be "password"</p></li><li><p><code>username</code>: Resource owner's username</p></li><li><p><code>password</code>: Resource owner's password</p></li><li><p><code>scope</code>: (Optional) Requested access scope</p></li></ul><p><strong>Access Token Response</strong>:</p><ul><li><p><code>access_token</code>: The access token</p></li><li><p><code>token_type</code>: Type of token (usually "Bearer")</p></li><li><p><code>expires_in</code>: Token lifetime in seconds (optional)</p></li><li><p><code>refresh_token</code>: Token to get a new access token (optional)</p></li><li><p><code>scope</code>: Scope of access token (optional)</p></li></ul><p></p><p>This flow is a strange one, primarily because it reintroduces the authentication and authorization coupling that OAuth 2.0 was designed to separate. It does allow some use of refresh tokens but does not have many advantages. It is altogether discouraged unless absolutely necessary.</p><p></p><h2>4. Client Credentials Grant</h2><p>The Client Credentials grant is designed for userless auth journeys between various servers.</p><p><strong>Flow</strong>:</p><ol><li><p>The client authenticates with its own credentials (client ID and secret)</p></li><li><p>The authorization server validates these credentials and issues an access token</p></li><li><p>The client uses this token to access protected resources</p></li></ol><p><strong>Access Token Request Parameters</strong>:</p><ul><li><p><code>grant_type</code>: Must be "client_credentials"</p></li><li><p><code>scope</code>: (Optional) Requested access scope</p></li></ul><p><strong>Access Token Response</strong>:</p><ul><li><p><code>access_token</code>: The access token</p></li><li><p><code>token_type</code>: Type of token (usually "Bearer")</p></li><li><p><code>expires_in</code>: Token lifetime in seconds (optional)</p></li><li><p><code>scope</code>: Scope of access token (optional)</p></li></ul><p>With this flow, the machine identity can simply reauthenticate automatically and so refresh tokens are not generally used, except perhaps for performance reasons. This is very common implementation for API communication and microservice-driven environments which rely upon service accounts.</p><p></p><div><hr></div><p>RFC 6749 specified those four OAuth 2.0 authorization grant flow types, but there remained room for more. </p><p>Several of which have gained widespread adoption in the years since then.</p><div><hr></div><p></p><h2>5. Authorization Code with PKCE</h2><p>How can public clients such as mobile apps or SPA participate in OAuth 2.0? Authorization Code grant is susceptible to interception attacks while the Implicit flow bypasses authorization grants altogether.</p><p>Proof Key for Code Exchange by OAuth Public Clients (<a href="https://datatracker.ietf.org/doc/html/rfc7636">RFC 7636</a>) was designed to solve just this problem.</p><p>PKCE introduces a new factor to the OAuth equation: the <code>code_verifier</code>.</p><p>Essentially, a unique code verifier value is generated by the client for each authorization request. It is then transformed typically using SHA-256 into a value known as the <code>code_challenge</code> and sent to the authorization server to fetch an authorization code.</p><p>The authorization code is returned to the client. At this point, the client sends an access token request with the authorization code to the token endpoint <strong>with the </strong><code>code_verifier</code><strong> to the token endpoint </strong>which then returns the access token. Thus, an intercepted authorization code cannot be used without the accompanying <code>code_verifier. </code></p><p><strong>Authorization Request Parameters</strong>:</p><ul><li><p>All standard Authorization Code parameters</p></li><li><p><code>code_challenge</code>: The transformed code verifier</p></li><li><p><code>code_challenge_method</code>: The method used to transform the code verifier (e.g., "S256" for SHA-256)</p></li></ul><p><strong>Access Token Request Parameters</strong>:</p><ul><li><p>All standard Authorization Code token request parameters</p></li><li><p><code>code_verifier</code>: The original code verifier string</p><p></p></li></ul><p>Both the Access Token response and the Refresh Tokens follow the same standard format as Authorization Code.</p><p>This is the recommended flow for all OAuth clients including both public and confidential clients by mitigating the risk of browser redirect theft or network interception.</p><p></p><h2>6. Device Authorization Grant</h2><p>The Internet has expanded beyond computers and smartphones to a wide panoply of &#8220;Things&#8221;. What does auth work like in the world of IoT where devices may not have browsers? </p><p>Device Authorization Grant (<a href="https://datatracker.ietf.org/doc/html/rfc8628">RFC 8628</a>) answers just such a question, at least for Internet-connected devices that can make HTTPS requests.</p><p>This flow follows these steps:</p><ol><li><p>The client sends an access request with a client identifier to the authorization server.</p></li><li><p>The authorization server issues a device code and an end-user code with an end-user verification URI.</p></li><li><p>The client instructs the end user (resource owner) to visit the verification URI on another device (transferring their user agent) and provides them with an end-user code.</p></li><li><p>The end user visits the verification URI, authenticates with the authorization server, then provides their user code. The authorization server will validate the user code and have the end user confirm the device auth request.</p></li><li><p>The device client will poll the authorization server to determine if the endu user has confirmed the auth request. Once this is completed, the polling response will include the access token.</p><p></p></li></ol><p>Those with smart TV&#8217;s may already be familiar with this auth flow as one common consumer-facing implementation flow.</p><p>Or for those working with cloud providers, you may recognize this flow as a method for authenticating your terminal CLI (headless) against a cloud provider.</p><p></p><p>The key innovation in this grant flow is the <strong>device authorization endpoint</strong> which is entirely separate from the authorization endpoint reached by users.</p><p></p><p><strong>Device Authorization Request Parameters</strong>:</p><ul><li><p><code>client_id</code>: Client identifier</p></li><li><p><code>scope</code>: (Optional) Requested access scope</p></li></ul><p><strong>Device Authorization Response</strong>:</p><ul><li><p><code>device_code</code>: Code used by the client to poll for the access token</p></li><li><p><code>user_code</code>: Code displayed to the user, typically easy to type</p></li><li><p><code>verification_uri</code>: URI the user should visit to authenticate</p></li><li><p><code>verification_uri_complete</code>: URI with the user code embedded (optional)</p></li><li><p><code>expires_in</code>: Lifetime of the device code in seconds</p></li><li><p><code>interval</code>: Minimum time in seconds between polling requests (optional)</p></li></ul><p><strong>Token Request Parameters</strong>:</p><ul><li><p><code>grant_type</code>: Must be "urn:ietf:params:oauth:grant-type"</p></li><li><p><code>device_code</code>: Device code received in the authorization response</p></li><li><p><code>client_id</code>: Client identifier (if client authentication is not used)</p><p></p></li></ul><p>Refresh tokens are almost a necessity in this flow from a UX perspective because these device s maintain long-term access and the inconvenience of reauthenticating IoT devices is not appealing to most end-users.</p><p>This is a very robust pattern for extending the OAuth 2.0 framework out into the world of IoT and headless device auth (e.g. CLI).</p><p></p><h2>7. Token Exchange Grant</h2><p>Access tokens are useful technology when implemented properly. A credential with clearly-defined boundaries, expiration, that can be revoked remotely as needed.</p><p>But an access token on its own is immutable. If an authenticated user with broad authorization wants to delegate this access token to another user or system that should have fairly limited scope, there is little that can be done without reauthenticating through some other possible authorization flow.</p><p>Token Exchange Grant (<a href="https://datatracker.ietf.org/doc/html/rfc8693">RFC 8693</a>) was the next extension to OAuth 2.0 to solve this problem by allowing for token exchanges for the purpose of delegation, authorized impersonation, token descoping, or service chaining.</p><p>This flow is simple enough. The client presents an existing token to the token endpoint with specifications for the new token. If these are valid, the authorization server will validate the request and issue a new token in the response. Simple as that.</p><p><strong>Access Token Request Parameters</strong>:</p><ul><li><p><code>grant_type</code>: Must be "urn:ietf:params:oauth:grant-type"</p></li><li><p><code>subject_token</code>: The token representing the subject</p></li><li><p><code>subject_token_type</code>: The type of the subject token</p></li><li><p><code>actor_token</code>: (Optional) Token representing the actor</p></li><li><p><code>actor_token_type</code>: (Optional) Type of the actor token</p></li><li><p><code>resource</code>: (Optional) Identifier for the target service or resource</p></li><li><p><code>audience</code>: (Optional) Logical name of the target service</p></li><li><p><code>scope</code>: (Optional) Requested scope</p></li><li><p><code>requested_token_type</code>: (Optional) Type of token requested</p></li></ul><p><strong>Access Token Response</strong>:</p><ul><li><p><code>access_token</code>: The issued token</p></li><li><p><code>issued_token_type</code>: Type of the issued token</p></li><li><p><code>token_type</code>: Type of the access token</p></li><li><p><code>expires_in</code>: Lifetime in seconds (optional)</p></li><li><p><code>scope</code>: Scope of the issued token (optional)</p></li><li><p><code>refresh_token</code>: Token to get a new access token (optional)</p></li></ul><h1>Assertions</h1><p>Assertions, in the context of auth, are not original to OAuth 2.0. SAML and WS-Federation had been using assertions long before OAuth hit the scene.</p><p>An assertion is a set of data that allows one entity to make claims about an identity or subject. It functions as a digitally signed statement so that a valid assertion can be taken as fact by the designated recipient (audience) that the identity or subject has the attributes the issuer reports.</p><h2>8. Assertion Grants</h2><p><a href="https://datatracker.ietf.org/doc/html/rfc7521">RFC 7521</a> opened the door for defining how assertions could be used as authorization grants within OAuth 2.0 both for SAML (<a href="https://datatracker.ietf.org/doc/html/rfc7522">RFC 7522</a>) and JWT (<a href="https://datatracker.ietf.org/doc/html/rfc7523">RFC 7523</a>)</p><p>At its highest level, assertion grant flows follow this sequence:</p><ol><li><p>A client obtains an assertion from the issue</p></li><li><p>The client presents the assertion to the token endpoint</p></li><li><p>The authorization server validates the assertion according to type-specific rules</p></li><li><p>If valid, the authorization issues an access token to the client.</p></li></ol><p>Broadly speaking, SAML is more commonly adopted in enterprise and legacy environments, particularly for web based SSO, while JWT is much more compact and widely embraced in modern web and mobile applications as well as API-centered ecosystems.</p><p>We won&#8217;t go into the SAML side here but let&#8217;s give a little more information on JWT.</p><p></p><h2>JSON Web Tokens</h2><p>JWT (JSON Web Token) emerged around the same time, though independently of, OAuth 2.0 and was standardized in <a href="https://datatracker.ietf.org/doc/html/rfc7519">RFC 7519</a> published in May 2015. Although it was not built from OAuth it did explicitly allocate a subname registration for OAuth (cf. 10.2), so the two were meant to go hand-in-hand.</p><p>XML in all its bulk and unreadability was an industry standard for quite some time, and as JSON continued to grow in popularity as an interchange format, so too did the desire for a lightweight token format based on JSON, especially as stateless APIs came to fruition.</p><p>JWT accomplishes several things at once which are important for OAuth:</p><ol><li><p>It provides a compact way to encode token information (HTTP headers)</p></li><li><p>Tokens can directly include claims, no external reference required.</p></li><li><p>Built-in signature verification to ensure token integrity</p></li></ol><p>All of these are contained in its simple tripartite format of a header which identifies the signature&#8217;s algorithm, the payload which contains the claims (assertions about the subject), and a signature to ensure token integrity.</p><p>JWT is not just limited to OAuth but has taken wide and deep root across the entire IAM and auth world.</p><p>In the context of OAuth 2.0 though it takes this format.</p><p><strong>JWT Access Token Request Parameters</strong>:</p><ul><li><p><code>grant_type</code>: Must be "urn:ietf:params:oauth:grant-type"</p></li><li><p><code>assertion</code>: The JWT assertion</p></li><li><p><code>scope</code>: (Optional) Requested access scope</p></li></ul><p><strong>Access Token Response</strong>: Standard OAuth 2.0 token response.</p><p><strong>JWT Required Claims</strong>:</p><ul><li><p><code>iss</code>: Issuer - who issued the JWT</p></li><li><p><code>sub</code>: Subject - who the JWT is about</p></li><li><p><code>aud</code>: Audience - recipient(s) the JWT is intended for</p></li><li><p><code>exp</code>: Expiration time</p></li><li><p><code>iat</code>: Issued at time</p></li><li><p><code>jti</code>: JWT ID - unique identifier for the token</p></li></ul><p></p><h1>OAuth 2.0: Best Security Practices</h1><p><a href="https://datatracker.ietf.org/doc/html/rfc9700">RFC 9700</a> came out fairly recently when this was written, and it provides a general collation of security vulnerabilities and best practices around the OAuth 2.0 framework.</p><p>A suitable way to close this breakdown is to visit these threat vectors and best practices.</p><h2>OAuth 2.0 Attack Vectors</h2><p>This RFC publication lays out a number of  attacker profiles which are specifically targeted by the mitigation document:</p><ul><li><p>A1: An attacker who operates OAuth clients registered with the targeted authorization server, luring users to their compromised URIs.</p></li><li><p>A2: Network attackers who can eavesdrop, manipulate, block, or spoof messages that are not protected by TLS.</p></li><li><p>A3: Attackers that can read authorization response content</p></li><li><p>A4: Attackers that can read authorization request content</p></li><li><p>A5: Attackers that can acquire a valid access token issued by the authorization server</p></li></ul><p>From these attacker profiles come the following attack types:</p><h3>1. Insufficient Redirection URI Validation</h3><p><strong>Threat Vector: </strong>Redirection URI patterns introduce risk as opposed to complete, literal URI redirect matching. </p><p>If subdomains or paths have wildcard or other regex matching characters, it is possible for an attacker to hijack that subdomain or path, and then steal authorization codes or access tokens.</p><p><strong>Mitigation: </strong>Use exact redirection URI matching.</p><p>Additional steps:</p><ul><li><p>Do not expose open redirectors</p></li><li><p>Attach an arbitrary fragment identifier <code>#_ </code>to the redirection URI to prevent browser from reattaching them to Location (insecure)</p></li></ul><h3>2. Credential Leakage via Referer Headers</h3><p><strong>Threat Vector: </strong>Authorization codes or state values can be unintentionally disclosed in the <code>Referer </code>HTTP Header. Disclosed state values remove protection from CSRF attacks.</p><p><strong>Mitigation: </strong>The page rendered as the result of the OAuth authorization response should not include third-party resources or links to external sites.</p><p>Additional steps:</p><ul><li><p>Suppress the <code>Referer</code> header <a href="https://www.w3.org/TR/2017/CR-referrer-policy-20170126/">through a policy</a></p></li><li><p>Bind the authorization code to a confidential client or PKCE challenge.</p></li><li><p>Authorization codes must be invalidated by the authorization server after their first use at the token endpoint.</p></li><li><p>State value should be invalidated by the client after its first use at the redirection endpoint.</p></li><li><p>Use the form post response mode instead of a redirect for the authorization response.</p></li></ul><h3>3. Credential Leakage via Browser History</h3><p><strong>Threat Vector: </strong>Authorization codes and access tokens can end up in the browser&#8217;s history of visited URLs (e.g. Implicit Flow) which when exposed can lead to replay attacks.</p><p><strong>Mitigation: </strong>Authorization code replay prevention and prevent access tokens from being included in URI query parameters<strong> </strong></p><h3>4. Mix-Up Attacks</h3><p><strong>Threat Vector: </strong>An OAuth client interacts with multiple authorization servers, one of which is under the control of an attacker. The attacker tricks the client into sending authorization codes or access tokens to the wrong server, thus hijacking them.</p><p>This can happen if the client stores the compromised authorization server in their session, redirects the user to that compromised auth server, then the compromised auth server forwards the request to a legitimate authorization server, using that legitimate server&#8217;s client ID. The user will log in on the legitimate server, but that server would then send the authorization code to the attacker.</p><p>Variants of this include intercepting and modifying the user&#8217;s traffic, intercept the access token in implicit grant, per-authorization server redirect URI&#8217;s, or OpenID Connect Abuse</p><p><strong>Mitigation: </strong>Every auth response should include the <code>iss </code>issuer ID as a parameter or claim.</p><h3>5. Authorization Code Injection</h3><p><strong>Threat Vector: </strong>An attacker who has acquired a valid authorization code may try to redeem that authorization code for an access token by injecting it into their client, attaching the victim&#8217;s identity to the attackers session.</p><p><strong>Mitigation: </strong>PKCE mitigates this, attaching and checking a random <code>nonce </code>value when requesting the session can prevent this as well.</p><h3>6. Access Token Injection</h3><p><strong>Threat Vector: </strong>An attacker with a valid, stolen access token may inject this into a legitimate client.</p><p><strong>Mitigation</strong>: OAuth 2.0 on its own cannot mitigate this but integration with OpenID Connect could include the <code>at_hash </code>claim in the ID token, introducing an additional layer of protection.</p><h3>7. Cross-Site Request Forgery</h3><p><strong>Threat Vector: </strong>An attacker injects to a legitimate client&#8217;s redirection URI to cause hte client to access resources under the attacker&#8217;s control. This is known as CSRF.</p><p><strong>Mitigation</strong>: Linking the request to the user agent session is a sufficient countermeasure and can be implemented via including <code>state </code>or <code>nonce</code> values or using PKCE.</p><h3>8. PKCE Downgrade Attack</h3><p><strong>Threat Vector: </strong>If an attacker can disable PKCE in their authorization request, PKCE can be downgraded so that <code>state</code> is not used at all, leaving OAuth open to CSRF.</p><p><strong>Mitigation: </strong>It cannot be guaranteed that OAuth clients will universally implement <code>state</code> properly, so authorization servers must reject any <code>code_verifier </code>token requests if there were no <code>code_challenge </code>authorization requests.</p><h3>9. Access Token Leakage at the Resource Server</h3><p><strong>Threat Vector: </strong>Counterfeit or compromised resource servers can receive access token and use the authorization granted in that token to target other resource servers.</p><p><strong>Mitigation: </strong>Sender-constrained access tokens to prevent access replay attacks as well as audience restriction (see next one for more detail).</p><h3>10. Misuse of Stolen Access Tokens</h3><p><strong>Threat Vector: </strong>Access tokens can be stolen in various ways and then used to access other resource servers.</p><p><strong>Mitigation: </strong>Two primary strategies:</p><ol><li><p>Sender-constrained Access Tokens: The sender is obligated to demonstrate knowledge of a certain secret as a pre-requisite for a resource server to accept the sent token. This can be implemented by either Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (<a href="https://datatracker.ietf.org/doc/html/rfc8705">RFC 8705</a>) or Demonstrating Proof of Possession (<a href="https://datatracker.ietf.org/doc/html/rfc9449">RFC 9449)</a>.</p></li><li><p>Audience-Restricted Access Tokens: Audience restriction <code>aud</code> scopes a token to a defined resource server. This also can enable token format to be custom tailored for various audiences. Implementation mechanisms are documented in <a href="https://rfc-editor.org/rfc/rfc6749#section-3.3">RFC 6749 3.3</a> and <a href="https://datatracker.ietf.org/doc/html/rfc8707">RFC 8707</a></p></li></ol><h3>11. Open Redirection</h3><p><strong>Threat Vector: </strong>Open redirection at the client or authorization server level can introduce phishing or malicious redirects.</p><p><strong>Mitigation: </strong>On the client side, only redirect if target URL&#8217;s are allowed or request integrity can be validated (<a href="https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html">OWASP guidelines</a>). On the authorization server side, the client must always be authenticated before redirection.</p><h3>12. 307 Redirect</h3><p><strong>Threat Vector: </strong>If an HTTP 307 (Temporary Redirect) occurs at the OAuth auhtorization endpoint, this can leak user credentials to the client (which in most authorization grant flows should not be happening).</p><p><strong>Mitigation: </strong>HTTP 303 (See Other) is a better status code in this case because it converts POST to GET and drops the user credentials. </p><p>HTTP 302 is another option but can have more variable behavior depending on the browser.</p><h3>13. TLS Terminating Reverse Proxies</h3><p><strong>Threat Vector</strong>: If a reverse proxy is deployed in front of the application server and TLS traffic terminates at the proxy, an attacker could try to circumvent security controls by manipulating particular HTTP headers such as <code>X-Forwarded-For</code> and then gaining the ability to eavesdrop, inject, or replay messages.<code> </code></p><p><strong>Mitigation: </strong>Reverse proxies must sanitize inbound requests to ensure the authenticity and integrity of all header values relevant to application server security.</p><h3>14. Refresh Token Protection</h3><p><strong>Threat Vector: </strong>Refresh tokens grant full access to mint fresh access tokens. They can be stolen and replayed to gain access tokens.</p><p><strong>Mitigation: </strong>Documented in <a href="https://datatracker.ietf.org/doc/html/rfc6749">RFC 6749</a>. Use TLS in transit. Ensure tokens are confidential, unique, and non-guessable. Bind them to a specific client and leverage expiration, revocation, and rotation.</p><h3>15. Client Impersonating Resource Owner</h3><p><strong>Threat Vector: </strong>A resource server could mistake a client for a resource owner such as when a malicious client could set a <code>client_id </code>to a value identifying the resource owner instead, whereupon the authorization server may accidentally believe the client is the resource owner.</p><p><strong>Mitigation: </strong>Authorization servers should not allow clients to influence <code>client_id, </code>or if this is not possible, enforce another mechanism to distinguish between access tokens issued by client credentials and those issued by user-based authorization grant flows.</p><h3>16. Clickjacking</h3><p><strong>Threat Vector: </strong>Clickjacking (i.e. UI redressing) can trick a user to accidentally click on a hidden link that can redirect authorization and cause credential theft or scope manipulation.</p><p><strong>Mitigation: </strong>Authorization servers are responsible for preventing clickjacking by using CSP Level 2+ and <code>X-Frame-Options </code>headers. CSP is preferable for flexibility and multiple allowed origins.</p><h3>17. Attacks on In-Browser Communication Flows</h3><p><strong>Threat Vector: </strong>When OAuth uses <code>postMessage</code> (<a href="https://html.spec.whatwg.org/multipage/web-messaging.html#web-messaging">example</a>) instead of a redirect, which is common in SPAs, this can cause origin risks, with cross-site attacks</p><p><strong>Mitigation: </strong>Authorization servers must use exact string matching for receiver origins and should only send to trusted origins. Clients must reject messages from untrusted origins using strict <code>e.origin </code>checks. The idea is to extend all redirect-based protections to <code>postMessage</code> flows.</p><p></p><h2>Nutshell: 15 Best OAuth 2.0 Security Practices</h2><p>Combining all these various attack vectors and mitigations, here are 15 best practices highlighted in RFC 9700 to ensure tight security on OAuth flows.</p><ol><li><p>Redirect URIs should have exact string matching.</p></li><li><p>Avoid open redirectors.</p></li><li><p>Enforce HTTPS.</p></li><li><p>Never leak credentials during HTTP 307. (Use HTTP 303).</p></li><li><p>CSRF protection: PKCE for public clients, <code>nonce </code>for Open ID Connect, or state-bound CSRF tokens otherwise.</p></li><li><p>Only use secure and transaction-specific PKCE challenge methods (e.g. SHA-256)</p></li><li><p>If multiple authorization servers, use the <code>iss </code>parameter or secondarily distinct redirect URIs per server.</p></li><li><p>Never use Implicit grant. For public clients, use PKCE.</p></li><li><p>Never use Resource Owner Password Credentials (ROPC) Grant.</p></li><li><p>Use sender-constrained access and refresh tokens (via Mutual TLS or DPoP) where possible.</p></li><li><p>Use token scoping, audience restriction, and fine-grained access.</p></li><li><p>Use asymmetric client authentication.</p></li><li><p>Use authorization server metadata to auto-discover endpoints and enable secure client auto-configuration.</p></li><li><p>Verify <code>postMessage </code>origins.</p></li><li><p>Do not support CORS on the authorization endpoints.</p></li></ol><p></p><h1>Conclusion</h1><p>OAuth 2.0 has a plethora of practitioners, but only a subset of those individuals often conceptually grasp how the framework&#8217;s esoteric (and perhaps clunky) words connect to each other.</p><p>Despite its relative complexity, OAuth 2.0 is certainly one of the most robust authorization frameworks to have ever been developed, and it behooves even the junior engineer to learn its general ins-and-outs as part of their journey as a technologist.</p><p>Understanding these authorization flows not only strengthens how security is implemented but can also open the door for extensibility as more sophisticated, secure, and user-friendly auth experiences continue to be engineered.</p>]]></content:encoded></item><item><title><![CDATA[A History of Storage: Block]]></title><description><![CDATA[How drives, protocols, and networks have evolved to indefinite scale]]></description><link>https://tech.ngperrin.com/p/a-history-of-block-storage-mainframe</link><guid isPermaLink="false">https://tech.ngperrin.com/p/a-history-of-block-storage-mainframe</guid><dc:creator><![CDATA[Thinking through the Cloud]]></dc:creator><pubDate>Sat, 29 Mar 2025 22:32:09 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cf8482b5-5806-4100-9819-f5f2f58b2d64_5000x3970.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When cloud practitioners talk about cloud storage, they generally refer to three primary categories: block, file, and object storage. These are not comprehensive or fully exclusive categories, but they are consistently decisive ways of referring to the ways in which data may be stored in cloud systems.</p><p>Let us explore the history of each of these and what they entail. This post will focus on <strong>block storage</strong>. We will look at brief pockets in a deep history that could be far more technical and exhaustive than we will choose to be here. This is mainly for the amateur or professional seeking a deeper understanding of the machines we manage.</p><h2>Block Storage: Origins in the Mainframe</h2><p>The early days of computing depended upon expensive, bulky mainframes where we find the advent of disk-based technology.</p><p>We can start with the <a href="https://www.ibm.com/history/system-360">IBM System/360</a>, the famous &#8220;$5 billion gamble&#8221; introduced in 1964 which Jim Collins ranked among the top three business accomplishments of all time, next to the Boeing 707 and Ford Model T.</p><p>The System/360 presented a landmark computing architecture which consolidated a number of computing advancements within a single framework. This was where the 8-bit definition of &#8220;byte&#8221; was born.</p><p>Alongside the IBM System/360 emerged the <a href="http://www.columbia.edu/cu/computinghistory/2311.html">IBM 2311 Disk Storage drive</a>.</p><p>This disk storage drive provided direct access to 7.25 million 8-bit bytes per removeable disk pack. Eight drives could be attached to one single control unit for a total of 58MB with a transfer speed of 156 KB/s.</p><p>The disk was broken into a Cylinder/Head/Sector (CHS) geometry. Mainframe disks (14 inches in diameter) would rotate platters. Each platter had concentric tracks which in turn were grouped into <em>cylinders</em>, which were stacks of tracks aligned vertically across multiple platters. </p><p>Each track in turn was divided into a fixed or variable-sized <em>sectors</em> of data <em><strong>block</strong></em>, including the common pattern of 1024 byte blocks that are familiar to technologists today.</p><p>The <em>head</em> was the electromagnetic piece that hovers just about the disk platter and can either read or write data.</p><p>This was a <em>mechanical </em>process.</p><p>Read/write operations consisted of the following steps:</p><ol><li><p>The control unit would send a &#8220;seek&#8221; command to the drive. This would trigger the actuator to move the heads. </p></li><li><p>The head would seek the correct cylinder and the system would wait until it was positioned above the right location. Because of this, the physical distance of cylinder traversal would determine how long the seek took (the IBM 2311 boasted an average seek time of 85ms).</p></li><li><p>When the correct record physically rotates under the head, the control unit signaled the channel to start reading or writing the raw bitstream. By reading, the data would be assembled into a buffer that was passed into main memory. By writing, the control unit would magnetize the cylinder track surface to etch the correct data bits according to a particular format (e.g. Count-Key-Data, abbreviated as CKD) determined by the OS or access method.</p></li></ol><p>While this physical, magnetic procedure may seem foreign to us today, it is this underlying process which still defines how block storage works today, including modern operating systems.</p><p>We can glean these block storage principles from the IBM 2311:</p><ul><li><p>Data is organized into fixed sized blocks (e.g. 1024 bytes)</p></li><li><p>Data is addressed by a numeric identifier</p></li><li><p>The OS or hypervisor reads or writes data based on addressing</p></li><li><p>The storage hardware does not know anything about what is stored (i.e. no metadata)</p></li></ul><p>This is raw data. These fundamentals remain at the deepest layers under the hood of computing today.</p><h2>SCSI and Open Standard Disk Storage</h2><p>Block storage had its mainframe successors with IBM System/370 backed by the IBM 3330 and 3350 Winchester disk drives, IBM ESA/390 backed by 3390 as well as competitors such as the Honeywell 6000 or Burroughs B6500/6700.</p><p>These primarily operated under proprietary, internal channel interfaces.</p><p>This changed with the development of the <a href="https://bitsavers.trailing-edge.com/pdf/ansi/X3/SASI_revC_Jan82.pdf">Shugart Associates System Interface (SASI)</a> in the late 1970s whose primary objective was to attach hard drives to <em>multiple vendors&#8217; </em>computers. It was a move toward vendor neutrality via an open standard.</p><p>Much of SASI was co-opted into a more widely known standard <a href="https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub131.pdf">Small Computer System Interface (SCSI)</a> in 1986.</p><p>SCSI provided generic commands that could be applied across different vendors, such as INQUIRY, READ, WRITE, etc. This provided a higher level of abstraction where the SCSI device could handle seek times and geometry which no longer needed to be considered by the underlying host. The host would provide the commands and the firmware would translate into mechanical execution.</p><p>SCSI has since been extended into SAS, iSCSI, and Fibre Channel (FCI), all of which remain dependent upon that original SCSI command set.</p><p></p><h2>SATA and PC Block Storage</h2><p>By the 1980s, personal computing was on the rise and with it a concrete need to solve for the problem of storage. Integrated Drive Electronics (IDE) came about as a way to simplify PC hard drive connections by integrating the disk controller to the disk itself.</p><p>But PC drive storage truly hit its stride with ANSI&#8217;s ATA (AT attachment) as the <em>de facto </em>standard for PC consumers to interface with the hard drive.</p><p>This early iteration of ATA, now often referred to retroactively as PATA (Parallel ATA) was constrained by issues around signal integrity with the increase of bus speeds, primary/secondary configuration with multiple channels, and bandwidth ceilings generally hitting UDMA/133.</p><p>There was a need for better.</p><p>SATA (Serial ATA) 1.0 was published in 2003 (<a href="https://web.archive.org/web/20111001000000*/http://www.sata-io.org/documents/serialata10a.zip">downloadable as ZIP here</a>) out of the collaboration of multiple hardware vendors.</p><p>SATA 1.0 provided 1.5 GB/s signaling with ~150 MB/s throughput all while maintaining backwards compatibility with ATA.</p><p>It was then iterated on with SATA 2.0 (3.0 GB/s) the following year and by SATA 3.0 in 2009 (6.0 GB/s) with minor version increments since then. There has been no movement beyond this 6 GB standard primarily because of the push toward NVMe for high performance in the years to come.</p><p>Yet to this day SATA is of crucial importance for HDD storage of massive volumes at relatively low costs and remains a primary archival or backup strategy for cold data storage as the data at rest costs less per GB when compared against SAS or NVMe solutions.</p><p>Furthermore, SATA is recognized by nearly all hypervisors and operating systems, requiring almost no specialized hardware while maintaining a strong balance of performance and throughput for standard workloads.</p><h2>Fibre Channel, iSCSI and Networked Storage</h2><p>Before the 1980s, compute processes were attached to storage first through mainframe-style channel connections as we have seen above and then through directly attaching disk arrays to the hardware, what we now refer to as DAS (Direct Attached Storage).</p><p>However, personal computing meant multiple computers could be at play within a single data ecosystem, computers that were meant to talk to one another.</p><p>NAS (Network Attached Storage) solutions such as NFS (Network File System) in 1984 and SMB (Server Message Block) several years later were built to allow for <em>file </em>level sharing over a network.</p><p>This works for files but not for block-level access of data in the way that databases and many workloads would require. Organizations needed a way to standardize raw block device access across multiple servers.</p><p>Here is where SAN (Storage Access Network) comes into play as a new model for providing distributed block storage access, first through the invention of <strong>Fibre Channel</strong> in the 1990s.</p><p><a href="https://hsi.web.cern.ch/fcs/spec/overview.htm">Fibre Channel SAN</a> works by encapsulating SCSI commands within Fibre channel frames that adhere to the FCP (Fibre Channel Protocol). Servers could perform SCSI read and write operations over a dedicated FC fabric to a centralized storage array for the first time in history.</p><p>Now there were new possibilities for block-storage fault tolerance and high availability, but at the same time this new complexity raised new problems to solve for as well such as networking infrastructure, fabric topology design, and building host bus adapters.</p><p>The main problem is that Fibre Channel requires specialized hardware. As networking bandwidth capacity soared in the late 1990s, and IP networks took root, a new demand emerged to find both a cheaper and simpler way to handle block storage connectivity.</p><p>iSCSI (Internet SCSI) was standardized in 2004 to tunnel those SCSI commands over TCP/IP, codified in <a href="https://datatracker.ietf.org/doc/html/rfc3720">RFC 3720</a>.</p><p>Now for the first time servers could connect to remote block storage arrays using a standard Ethernet NIC or an iSCSI offload engine rather than needing a Fibre Channel Host Bus Adapter.</p><p>iSCSI gained widespread adoption particularly among cost-sensitive businesses, and as Ethernet continued to reach new speed ceilings (and with Offload NICs and Jumbo Frames coming into the picture), iSCSI came to significantly narrow the performance gap with FC.</p><p>To this day, FC and iSCSI remain common staples in enterprise data centers for handling storage networking.</p><h2>NVMe and the Solid State Drive</h2><p>HDD (Hard Disk Drives) have been all the rage for quite some time. They are one of those vestigial tethers back to those early days of mainframe computing because just like the IBM System/360 we discussed above, they depend upon rotating magnetic platters with a read/write actuator arm to access data. Although they may spin at 7,200 RPM they still have a seek time. They are fundamentally mechanical.</p><p>SSD (Solid State Drives) are a fundamental paradigm shift in this regard. They are the first quantum leap beyond magnetic platter drives to what we know as flash-based storage.</p><p>Flash memory is not a new thing. It was invented in the 1980s by engineers at Toshiba, deriving ideas and patterns from pre-existing EEPROM technology.</p><p>Flash memory can be divided into NOR flash and NAND flash (referring to the the NOR and NAND logic gates). NOR provides writing over an erased location at the granularity of the machine word with powerful direct random access at individual bytes. It has faster read speeds than its cousin NAND.</p><p>NAND flash memory can read, write, delete blocks through a serial access approach. While it may be less efficient for random access tasks, it introduces considerable cost-effective power for high-density data storage. NAND is the foundation of many flash-based technologies we are familiar with including USB drives, smart phones, and the SSD.</p><p>NAND flash SSDs no longer have a physical seek time where an actuator head spins over a magnetic drive like HDDs. Instead reads and writes occur electronically at microsecond-level latencies with significantly higher random I/O.</p><p>However, there remained a problem. </p><p>While SATA provides a wonderful level of host abstraction for read and write operations using SCSI commands, the <strong>standard was designed exclusively for mechanical drives</strong>. Consequently SATA SSDs encountered bottlenecks from the protocols used to access them.</p><p>The industry solution to this requires a brief rewind to 2003 when PCIe (Peripheral Component Interconnect Express) was introduced as a bus standard to serve as an alternative to SATA for SSDs, before SSDs were driven by flash technology. PCIe offers direct high speed links between the SSD and the CPU, designed from the bottom to maximize SSD efficiency.</p><p>This was then conjoined to <a href="https://nvmexpress.org/wp-content/uploads/NVM-Express-1_0e.pdf">NVMe (Non-Volatile Memory Express) in 2013</a> to complete a computer architecture standard which was built to fully leverage the parallelism possible in modern SSDs through physically storing a NVMe controller chip with the storage medium.</p><p>From the start, NVMe feature much higher IOPS and lower latency than SATA SSDs. Today&#8217;s performance-critical applications depend upon this kind of hardware.</p><p>This has even been extended to<a href="https://nvmexpress.org/specification/nvme-of-specification/"> NVMe-oF (NVMe over Fabrics)</a> which have attempted to apply the concept of direct-attached flash across entire networks. Just as Fibre Chanenl and iSCSI attempted to expand SCSI commands to the network layer, so too does NVMe-oF attempt to expand NVMe commands to the network layer as well.</p><p>PCIe and NVMe remain rapidly improving technologies, and it may not be long until HDD&#8217;s will only be considered an archival solution, much like tape storage today. Time shall tell what future horizons there are for block storage.</p><h2>Block Storage and Cloud Architecture</h2><p>Several considerations can be drawn from this cursory glance through block storage history within the context of cloud professionals.</p><p><em>First</em>, and this goes for data storage in general, the lifespan of an organization&#8217;s data assets can often indicate how many protocols it has jumped through, failed to jump through, or been caught up in some weird in-between state.</p><p>This is especially the case with many on-premise data solutions or even earlier implementations of cloud block storage.</p><p>History and operations can shape organizational data in a number of ways that may not be obvious at first glance. As Peter Drucker notes, you cannot underestimate how long temporary solutions simply live on by default.</p><p>It is always important to ask oneself if the decisions that shaped technology or data solutions a certain way were primarily determined by constraints or requirements that no longer remain relevant, or if there is a true ghost in the past that may emerge if you disrupt the "way things have always been done here&#8221;. </p><p>Both are possible. This requires case-by-case judgment.</p><p><em>Second, </em>interest in block storage does not seem to be going away anytime soon for IT professionals. If there is one consistency we can trace in this historical thread, it is that there has up until now been an intense interest and demand in optimizing and maximizing low-level data operations using block storage. Even as other data storage technologies wax and wane, block storage has been a consistent forerunner.</p><p>We can trace this to the fundamental advantages it has offered throughout history:</p><ul><li><p>It can offer high performance on random reads/writes (e.g. OLTP databases, queues)</p></li><li><p>Because it is not concerned with metadata, block storage can use any filesystem and offers great flexibility for formatting, encryption, and partitioning. </p></li><li><p>VM operating systems are strongly integrated with block volumes (e.g. AWS EBS, Azure Disk) to parallel standard computing orchestration. Block storage is a universally accepted, deeply integrated method for storage that can be transferred and migrated across a huge breadth of technology solutions (in contrast to much more opinionated storage methods such as key-value stores).</p></li></ul><p><em>Third, </em>here are some open-ended use case questions I will leave here that cloud professional could use to judge between various block storage solutions:</p><ul><li><p>Are the workload read/writes random or sequential? Is it more read intensive or write intensive? What are the latency requirements?</p></li><li><p>Does the workload need direct block device access (transactional databases and hypervisors do)?</p></li><li><p>What are the consistency model and redundancy expectations?</p></li><li><p>Is concurrent access a need for volumes, or is it acceptable for only one host to access a volume at a time?</p></li><li><p>What are the capacity, scaling, and cost needs?</p></li><li><p>What are the HA and Fault Tolerance requirements?</p></li><li><p>What layers and forms of encryption are required for data at rest?</p></li><li><p>How does it integrate with pre-existing hardware, systems, or data? How do your block storage choices align with the trajectory of organizational or industry technologies?</p></li><li><p>What are the retention and migration SLA expectations?</p></li><li><p>What levels of IT storage admin experience available and what maintenance overhead is acceptable or preferable for the business line?</p></li></ul><p></p><p>Through all of this, it truly is a marvel that through the radical changes that have swept through computing, one thing that remains the same is that we are still reading from and writing to <strong>blocks </strong>at the end of the day.</p>]]></content:encoded></item></channel></rss>