<?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[Frederic’s Substack]]></title><description><![CDATA[My personal Substack]]></description><link>https://fredferre.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!vvpX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F982fbae4-d4f3-4cd4-8a50-fe0e57d91926_1024x1024.png</url><title>Frederic’s Substack</title><link>https://fredferre.substack.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 06 May 2026 21:16:44 GMT</lastBuildDate><atom:link href="https://fredferre.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Frederic F.]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[fredferre@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[fredferre@substack.com]]></itunes:email><itunes:name><![CDATA[Frederic F.]]></itunes:name></itunes:owner><itunes:author><![CDATA[Frederic F.]]></itunes:author><googleplay:owner><![CDATA[fredferre@substack.com]]></googleplay:owner><googleplay:email><![CDATA[fredferre@substack.com]]></googleplay:email><googleplay:author><![CDATA[Frederic F.]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[The Bottleneck Was Never the Code]]></title><description><![CDATA[Three months of inverting our planning-to-coding ratio]]></description><link>https://fredferre.substack.com/p/the-bottleneck-was-never-the-code</link><guid isPermaLink="false">https://fredferre.substack.com/p/the-bottleneck-was-never-the-code</guid><dc:creator><![CDATA[Frederic F.]]></dc:creator><pubDate>Tue, 05 May 2026 09:13:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!iK4R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.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_!iK4R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iK4R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png 424w, https://substackcdn.com/image/fetch/$s_!iK4R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png 848w, https://substackcdn.com/image/fetch/$s_!iK4R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png 1272w, https://substackcdn.com/image/fetch/$s_!iK4R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iK4R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png" width="1456" height="931" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:931,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6238242,&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://fredferre.substack.com/i/196423644?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.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_!iK4R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png 424w, https://substackcdn.com/image/fetch/$s_!iK4R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png 848w, https://substackcdn.com/image/fetch/$s_!iK4R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.png 1272w, https://substackcdn.com/image/fetch/$s_!iK4R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F524cd625-9c48-4e64-ba99-c5026b3ff71f_2432x1555.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>Earlier this year we kept having to re-work our AI coding assistant&#8217;s implementation of every new Bottom Sheet we were adding to the app.</p><p>We use a custom <code>BottomSheet</code> component on our mobile app, a wrapper around React Native Bottom Sheet that abstracts the structure and parts of the layout. Every time we asked the AI to add a new sheet, it would re-implement the library from scratch. We&#8217;d revert the change. Next session, we&#8217;d ask for a different sheet. The AI would re-implement the wrapper again. Sometimes it broke the existing ones in the process.</p><p>It wasn&#8217;t a knowledge problem, we knew exactly how we wanted these components to be implemented. We just had to repeat ourselves over and over again. Yes code was written fast but we were losing the time gained by having to explain ourselves from scratch for each new case.</p><p>The honest read on what was happening: we had no machine-readable record of how to implement these Bottom Sheets in our app, what to abstract in that wrapper and what to leave customised by the inside component. The AI couldn&#8217;t reason about a convention it had never been told about. We&#8217;d been treating it as a faster typist when its actual constraint was context.</p><p>That realization changed how we work. Three months later, we spend 80% of our time stirring feature&#8217;s scope and iterating over the specs and 20% of the time implementing, the inverse of how we used to work until AI showed up. The mechanism isn&#8217;t a smarter model or better prompts. It&#8217;s a deliberate investment in the context that agents read before they touch anything.</p><blockquote><p><strong>If writing code is no longer rationed, what is the new shape of engineering work, and what new form of debt does it produce?</strong></p></blockquote><div class="paywall-jump" data-component-name="PaywallToDOM"></div><p>This is the first piece in a five-part series on what we built, what we learned, and what we still don&#8217;t know. Today: why documentation became the infrastructure of how we work, and what we actually centralize in it.</p><h2>Documentation was the bottleneck we kept ignoring</h2><p>Software development has had a technical documentation problem for decades, and it&#8217;s not a tooling problem. It&#8217;s a priority problem.</p><p>The traditional flow is well-understood. A product owner writes a spec. A designer translates it into screens. An engineer translates those into code. At every handoff, context degrades. The PM didn&#8217;t realise that by adding some nice to have requirements he was adding the overhead of having to create new tables or refactor the whole data model. The designer specified a navigation that conflicts with the current navigation structure.</p><p>Documentation was supposed to prevent this but it&#8217;s a challenge to keep maintaining it. The codebase was the source of truth, and the codebase could only be read by engineers. Knowledge lived in people&#8217;s heads, surfaced in chat threads, evaporated when someone left.</p><p>When AI coding assistants arrived, we used them the obvious way: write code faster. The result was instructive. We generated more code, but the spec-to-implementation gap didn&#8217;t close. We spent less time typing and more time correcting.</p><p>The uncomfortable insight: we thought AI was all about producing code that works fast but the real challenge is engineering its context so that it produces code that works fast but that leverages your engineers knowledge and adheres to your conventions and patterns so that your codebase stays consistent and clean. This is what in turn makes your system robust and every next move easier and easier.</p><p>So we stopped optimizing for code output and started investing in documentation infrastructure.</p><h2>What "80% planning, 20% coding" actually means</h2><p>It doesn&#8217;t mean more meetings. It means different artifacts, maintained at a different cadence, by a different group of people.</p><p>The PM starts a session to start ideating over a new product change. He/she goes back and forth about the why, for who, the scope and finally gets to the technical spec, the "how". This is the moment where AI leverages the documentation and other artefacts to design a solution anchored in the reality of the codebase. It suggests the changes to the system documentation to deliver this feature. The engineer can review that proposal and course adjust if needed.</p><p>When implementation begins, the developer pastes a refined-issue URL into the AI tool. The agent reads the issue which contains the why, what and how all in the same place. It has highly detailed instructions that a human could almost never write which allows the coding agent to implement the changes almost in one shot. The 20% is the coding step itself, which becomes largely mechanical when the spec is precise.</p><p>This only works if the documentation is precise <em>and</em> current. When it drifts, agents start hallucinating confidently, which is harder to catch than a compile error. The cost of poor documentation is no longer just human confusion. It&#8217;s bad code that looks right.</p><p>That&#8217;s what we mean by <em>context infrastructure</em>. The docs aren&#8217;t a reference artifact. They&#8217;re the literal input agents consume before taking action.</p><h2>What we centralize, and why</h2><p>Our documentation lives in a single repository, a <strong>Central Hub</strong>, separate from any product code. The same hub serves multiple codebases (in our case, a backend, a mobile app and a web app). When a convention gets updated, every agent on every project picks it up immediately.</p><p>The hub holds two layers: company and product context (vision, mission, personas and JTBD, design guidelines and brand tone of voice) and architectural (system documentation structured following the arc42 framework). Inside arc42 we use C4 to draw the architecture diagrams for each section, and ADRs to populate the dedicated decisions section (<a href="https://docs.arc42.org/section-9/">&#167;9</a>). None of these frameworks are novel on their own. What&#8217;s novel is that we&#8217;re not updating them after implementing a new change, we use them as context to write the spec for agents.</p><ul><li><p><strong>Vision, mission, brand, personas and JTBD, design guidelines and brand tone of voice.</strong> The company&#8217;s identity and direction: who it&#8217;s for, why it exists, how it presents itself. The Product Manager agent reads these before scoping a feature, and stress tests the proposed work against strategic pillars and current usage data. Work that doesn&#8217;t align with any pillar surfaces immediately as a conversation, not as something that quietly sneaks into a sprint.</p></li><li><p><strong>System documentation following <a href="https://arc42.org">arc42</a>.</strong> Stakeholders, quality goals, system decomposition, technology decisions, risks, and a shared glossary. The Architect agent reads the relevant sections before proposing any spec. arc42 is a free, open-source template that&#8217;s been around for over a decade. We adopted it because it gave us a structure we didn&#8217;t need to invent.</p></li><li><p><strong>Diagrams in <a href="https://c4model.com">C4</a>.</strong> arc42 calls for architecture diagrams in several sections; we draw ours using C4. It visualizes systems at four levels of detail (Context, Containers, Components, Code). Each level gives agents a map at the right zoom level: broad enough to understand boundaries, precise enough to understand business rules. We render the diagrams as Mermaid in markdown so they live next to the prose and version-control cleanly.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wMob!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wMob!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png 424w, https://substackcdn.com/image/fetch/$s_!wMob!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png 848w, https://substackcdn.com/image/fetch/$s_!wMob!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png 1272w, https://substackcdn.com/image/fetch/$s_!wMob!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wMob!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png" width="1139" height="482" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:1139,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43811,&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://fredferre.substack.com/i/196423644?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.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_!wMob!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png 424w, https://substackcdn.com/image/fetch/$s_!wMob!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png 848w, https://substackcdn.com/image/fetch/$s_!wMob!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.png 1272w, https://substackcdn.com/image/fetch/$s_!wMob!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e48067-d324-4ff2-8f64-2e87042ef7bd_1139x482.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>Of these formats, ADRs are the one that pays off most often. Most "AI hallucinations" we see in the wild aren&#8217;t really hallucinations. They&#8217;re decisions an agent made because nothing told it which way had already been chosen. An ADR collapses that ambiguity to a citation.</p><h2>What this looks like in practice</h2><p>A recent feature: a notification system to re-engage users after install.</p><p>Our human PM opened a session with the Product Manager agent. They worked through whether to build it (alignment with strategy and vision), what notifications triggers to build in which order, what success looked like (specific engagement metrics). The Architect agent reviewed feasibility against the existing architecture. The Developer agent explored the backend for existing event hooks that could trigger notifications. The session produced an ADR on the notification service choice, an update to the building block view, and three glossary entries.</p><p>From that spec, the Project Manager agent broke the work into Linear issues. Each issue referenced the relevant arc42 sections, the new ADR, and the acceptance criteria the PM session had defined.</p><p>When implementation began, the developer pasted the first issue&#8217;s URL into the tool. The agent read the issue, loaded the referenced arc42 sections and ADR, and applied the patterns defined in our shared rules. It wrote code that matched the conventions on the first pass. The code reviewer agent flagged one error-handling inconsistency on review; the developer agent fixed it. The PR merged.</p><p>We don&#8217;t have clean apples-to-apples comparison data, but features that used to take a day or more now routinely ship in an afternoon. More importantly, they ship in a state we don&#8217;t have to argue about: they follow the conventions we already documented. This eventually means less debates and re-work during pull request review.</p><h2>The new failure mode: context debt</h2><p>This isn&#8217;t free. We&#8217;ve replaced one kind of debt with another.</p><p>Technical debt used to cause bugs and decrease velocity. Now it also confuses agents and can introduce more tech debt. When the codebase has inconsistent patterns, agents don&#8217;t know which to follow. They pick one, and if it&#8217;s the wrong one, the team spends hours unwinding an implementation that went sideways. Tech debt is paid twice: once in defects and a second time when planning the next move.</p><p>The new form of debt is <strong>context debt</strong>: documentation that&#8217;s stale, incomplete, or ambiguous. It compounds the same way technical debt does.</p><p>There&#8217;s one extra propagation path: one agent&#8217;s hallucination, once written into a section or an ADR, becomes the next agent&#8217;s source of truth.</p><p>The honest version of "documentation-first development" is that drift is now visible (agents make bad specs). Even though it&#8217;s now easier than ever to maintain documentation thanks to AI and automation pipelines, it still requires a lot of focus and critical thinking to maintain the context infrastructure. During each session it&#8217;s about recognising missing or wrong context and creating tasks to improve the central hub so we don&#8217;t have to repeat ourselves next time.</p><h2>What we don&#8217;t know yet</h2><p>Three months in, four people, a greenfield project. The limits we know about:</p><ul><li><p><strong>Scale is unproven.</strong> This workflow works at four but will probably need to be re-structured for a bigger team.</p></li><li><p><strong>Greenfield helps.</strong> We had no legacy documentation to retrofit. Applying this to a ten-year-old codebase is a fundamentally different problem.</p></li><li><p><strong>The cost of staying current.</strong> Right now we can maintain the documentation because drift is visible. If team pace increases, the maintenance burden could compound faster than we can absorb it.</p></li></ul><p>We&#8217;re sharing what we learned because the direction seems clear, not because we&#8217;re certain it scales. The bottleneck was never typing speed. Code was rationed, and we mistook the rationing for the work. The work is shared understanding, built by humans, together.</p><p><em>Next in this series, in two weeks: <strong>Agentic Product Management</strong>. If documentation is the foundation, what does the layer above look like? What changes about product management when refinement happens with agents in the room?</em></p>]]></content:encoded></item><item><title><![CDATA[AI Dashboard Generator: Describe Data, Get Visualizations]]></title><description><![CDATA[AI Dashboard Generator: Describe Data, Get Visualizations]]></description><link>https://fredferre.substack.com/p/ai-dashboard-generator-describe-data</link><guid isPermaLink="false">https://fredferre.substack.com/p/ai-dashboard-generator-describe-data</guid><dc:creator><![CDATA[Frederic F.]]></dc:creator><pubDate>Sat, 14 Feb 2026 15:07:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kA5y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7da0bfe-89e6-4720-914f-6a96675e3250_2836x1572.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/freddo1503/mystique&quot;,&quot;text&quot;:&quot;Mystique&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/freddo1503/mystique"><span>Mystique</span></a></p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7da0bfe-89e6-4720-914f-6a96675e3250_2836x1572.png&quot;}],&quot;caption&quot;:&quot;Describe what you want to see. The system figures out the rest.&quot;,&quot;alt&quot;:&quot;Retro futuristic illustration of a person wearing augmented reality glasses viewing holographic data dashboard charts&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7da0bfe-89e6-4720-914f-6a96675e3250_2836x1572.png&quot;}},&quot;isEditorNode&quot;:true}"></div><h2><strong>Every Dashboard I&#8217;ve Built Has the Same Problem</strong></h2><p>Here&#8217;s a story you&#8217;ve probably lived. You join a project, and someone asks for a dashboard. You spend a few days figuring out the data source, writing API calls or SQL queries, choosing chart types, wiring up data mappings, tweaking the layout, styling it. You ship it. Everyone&#8217;s happy.</p><p>Two weeks later, someone wants different metrics. The team pivots to tracking something else entirely. You rebuild half the dashboard. Then the other half. Then you start wondering why you&#8217;re spending more time maintaining visuali</p><p>zations than building the product itself.</p><p>Charting isn&#8217;t the hard part. Libraries like ECharts or Recharts can render beautiful charts from a JSON config. That&#8217;s a solved problem. The hard part is everything <em>around</em> the chart: the manual mapping between &#8220;what I want to see&#8221; and &#8220;how to fetch and display it.&#8221; Figuring out the right API call, extracting the right fields, choosing the right chart type, mapping data to axes, laying it all out. That&#8217;s where all the time goes, and every time a requirement changes, it breaks.</p><p>I kept running into this, and at some point the question shifted: <em>what if I could just describe what I want to see, and the system figures out how to get it and show it?</em></p><p>That question is what led me to build <a href="https://github.com/freddo1503/mystique">Mystique</a>.</p><h2><strong>Let the Model Do the Mapping</strong></h2><p>Charting libraries already speak JSON. ECharts takes a JSON options object. Grafana dashboards are JSON files. This isn&#8217;t new. What&#8217;s new is that language models have gotten good enough at structured output to <em>generate</em> these configs reliably from natural language.</p><p>That&#8217;s the entire idea behind Mystique. You describe a dashboard in plain English. A language model generates a valid JSON config: which APIs to call, what fields to extract, how to map them to chart axes, what chart types to use, how to lay it all out. The config gets validated, the data gets fetched, and the charts render.</p><p>The model doesn&#8217;t just pick a chart type. It figures out the entire pipeline. When you say &#8220;show me product prices and ratings,&#8221; it identifies the right API endpoint, determines which response fields to visualize, decides whether a bar chart or scatter plot fits better, maps fields to x and y axes, and arranges everything in a responsive grid.</p><p>The key mechanism that makes this reliable is <em>structured output</em>. I&#8217;m using the Vercel AI SDK, which lets you pass a Zod schema to the language model and constrain its output to conform to it. The model can only produce JSON that matches the contract. This isn&#8217;t a &#8220;generate some JSON and hope it parses&#8221; situation. The output is structurally guaranteed to be valid.</p><p>To help the model produce <em>good</em> configs (not just valid ones), I use few shot examples in the prompt: natural language descriptions paired with high quality dashboard configs that teach the model what good looks like. The temperature is set low, 0.2, for consistency.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TkC4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TkC4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png 424w, https://substackcdn.com/image/fetch/$s_!TkC4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png 848w, https://substackcdn.com/image/fetch/$s_!TkC4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png 1272w, https://substackcdn.com/image/fetch/$s_!TkC4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TkC4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png" width="238" height="593.140625" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1914,&quot;width&quot;:768,&quot;resizeWidth&quot;:238,&quot;bytes&quot;:84959,&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://fredferre.substack.com/i/187955333?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.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_!TkC4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png 424w, https://substackcdn.com/image/fetch/$s_!TkC4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png 848w, https://substackcdn.com/image/fetch/$s_!TkC4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.png 1272w, https://substackcdn.com/image/fetch/$s_!TkC4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2a6c6b3-1576-455b-bbd4-3711670fb186_768x1914.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><h2><strong>Watching a Dashboard Build Itself</strong></h2><p>The part that really sold me on this approach is progressive streaming. In the demo application, the AI doesn&#8217;t generate the entire config and then render it. The config streams in token by token, and the dashboard renders <em>as the AI thinks</em>. You type a description, hit generate, and charts start materializing on screen while the model is still working.</p><p>This required a bit of care. You can&#8217;t render half a config or you&#8217;d get missing chart references and broken layouts. So there&#8217;s a guard that checks whether enough structure has arrived before attempting to render. It waits until the config has at least one complete chart with field mappings, a data source with a URL, and a layout position. Only then does the dashboard appear. As more charts stream in, they fill the grid progressively.</p><p>The experience of watching a dashboard build itself from a sentence is surprisingly compelling. It makes the abstract idea, &#8220;describe what you want, get a visualization,&#8221; feel real.</p><h2><strong>Dashboards That Don&#8217;t Need to Exist Forever</strong></h2><p>This is the paradigm shift I&#8217;m most excited about. If the AI can reliably generate valid configs from descriptions, then dashboards become disposable. You describe what you need right now, you get it right now, and you discard it when you&#8217;re done. No maintenance burden. No stale metrics. Just a fresh answer to a fresh question.</p><p>When you say &#8220;show me product prices by category,&#8221; you&#8217;re expressing intent, not writing configuration. You don&#8217;t need to know the API schema. You don&#8217;t need to know what chart type works best. You just need to know what question you&#8217;re trying to answer.</p><p>Today Mystique works with REST APIs. The architecture uses pluggable data adapters, which means SQL and database connectors are the natural next step. Imagine describing &#8220;show me monthly revenue by region&#8221; and the AI writes the SQL query, fetches the data, and renders the chart.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/freddo1503/mystique&quot;,&quot;text&quot;:&quot;Mystique&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/freddo1503/mystique"><span>Mystique</span></a></p><div><hr></div><p><em>Have questions or want to discuss potential collaborations? Feel free to reach out in the comments below or connect with me directly!</em></p><p><a href="https://www.linkedin.com/in/fferrera31/">Linkedin</a> | <a href="https://fredferre.com/">Portfolio</a></p>]]></content:encoded></item><item><title><![CDATA[Deploying Strapi on AWS: A Flexible and Scalable Approach]]></title><description><![CDATA[Building MVPs with a modern headless CMS]]></description><link>https://fredferre.substack.com/p/deploying-strapi-on-aws-a-flexible</link><guid isPermaLink="false">https://fredferre.substack.com/p/deploying-strapi-on-aws-a-flexible</guid><dc:creator><![CDATA[Frederic F.]]></dc:creator><pubDate>Wed, 17 Sep 2025 14:05:22 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/60b51f9b-4f36-4ec4-b648-a1b30d00a0f9_1536x1024.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_!u3sU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!u3sU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!u3sU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!u3sU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!u3sU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!u3sU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1615026,&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://fredferre.substack.com/i/173852077?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.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_!u3sU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!u3sU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!u3sU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!u3sU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8322535-a323-4d62-9c9e-d49d4babd3ab_1536x1024.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 class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/freddo1503/strapi-on-aws&quot;,&quot;text&quot;:&quot;Github&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/freddo1503/strapi-on-aws"><span>Github</span></a></p><p>Strapi has gained popularity as a headless CMS for rapid application development, making it a strong candidate for Minimum Viable Products (MVPs). Because of its JavaScript-based, open-source nature, it can adapt quickly to changing requirements &#8212; a critical factor when your primary goal is to validate ideas and gather user feedback.</p><p>In this post, I'll walk you through how you can deploy Strapi on AWS to achieve flexibility, scalability, and cost-effectiveness.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fredferre.substack.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">Frederic&#8217;s Substack is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</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><h2>Why Use Strapi for an MVP?</h2><p>An MVP often has two main objectives: reduce time to market and validate product-market fit. Strapi fulfills these needs by offering:</p><p><strong>Rapid Development</strong>: Its intuitive admin panel and pre-built APIs reduce the need for extensive boilerplate code.</p><p><strong>Adaptability</strong>: You can customize data models and permissions without being locked into proprietary ecosystems.</p><p><strong>Neutral Ecosystem</strong>: Strapi runs on Node.js, which makes it easy to integrate with other services across different cloud environments.</p><p>These traits make Strapi one of several potential solutions for MVPs. While it's not the only headless CMS on the market, its flexibility makes it worth considering.</p><h2>Key AWS Services for Deployment</h2><p>Here are the core AWS services that form the backbone of this architecture:</p><p><strong>Amazon Elastic Container Service (ECS)</strong>: By containerizing Strapi, you can simplify your deployment and scale your containers in response to traffic spikes. ECS orchestrates containers, reducing manual server management.</p><p><strong>Amazon Elastic Container Registry (ECR)</strong>: This is where you can store container images securely and integrate seamlessly with ECS for automated deployments.</p><p><strong>AWS Fargate</strong>: As a serverless compute engine, Fargate allows you to run containers without provisioning or managing servers. It also scales automatically based on defined CPU and memory requirements.</p><p><strong>Amazon RDS</strong>: For database management, RDS takes care of updates, backups, and failover. Popular engines like PostgreSQL and MySQL are supported, ensuring Strapi's database remains robust and easy to scale.</p><p><strong>Amazon S3</strong>: When handling media files, S3 provides a cost-effective storage solution. It's particularly useful for large file uploads, backups, and static asset hosting.</p><p>These services, when combined, form the backbone of a flexible, scalable architecture. Feel free to substitute or remove services based on your project's unique needs and constraints.</p><h2>Benefits of This Approach</h2><p><strong>Cost-Effectiveness</strong>: By leveraging serverless services like Fargate, you only pay for what you use. Autoscaling features reduce expenses during low-traffic periods.</p><p><strong>Ease of Scaling</strong>: ECS with Fargate can automatically adjust container instances according to demand, preventing downtime or performance bottlenecks.</p><p><strong>Adaptability</strong>: AWS offers a broad range of services, giving you the flexibility to add or swap components (e.g., switching to Amazon DynamoDB if you prefer a NoSQL approach).</p><p><strong>Reduced Maintenance</strong>: Offloading tasks like database patching and server updates to managed services lets you focus more on product development and less on infrastructure.</p><h2>Wrapping Up</h2><p>Whether you're building an MVP or looking for a robust content management layer, Strapi deployed on AWS can be a compelling choice. It delivers the speed, flexibility, and scalability many teams look for in early-stage projects, while also providing an adaptable foundation for future growth.</p><p>Still, it's just one option in the world of headless CMS solutions, so be sure to evaluate your requirements and budget before committing.</p><div><hr></div><p><em>Have questions or want to discuss potential collaborations? Feel free to reach out in the comments below or connect with me directly!</em></p><p><a href="https://www.linkedin.com/in/fferrera31/">Linkedin</a> | <a href="https://fredferre.com">Portfolio</a></p>]]></content:encoded></item></channel></rss>