<?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[Keep Shipping]]></title><description><![CDATA[Ideas, mental models and strategies for AIOps, platform engineering, and making cloud infrastructure self-driven & invisible.]]></description><link>https://blog.localops.co</link><image><url>https://substackcdn.com/image/fetch/$s_!athx!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ff1079-82e4-445b-bea1-9d58ed4ad9f5_240x240.png</url><title>Keep Shipping</title><link>https://blog.localops.co</link></image><generator>Substack</generator><lastBuildDate>Sun, 03 May 2026 00:55:57 GMT</lastBuildDate><atom:link href="https://blog.localops.co/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[LocalOps Inc.]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[localops@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[localops@substack.com]]></itunes:email><itunes:name><![CDATA[LocalOps Inc]]></itunes:name></itunes:owner><itunes:author><![CDATA[LocalOps Inc]]></itunes:author><googleplay:owner><![CDATA[localops@substack.com]]></googleplay:owner><googleplay:email><![CDATA[localops@substack.com]]></googleplay:email><googleplay:author><![CDATA[LocalOps Inc]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Introducing Projects]]></title><description><![CDATA[Isolate members & environments in your organization]]></description><link>https://blog.localops.co/p/introducing-projects-597</link><guid isPermaLink="false">https://blog.localops.co/p/introducing-projects-597</guid><dc:creator><![CDATA[Anand]]></dc:creator><pubDate>Tue, 28 Apr 2026 12:04:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EA1l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Our customers wanted to isolate people &amp; environments across different <em>projects</em> so that their team doesn&#8217;t deploy / see environments they don&#8217;t belong to.</p><p>We re-imagined and re-built <strong>Projects</strong> to solve this. </p><p>Along the way, we made a ton of UI enhancements to make it easier to create multiple projects, switch between them and isolate cloud environments with clarity.</p><p>We consciously didn&#8217;t invest time in building complicated RBAC features to make things simple for admins to govern environments and easier for teams to isolate and secure resources without getting into Spaghetti full of permissions and roles configurations.</p><h2>Projects</h2><p>A project is a place where environments and members working on one product or client or an agenda can be grouped together in one place. Go to &#8220;<strong>Projects</strong>&#8221; section under Organization menu to create/manage projects. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EA1l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EA1l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png 424w, https://substackcdn.com/image/fetch/$s_!EA1l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png 848w, https://substackcdn.com/image/fetch/$s_!EA1l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png 1272w, https://substackcdn.com/image/fetch/$s_!EA1l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EA1l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png" width="1456" height="922" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:922,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1985133,&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://blog.localops.co/i/195534448?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.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_!EA1l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png 424w, https://substackcdn.com/image/fetch/$s_!EA1l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png 848w, https://substackcdn.com/image/fetch/$s_!EA1l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.png 1272w, https://substackcdn.com/image/fetch/$s_!EA1l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96b63c9a-5495-400a-b6e7-e667a9992769_3528x2235.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>Say you&#8217;re building an Agentic CRM product. You can create a project and organize environments as follows.</p><p><strong>Project Name: Agentic CRM</strong></p><p>Environments you can create and group under the project:</p><ol><li><p>CRM QA</p></li><li><p>CRM UAT</p></li><li><p>CRM Production</p></li></ol><p><strong>Members:</strong> Can include people who work on the CRM project. Unless they belong to the project, they won&#8217;t be able to access or deploy in above environments.</p><p>Unless someone belongs to Agentic CRM project, they can&#8217;t see or deploy in above environments.</p><p>Another example - say you are product studio/agency and your dev team is building applications for a client - Acme Co. You can then create a project as follows.</p><p><strong>Project Name: Acme Co</strong></p><p>Environments:</p><ol><li><p>ACME QA</p></li><li><p>ACME UAT</p></li><li><p>ACME Prod</p></li></ol><p>Or say you have <a href="https://localops.co/case-study/suprsend-unlocks-enterprise-revenue-byoc">BYOC distribution for your service</a> for your enterprise customers and you&#8217;re deploying &amp; managing such environments on the customer&#8217;s cloud accounts as In-VPC distribution, you can have a project as follows. <em>And assign specific DevOps engineers to manage such customer environments.</em></p><p><strong>Project Name: BYOC distribution</strong></p><p>Environments:</p><ul><li><p>Acme Co</p></li><li><p>Heist enterprise</p></li><li><p>Trust bank</p></li><li><p>and so on..</p></li></ul><p><strong>Default project:</strong> For every new signup/organization, we create a &#8220;Default" project for convenience. Any number of additional projects can be created as appropriate to your setup. </p><h2>Brand new navigation:</h2><p>Until now, the sidebar navigation had a flat menu structure that let users navigate between environments, connections and code repositories. </p><p>With Projects coming in as a native group method, we are introducing a project switcher at the top so users can switch between their projects in 1-click.</p><p>And we have cleaned up all the menu structure to clearly indicate which menus belong to a <strong>Project scope</strong> and which ones belong to their <strong>Organization&#8217;s scope</strong>. This gives clarity over what is isolated and grouped under projects and what functionality works at the organization scope. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tEGh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tEGh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png 424w, https://substackcdn.com/image/fetch/$s_!tEGh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png 848w, https://substackcdn.com/image/fetch/$s_!tEGh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png 1272w, https://substackcdn.com/image/fetch/$s_!tEGh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tEGh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png" width="1456" height="1175" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1175,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2658026,&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://blog.localops.co/i/195534448?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.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_!tEGh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png 424w, https://substackcdn.com/image/fetch/$s_!tEGh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png 848w, https://substackcdn.com/image/fetch/$s_!tEGh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.png 1272w, https://substackcdn.com/image/fetch/$s_!tEGh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12b9874d-b4b3-4512-9824-280031653dfa_3147x2540.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>New clean URLs:</h2><p>We put a lot of effort in making the platform super simple to navigate and are a big fan of clean URLs. </p><p>We have now cleaned up all the page URLs of the console (&amp; our product documentation &#128517;) so that they now have a URL clearly indicating the hierarchical context of capabilities (Orgs &gt; Projects &gt; Environments).</p><p>Some examples for you:</p><ul><li><p>https://console.localops.co/localops-inc/org-projects</p></li><li><p>https://console.localops.co/localops-inc/projects/65a299d7-a1ee-4547-8f3e-14e6d0b61dd6/environments</p></li><li><p>https://console.localops.co/localops-inc/projects/65a299d7-a1ee-4547-8f3e-14e6d0b61dd6/members</p></li><li><p>https://console.localops.co/localops-inc/projects/65a299d7-a1ee-4547-8f3e-14e6d0b61dd6/deployments</p></li><li><p>https://console.localops.co/localops-inc/connections</p></li></ul><p>Our roadmap has more capabilities coming in to let teams organize their setup and manage their AWS environments with much more ease. </p><p><strong>Want to solve similar problems in your cloud operations?</strong></p><p>Get started with a quick demo at <a href="https://go.localops.co/tour">https://go.localops.co/tour</a>. Our engineers will guide you with a personalized tour.</p><p>Cheers.</p><p></p>]]></content:encoded></item><item><title><![CDATA[Open-Source Heroku Alternatives: What Works in Production and What Doesn't]]></title><description><![CDATA[Thinking of using open-source Heroku alternatives for production? Here&#8217;s what works, what doesn&#8217;t, and the real cost most teams miss.]]></description><link>https://blog.localops.co/p/open-source-heroku-alternatives</link><guid isPermaLink="false">https://blog.localops.co/p/open-source-heroku-alternatives</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Fri, 24 Apr 2026 14:06:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!E_qH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.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_!E_qH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E_qH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png 424w, https://substackcdn.com/image/fetch/$s_!E_qH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png 848w, https://substackcdn.com/image/fetch/$s_!E_qH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png 1272w, https://substackcdn.com/image/fetch/$s_!E_qH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E_qH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png" width="1345" height="1049" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1049,&quot;width&quot;:1345,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2278212,&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://blog.localops.co/i/195335385?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca77cfbd-4897-439f-a0c3-6017fe5527ed_1345x2400.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_!E_qH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png 424w, https://substackcdn.com/image/fetch/$s_!E_qH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png 848w, https://substackcdn.com/image/fetch/$s_!E_qH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.png 1272w, https://substackcdn.com/image/fetch/$s_!E_qH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40151fa9-6f3a-44b9-adb3-cb120106cf13_1345x1049.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><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> What open-source Heroku alternatives actually deliver in production versus in demos, the real build-versus-buy cost of running a self-hosted alternative when engineering hours and on-call burden are included, and the long-term architectural risks that engineering leaders accept when choosing between a managed PaaS and a self-hosted cloud-native IDP.</p><p><strong>Who it is for:</strong> CTOs and VPs of Engineering evaluating Heroku alternatives in 2026, specifically teams that have looked at Coolify, Dokku, Caprover, or CapRover and are trying to determine whether the open-source route is the right call for a production workload.</p><p><strong>The conclusion:</strong> Open-source Heroku alternatives are genuinely good for specific use cases: small teams, internal tooling, hobby workloads, and teams with a dedicated platform engineer who wants full control over every configuration surface. For scaling SaaS teams with production reliability requirements, enterprise compliance obligations, and engineering organisations where platform maintenance competes with product development for senior engineering hours, the total cost of a self-hosted alternative consistently exceeds that of a managed cloud-native IDP, once all hours are included. This guide shows exactly where costs accumulate and what the architectural risks look like over a three-year horizon.</p><blockquote><p>Evaluating whether to build or buy your platform?<br>&#8594; <a href="https://localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how a production-ready AWS environment is set up in 30 minutes</a></p></blockquote><h2><strong>The Open-Source Heroku Alternative Landscape in 2026</strong></h2><p>The field of open-source Heroku alternatives is active and well-populated. Teams evaluating the category in 2026 have meaningful options, each with a different point of view on how to replicate Heroku&#8217;s developer experience on self-hosted infrastructure.</p><p><strong>Dokku</strong> is the oldest and most established option. It describes itself as a &#8220;Docker-powered mini-Heroku&#8221; and implements the Heroku buildpack interface on a single server. Push to a Git remote, Dokku builds and deploys. The operational model is close to Heroku for simple applications. The scaling model, Dokku, runs on a single server, which is the primary limitation.</p><p><strong>Coolify</strong> is the most actively developed option in 2026. It provides a web UI for managing applications, databases, and services across multiple servers. It supports Docker Compose deployments and has grown its feature set significantly. It has a strong following among indie developers and small teams.</p><p><strong>CapRover</strong> sits between Dokku and Coolify in complexity. It runs on Docker Swarm, supports multiple nodes, and provides a dashboard for application management. It is more capable than Dokku for multi-service architectures but less actively developed than Coolify.</p><p><strong>Kamal</strong> (formerly MRSK, from the Rails team at 37signals) takes a different approach: it deploys Docker containers to bare servers using SSH, with zero platform software running on the target servers. It is a deployment tool more than a platform, and it requires more operational involvement than the others.</p><p>Each of these tools has genuine strengths. None of them is a complete substitute for Heroku at the production scale for a B2B SaaS team with reliability requirements and enterprise customers. The gap between what they demonstrate in a tutorial and what they require in production is where the real evaluation happens.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vsdM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vsdM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png 424w, https://substackcdn.com/image/fetch/$s_!vsdM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png 848w, https://substackcdn.com/image/fetch/$s_!vsdM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png 1272w, https://substackcdn.com/image/fetch/$s_!vsdM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vsdM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png" width="1240" height="652" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:652,&quot;width&quot;:1240,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:102062,&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://blog.localops.co/i/195335385?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.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_!vsdM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png 424w, https://substackcdn.com/image/fetch/$s_!vsdM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png 848w, https://substackcdn.com/image/fetch/$s_!vsdM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.png 1272w, https://substackcdn.com/image/fetch/$s_!vsdM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae2f03e-d73c-4e78-8f73-8dc97ead4623_1240x652.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>Want to skip managing platform layers entirely?<br>&#8594; <a href="https://docs.localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Explore how LocalOps handles infrastructure, deployments, and observability on AWS</a></p><h2><strong>What Open-Source Heroku Alternatives Actually Deliver in Production</strong></h2><p>The honest evaluation of open-source Heroku alternatives requires separating two distinct questions: what do they deliver at initial setup, and what do they require to operate reliably at production scale over time?</p><p>The initial setup story for most open-source Heroku alternatives is genuinely good. Dokku on a DigitalOcean droplet or a small EC2 instance can be running and deploying applications within an hour. Coolify&#8217;s setup process is well-documented and fast. For a team deploying a single application with a Postgres database and basic monitoring, these tools deliver the Heroku-like experience they promise.</p><p>The production-scale story is where the honest picture diverges from the tutorial experience.</p><p><strong>What works well in production:</strong></p><p><em><strong>Single-server deployments for low-traffic applications</strong>.</em> Dokku and Coolify are reliable for applications that fit on a single server with headroom. Internal tools, admin dashboards, low-traffic marketing sites, and development environments run well on these platforms. The operational model is simple because the infrastructure is simple.</p><p><em><strong>Teams with a dedicated platform engineer</strong>.</em> Open-source Heroku alternatives work in production when there is a person on the team whose job it is to maintain the platform, respond to platform failures, and keep the underlying infrastructure patched and healthy. The platform does not manage itself; it requires ownership. When that ownership is clearly assigned, and the person has the skills to carry it, these tools can support meaningful production workloads.</p><p><em><strong>Non-critical workloads where downtime is acceptable</strong>.</em> Tools, demos, staging environments, and internal services where an hour of downtime does not translate directly to customer impact or revenue loss tolerate the failure modes of self-hosted platforms better than customer-facing production services do.</p><p><strong>What breaks or degrades at the production scale:</strong></p><p><em><strong>Multi-node reliability</strong>.</em> Dokku is fundamentally a single-server platform. Dokku Scheduler plugins exist to add Kubernetes or Nomad scheduling, but they add significant operational complexity and are not production-proven at the same level as the core Dokku runtime. Coolify&#8217;s multi-server support is functional but has more surface area for failure than a managed Kubernetes cluster operated by a team with dedicated expertise.</p><p><em><strong>Automatic failover</strong>.</em> When the server running a Dokku deployment fails, the application goes down. Bringing it back up requires either manual intervention or a separately built and maintained automated recovery system. Heroku handles dyno failure transparently. Managed Kubernetes on EKS handles pod failure transparently. Self-hosted platforms without a managed control plane require explicit failover engineering.</p><p><em><strong>Observability at scale</strong>.</em> The default observability story for most open-source Heroku alternatives is thin. Coolify provides basic container metrics. Dokku provides application logs through dokku logs. Neither provides the integrated metrics collection, log aggregation, and dashboard correlation that production incident response requires. Teams running these platforms in production typically assemble a separate observability stack, Prometheus, Loki, and Grafana, on top of the platform, which is the same assembling problem that Heroku&#8217;s add-on model creates, shifted from a managed service to a self-hosted infrastructure project.</p><p><em><strong>Security patching cadence</strong>.</em> Open-source platforms run on servers that require OS-level patching, Docker runtime updates, and platform software updates. These updates need to happen on a cadence that matches the vulnerability disclosure cycle, which is roughly continuous. On a managed platform, Heroku or a cloud-native IDP, the platform team handles this. On a self-hosted alternative, someone on the engineering team handles it. That someone is typically the same person who handles production incidents, infrastructure changes, and developer support requests.</p><h2><strong>The Real Operational Limitations of Open-Source Heroku Alternatives</strong></h2><p>This is the gap between what open-source Heroku alternatives promise and what they deliver for scaling startup teams, and it is worth examining each limitation specifically rather than in aggregate.</p><p><strong>Limitation 1: Scaling models that don&#8217;t match production workload patterns.</strong></p><p>Dokku scales vertically by default: increase the server size to handle more load. Horizontal scaling in Dokku requires additional configuration and is not automatic. Coolify and CapRover support Docker Swarm for multi-node deployments, but Docker Swarm&#8217;s autoscaling model is limited compared to Kubernetes&#8217; Horizontal Pod Autoscaler.</p><p>For workloads with variable traffic, B2B SaaS applications that peak during business hours, consumer applications with campaign-driven spikes, and any application with non-linear load patterns, the inability to autoscale horizontally based on real-time resource metrics is a meaningful operational gap. Teams either overprovision the server (paying for idle capacity continuously) or accept that traffic spikes will cause degraded performance until someone manually adjusts the infrastructure.</p><p><strong>Limitation 2: Database management is the team&#8217;s responsibility.</strong></p><p>Heroku Postgres is a managed database: provisioning, backups, point-in-time recovery, connection pooling, version upgrades, and failover are handled by the platform. Open-source Heroku alternatives do not provide managed databases. Coolify can deploy a Postgres container; it does not manage it the way Heroku Postgres or Amazon RDS does.</p><p>Running a production Postgres database correctly, with automated backups, point-in-time recovery, failover, connection pooling, and a maintenance window strategy for version upgrades, is a non-trivial operational project. Teams that migrate to an open-source Heroku alternative and bring their Postgres database with them are taking on database operations as an engineering responsibility. For teams without database operations expertise, this is where production incidents happen.</p><p><strong>Limitation 3: SSL, networking, and security configuration are manual and ongoing.</strong></p><p>Heroku handles SSL termination, HTTP-to-HTTPS redirection, and TLS certificate renewal automatically. Open-source alternatives handle this through Let&#8217;s Encrypt integration (Coolify, Dokku, and CapRover all support this), but certificate renewal failures, DNS configuration errors, and networking changes are the team&#8217;s operational responsibility.</p><p>At low service count, this is manageable. As the service count grows, ten, fifteen, twenty services, the surface area for SSL and networking configuration errors grows proportionally. Each service is an additional certificate to renew, an additional DNS record to maintain, and an additional networking configuration that can drift from the intended state.</p><p><strong>Limitation 4: No compliance posture for enterprise customers.</strong></p><p>Open-source Heroku alternatives running on a VPS or small EC2 instance do not provide the compliance infrastructure that enterprise procurement requires: dedicated VPC, IAM-based access control with audit logs, network isolation between services, data residency in a specified region, and evidence of SOC 2 or equivalent security posture.</p><p>For B2B SaaS teams without enterprise ambitions, this may not matter today. For teams with any enterprise go-to-market motion, the infrastructure needs to satisfy the security questionnaire that accompanies every significant deal. An application running on a Coolify-managed Docker host cannot answer that questionnaire honestly. The compliance gap that exists on Heroku also exists on most open-source Heroku alternatives, and in some cases is larger, because self-hosted infrastructure adds an operational attack surface that managed platforms control more tightly.</p><blockquote><p>These are the exact gaps teams hit at scale<br>&#8594; <a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Talk to an engineer about how teams move off self-hosted setups without downtime</a></p></blockquote><p><strong>When should a scaling startup choose a managed cloud-native IDP instead?</strong></p><p>The decision point is not binary, but there are clear signals that the open-source route is the wrong call for a specific team:</p><ul><li><p>The team has more than five engineers, and product development competes directly with platform maintenance for senior engineering time</p></li><li><p>The product has enterprise customers or is actively pursuing enterprise deals that will require security questionnaire responses.</p></li><li><p>The application has stateful workloads, background job queues, WebSocket connections, and large file processing, which require reliable persistent compute</p></li><li><p>The team does not have a designated platform engineer with Kubernetes or Docker Swarm expertise.</p></li><li><p>Production downtime directly impacts customer experience, SLAs, or revenue</p></li></ul><p>At any of these signals, the TCO analysis for a self-hosted alternative consistently comes out worse than a managed cloud-native IDP when all costs are included. The following section works through why.</p><h2><strong>The True Build-Versus-Buy Cost of a Self-Hosted Heroku Alternative</strong></h2><p>This is the analysis that most engineering teams do not complete before choosing the open-source route, and the one that produces the most surprises when they do it retrospectively after six months of operation.</p><p>The surface-level cost comparison is straightforward: open-source Heroku alternatives are free to use, so the cost is just the infrastructure. A $40/month DigitalOcean droplet or a small EC2 instance is dramatically cheaper than Heroku&#8217;s production dyno tiers. The analysis looks obvious.</p><p>The cost that does not appear in that comparison is engineering time, for initial setup, for ongoing maintenance, for incident response, and for the opportunity cost of senior engineers spending hours on platform work instead of product development.</p><p><strong>The initial setup cost:</strong></p><p>Setting up a production-grade self-hosted Heroku alternative takes longer than tutorials suggest. The tutorial path, Dokku on a droplet, one application deployed, is genuinely fast. The production path, multi-server setup, managed database configuration, observability stack, SSL and networking configuration, backup verification, monitoring and alerting, runbook documentation, takes a senior engineer two to four weeks of focused effort.</p><p>For a company with fifteen engineers at an average fully-loaded cost of $200,000/year, a senior engineer costs approximately $100/hour. Two weeks of setup at 40 hours per week is $8,000. Four weeks is $16,000. This is the upfront engineering investment before the platform serves a single production request.</p><p>Most teams do not account for this cost because it feels like infrastructure work rather than a direct expenditure. It appears in sprint velocity metrics as product features not shipped. It does not appear in the infrastructure budget.</p><p><strong>The ongoing maintenance cost:</strong></p><p>After initial setup, a self-hosted Heroku alternative requires continuous maintenance. Security patches for the host OS, Docker runtime, and platform software need to be applied on a regular cadence. The observability stack needs to be maintained. SSL certificates need to be monitored. Backup integrity needs to be verified periodically. Capacity needs to be reviewed as the application grows.</p><p>Conservative estimate for a production self-hosted setup: two to four hours of platform maintenance per week. At $100/hour for a senior engineer, that is $800&#8211;$1,600/month in ongoing maintenance cost, consistently, before any incidents occur.</p><p>Over twelve months, the maintenance cost alone is $9,600&#8211;$19,200. This is in addition to the infrastructure cost, and it compounds with the service count as the platform&#8217;s surface area grows.</p><p><strong>The on-call burden:</strong></p><p>Self-hosted platforms fail in ways that managed platforms handle transparently. A pod crash on EKS restarts automatically. A disk filling on a self-hosted Coolify instance takes the application down until someone investigates and resolves it. A networking configuration change that breaks SSL certificate renewal on a Dokku server causes downtime until someone diagnoses and fixes it.</p><p>Production incidents on self-hosted infrastructure happen at off-hours with the same frequency as on managed platforms. The difference is who responds. On Heroku or a managed IDP, Heroku&#8217;s reliability team or the IDP provider&#8217;s on-call rotation handles infrastructure incidents. On a self-hosted alternative, someone from the engineering team handles them.</p><p>At a company with one person effectively on-call for the platform, this represents a meaningful quality-of-life cost that compounds into retention risk over time. Senior engineers who regularly wake up at 2 AM for platform incidents that managed infrastructure would have handled automatically do not stay in that role indefinitely.</p><p><strong>The opportunity cost: what the platform engineer is not building.</strong></p><p>This is the largest and least visible cost component. Every hour a senior engineer spends on platform maintenance, incident response, and infrastructure configuration is an hour not spent on the product features, performance improvements, and technical debt reduction that drive business value.</p><p>For a team at Series A with a product roadmap full of competitive priorities, redirecting a senior engineer&#8217;s capacity toward platform maintenance is a strategic cost that appears nowhere in the infrastructure budget and shows up instead in delayed product releases and compressed competitive advantage.</p><p><strong>The full cost comparison:</strong></p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/UvuiL/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a4072a1b-362f-45b8-8d20-605fe516ceb7_1220x932.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/549e808d-57a1-4960-95f5-8ac709a3b496_1220x932.png&quot;,&quot;height&quot;:463,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/UvuiL/1/" width="730" height="463" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><h2><strong>The Long-Term Architectural Risks of Each Path</strong></h2><p>This is the analysis that matters most for engineering leaders making a three-year infrastructure bet. The day-one costs are relatively predictable. The long-term architectural implications of the hosting choice shape the company&#8217;s technical trajectory in ways that are harder to reverse than they appear at the decision point.</p><p><strong>Risk Profile 1: Managed PaaS Heroku Alternatives (Render, Railway, Fly.io)</strong></p><p>Managed PaaS alternatives to Heroku provide a genuine improvement on Heroku&#8217;s developer experience in some areas and similar constraints in others. They are worth examining honestly as a category before discussing the IDP path.</p><p><em><strong>What improves over Heroku:</strong></em> Better pricing models in most cases, better geographic distribution options, more modern infrastructure primitives, and more active product development. Render and Railway, in particular, have improved the developer experience meaningfully relative to Heroku.</p><p><em><strong>What does not improve:</strong></em> The fundamental architecture remains the same. The application runs on the provider&#8217;s infrastructure, not in the team&#8217;s cloud account. The compliance posture is governed by the provider&#8217;s security posture, not the team&#8217;s. Infrastructure control is limited by what the provider exposes. The vendor dependency is as deep as Heroku&#8217;s, in some cases, deeper, because modern PaaS platforms have fewer migration paths than Heroku did.</p><p><em><strong>The long-term architectural risk:</strong></em> Three years into using a managed PaaS alternative, the team has made application architecture decisions shaped by the platform&#8217;s constraints, built deployment workflows around the platform&#8217;s model, and accumulated operational familiarity with a platform that may change pricing, deprecate features, or change ownership. The compliance and infrastructure control limitations that eventually drove the team off Heroku are structurally present in every managed PaaS alternative. The team is on a path that leads back to the same decision in a different form.</p><p><strong>Risk Profile 2: Self-Hosted Open-Source Alternatives (Coolify, Dokku, Caprover)</strong></p><p>Self-hosted alternatives transfer the operational risk from the vendor to the engineering team. This is a genuine benefit for teams with the expertise and capacity to absorb it. For most scaling SaaS teams, it is a risk transfer that creates more exposure than it eliminates.</p><p><em><strong>The platform drift risk:</strong></em> Open-source platforms are maintained by communities with priorities that may not align with the production requirements of a scaling SaaS company. Coolify&#8217;s roadmap is driven by its maintainers&#8217; priorities, not by what the teams running it in production need. A critical security vulnerability in an open-source platform&#8217;s dependency may be patched in weeks or months, not hours, as a commercial managed platform provider would address it. Teams running production workloads on open-source platforms accept that the platform&#8217;s maintenance cadence is outside their control.</p><p><em><strong>The expertise dependency risk:</strong></em> Self-hosted platforms run reliably when someone on the team understands them deeply. That expertise lives in a person, not in the platform. When the person who set up and maintains the Dokku or Coolify installation leaves the company, the institutional knowledge leaves with them. The team inherits a production system they did not build, with configuration choices they do not fully understand, running on infrastructure they now own completely. This is a common and underappreciated operational risk for engineering-led companies.</p><p><em><strong>The scale ceiling risk:</strong></em> Open-source Heroku alternatives have natural scale ceilings that are lower than the scale ceilings of Kubernetes-native platforms. Dokku hits its ceiling at single-server scale. Coolify and CapRover on Docker Swarm hit their ceiling below what a mid-sized production workload on EKS handles routinely. Teams that choose a self-hosted alternative may find themselves re-platforming again within two to three years as the workload outgrows the platform&#8217;s scaling model. Re-platforming has a cost that compounds with each cycle, and it diverts engineering capacity from product development at exactly the growth stage where product velocity matters most.</p><p><strong>Risk Profile 3: Cloud-Native IDP on Your Own AWS Account (LocalOps)</strong></p><p>The long-term architectural risk profile of a cloud-native IDP differs from both managed PaaS and self-hosted alternatives in one structural dimension: the infrastructure lives in the team&#8217;s AWS account.</p><p><em><strong>What this means for long-term risk:</strong></em> The vendor dependency is on the IDP&#8217;s operational interface, the deployment experience, the observability dashboards, and  the environment management UI, not on the infrastructure itself. If the IDP provider changes pricing, changes the product, or ceases operation, the EKS cluster, RDS databases, ElastiCache instances, and S3 buckets continue running in the team&#8217;s AWS account. The migration path is to adopt a different operational interface on top of the same infrastructure, not to re-platform the infrastructure from scratch.</p><p><em><strong>The compliance posture compounds positively:</strong></em> An application running on AWS-native infrastructure inside the team&#8217;s own VPC, with IAM-based access control and AWS-native audit logging, starts from a compliance posture that can support enterprise customers from day one. As the company grows and enterprise procurement becomes more rigorous, the infrastructure posture improves by configuration, enabling additional AWS compliance features, adding audit log retention, enabling GuardDuty, rather than by platform migration.</p><p><em><strong>The scale ceiling is the AWS scale ceiling:</strong></em> EKS scales to the capacity of the AWS region. There is no platform-imposed scale ceiling below the hyperscaler ceiling. Teams that grow from five services to fifty services, from one AWS region to three, and from $1M ARR to $100M ARR do not re-platform their infrastructure along the way; they scale the same Kubernetes and AWS-native services that were there from the beginning.</p><p><em><strong>The architectural risk to manage:</strong></em><strong> </strong>The risk of a cloud-native IDP path is primarily in the initial adoption decision: choosing a provider whose infrastructure model, pricing, and roadmap alignment fit the team&#8217;s three-year trajectory. This risk is manageable through due diligence at the selection point, examining the IDP&#8217;s architecture (does infrastructure live in your account?), pricing model (does cost scale reasonably with your workload growth?), and migration path (what happens if you need to change providers?).</p><h2><strong>How LocalOps Addresses the Build-Versus-Buy Decision</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform that resolves the build-versus-buy tension for scaling SaaS teams, replacing Heroku.</p><p>The build case for a self-hosted alternative rests on cost and control. LocalOps preserves both while eliminating the engineering overhead of operating the platform. Infrastructure runs in the team&#8217;s AWS account, with full VPC control, full IAM visibility, and full compliance posture. The platform fee replaces the engineering hours that self-hosted alternatives require.</p><p>The buy case for a managed PaaS rests on simplicity and developer experience. LocalOps matches the simplicity of managed PaaS, push to branch, service deploys, logs and metrics are immediately available, without the compliance constraints and infrastructure opacity that come with a provider-owned cloud environment.</p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and a complete observability stack automatically. No Terraform. No Helm charts. First environment ready in under 30 minutes. No platform maintenance, no on-call burden for infrastructure incidents, no observability setup project.</p><p>The infrastructure stays in the team&#8217;s AWS account permanently. The engineering hours that a self-hosted alternative would consume go back to the product roadmap.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221;</em> &#8212; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, all of which LocalOps has saved for us.&#8221;</em> &#8212; Gaurav Verma, CTO and Co-founder, SuprSend</p></blockquote><div><hr></div><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>When is Dokku or Coolify the right answer for a production workload?</strong></p></li></ol><p>Dokku and Coolify are the right answer when the workload is genuinely simple, the team has a dedicated platform engineer with operational enthusiasm, and downtime does not directly impact customer experience or revenue. Internal tools, admin dashboards, low-traffic APIs, and development environments are well-served by open-source alternatives. The wrong answer is applying these tools to customer-facing production services at Series A scale without accounting for the operational cost of running and maintaining the platform under real production conditions.</p><ol start="2"><li><p><strong>What is the most common failure mode when teams self-host a Heroku alternative in production?</strong></p></li></ol><p>The most consistent failure mode is not a technical failure; it is an expertise departure. The engineer who set up and understood the self-hosted platform leaves the company. The team inherits a production system with undocumented configuration choices, dependency versions that have drifted from the original setup, and no institutional knowledge of why specific decisions were made. Recovering from this situation typically requires a platform audit, a re-provisioning project, and several weeks of senior engineering time, at a moment when that time is usually least available. Managed platforms eliminate this risk category because the platform knowledge lives in the provider&#8217;s team, not in a single employee.</p><ol start="3"><li><p><strong>How does the compliance posture of self-hosted alternatives compare to LocalOps on AWS?</strong></p></li></ol><p>Self-hosted Heroku alternatives running on a VPS or small EC2 instance have a weaker compliance posture than applications running in a properly configured AWS VPC on LocalOps. VPC isolation, IAM-based access control, audit logging, and data residency are native features of the AWS environment that LocalOps provisions automatically. On a self-hosted alternative, these capabilities require explicit engineering work to implement, document, and maintain. For B2B SaaS teams pursuing enterprise customers, the compliance gap between a self-hosted alternative and an AWS-native IDP is the compliance gap between infrastructure that fails a security questionnaire and infrastructure that passes one.</p><ol start="4"><li><p><strong>What does the migration path look like if a team wants to move from Coolify or Dokku to LocalOps?</strong></p></li></ol><p>The migration involves three steps: containerising any applications that are not already containerised (most Dokku-deployed applications are Heroku-buildpack-based and require Dockerfiles), migrating managed services (Postgres to RDS, Redis to ElastiCache), and connecting the GitHub repository to LocalOps for automated deployments. LocalOps provides the environment infrastructure automatically, VPC, EKS cluster, load balancers, IAM roles, observability stack, so teams are not building the AWS environment from scratch. The migration from a self-hosted alternative to LocalOps is typically faster than the original setup of the self-hosted alternative, because LocalOps automates the infrastructure provisioning that the self-hosted setup required manual work to achieve.</p><ol start="5"><li><p><strong>Is the open-source alternative path ever cheaper than a managed IDP over a three-year horizon?</strong></p></li></ol><p>For teams with a dedicated platform engineer whose primary role is infrastructure operations and whose time is not competing with product development, the total cost of ownership for a well-run self-hosted alternative can match or slightly undercut a managed IDP over three years. This is the scenario where the build path makes financial sense: the engineering cost is already allocated to infrastructure work, and the open-source alternative gives that engineer maximum control. For teams where the platform engineer is also a product engineer, where platform maintenance competes directly with feature development, the open-source path is more expensive over a three-year horizon in every realistic model. The engineering opportunity cost of platform maintenance consistently exceeds the managed IDP&#8217;s platform fee.</p><ol start="6"><li><p><strong>What architectural signals indicate that a team has outgrown its self-hosted Heroku alternative?</strong></p></li></ol><p>The clearest signals are: traffic spikes that cause degraded performance because autoscaling is not available or not automatic, incident response time that is measured in hours rather than minutes because platform observability is insufficient, security questionnaire line items that cannot be answered honestly because the infrastructure lacks VPC isolation and IAM controls, and deployment pipelines that require manual steps because the CI/CD integration on the self-hosted platform does not support the team&#8217;s Git workflow. Any one of these signals is worth evaluating against the TCO comparison above. Multiple signals simultaneously indicate that the re-platforming project will be more costly the longer it is deferred.</p><h2><strong>Key Takeaways</strong></h2><p>Open-source Heroku alternatives are real products with genuine use cases. They are not the right answer for every team, and the evaluation should be made with the full cost picture visible, not just the infrastructure bill.</p><p>The TCO analysis for a self-hosted Heroku alternative has four components: infrastructure (cheap), initial setup engineering (significant upfront), ongoing maintenance engineering (continuous and compounding), and on-call burden (invisible in budgets, visible in retention). When all four are included, the self-hosted path is cheaper than a managed IDP only when a dedicated platform engineer&#8217;s time is already fully allocated to infrastructure work and not competing with product development.</p><p>The long-term architectural risk of the self-hosted path is the scale ceiling, the expertise dependency, and the platform drift, three risk categories that compound silently over two to three years and surface as a re-platforming project at the moment of least available engineering capacity.</p><p>The long-term architectural risk of the managed PaaS path is the infrastructure opacity, the compliance ceiling, and the vendor dependency on a provider whose infrastructure the team does not own, risks that surface specifically when enterprise customers arrive, and the security questionnaire requires answers the platform cannot support.</p><p>The cloud-native IDP path on the team&#8217;s own AWS account resolves both risk profiles: the platform is managed (no maintenance burden), but the infrastructure is owned (compliance posture, vendor independence, no scale ceiling). The engineering hours that a self-hosted alternative would consume return to the product roadmap. The compliance posture that a managed PaaS cannot provide is native to the AWS environment from day one.</p><p><strong><a href="https://cal.com/anand-localops/migrate-from-heroku-to-aws?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026&amp;_gl=1*1rbbcig*_gcl_au*MTIxMDY4ODQyMy4xNzczODMxMDQz*_ga*MTQzNTE0NTI4LjE3NzM4MzEwNDI.*_ga_YJTCX7ZE2G*czE3NzcwMzc4NjUkbzI1JGcxJHQxNzc3MDM4OTQwJGo0NCRsMCRoMA..&amp;duration=30">Get Started with LocalOps</a> &#8594;</strong> First production environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026&amp;_gl=1*1rbbcig*_gcl_au*MTIxMDY4ODQyMy4xNzczODMxMDQz*_ga*MTQzNTE0NTI4LjE3NzM4MzEwNDI.*_ga_YJTCX7ZE2G*czE3NzcwMzc4NjUkbzI1JGcxJHQxNzc3MDM4OTQwJGo0NCRsMCRoMA..">Schedule a Migration Call </a>&#8594;</strong> Our engineers walk through your specific stack, whether you&#8217;re currently on Coolify, Dokku, or Heroku, and map the migration path to AWS.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026&amp;_gl=1*nzmp8o*_gcl_au*MTIxMDY4ODQyMy4xNzczODMxMDQz*_ga*MTQzNTE0NTI4LjE3NzM4MzEwNDI.*_ga_YJTCX7ZE2G*czE3NzcwMzc4NjUkbzI1JGcxJHQxNzc3MDM4OTQwJGo0NCRsMCRoMA..">Read the Heroku Migration Guide</a> &#8594;</strong> Full technical walkthrough: database migration, environment setup, CI/CD pipeline configuration, DNS cutover.</p>]]></content:encoded></item><item><title><![CDATA[How Internal Developer Platforms Give Engineering Teams Full Observability Without Manually Configuring Grafana]]></title><description><![CDATA[Why per-environment observability breaks down with manual setup, and how an Internal developer platform fixes it.]]></description><link>https://blog.localops.co/p/internal-developer-platform-observability-grafana-prometheus</link><guid isPermaLink="false">https://blog.localops.co/p/internal-developer-platform-observability-grafana-prometheus</guid><dc:creator><![CDATA[Madhushree Sivakumar]]></dc:creator><pubDate>Fri, 24 Apr 2026 04:30:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tftk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.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_!tftk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tftk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png 424w, https://substackcdn.com/image/fetch/$s_!tftk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png 848w, https://substackcdn.com/image/fetch/$s_!tftk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png 1272w, https://substackcdn.com/image/fetch/$s_!tftk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tftk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png" width="1456" height="1761" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1761,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6476748,&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://blog.localops.co/i/195201968?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.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_!tftk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png 424w, https://substackcdn.com/image/fetch/$s_!tftk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png 848w, https://substackcdn.com/image/fetch/$s_!tftk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.png 1272w, https://substackcdn.com/image/fetch/$s_!tftk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F599c555f-2bd4-4ae7-9c57-76cc4ba99a25_1984x2400.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 style="text-align: justify;"></p><p style="text-align: justify;">You have three environments: dev, staging, production. Each one has a Grafana instance someone set up months ago. Staging has different dashboard versions than production because whoever set it up used a different Helm chart version. The dev Prometheus stopped scraping correctly after a node replacement, but nobody noticed until a bug in dev could not be reproduced in staging. The production Grafana still has the default admin password because rotating it means logging into a cluster nobody touches unless something breaks.</p><p style="text-align: justify;">This is not unusual. It is the default state for teams that treat observability as something you configure after provisioning an environment, rather than part of provisioning itself.</p><h3>TL;DR</h3><ul><li><p style="text-align: justify;">The Prometheus + Loki + Grafana stack covers infrastructure metrics and application logs automatically. Custom application metrics still require code-level instrumentation.</p></li><li><p style="text-align: justify;">Multi-environment observability breaks down not at setup, but over time &#8212; through version drift, storage misconfiguration, and scrape failures that produce silence instead of errors.</p></li><li><p style="text-align: justify;">An internal developer platform that provisions observability at environment creation removes per-environment setup work and the drift that follows.</p></li><li><p style="text-align: justify;">Infrastructure metrics (CPU, memory, pod restarts) are not the same as application metrics. A pod with a normal CPU can be returning 500s on 30% of requests. Infrastructure metrics will not surface that.</p></li><li><p style="text-align: justify;">For BYOC distribution and single-tenant enterprise deployments, centralized observability creates data residency problems. Per-environment, in-cluster observability fits better.</p></li><li><p style="text-align: justify;">The ops.json instrumentation pattern reduces the friction of surfacing custom application metrics in Grafana without writing ServiceMonitor CRDs.</p></li></ul><h3>What Does &#8220;Built-In Observability&#8221; Actually Mean in an IDP</h3><p style="text-align: justify;">The phrase gets used loosely. It can mean anything from a link to your existing Datadog account to a fully provisioned monitoring stack running inside the same Kubernetes cluster as your application. Those are not equivalent.</p><p style="text-align: justify;">The standard open-source stack has three components.</p><p style="text-align: justify;"><strong>Prometheus</strong> is a time-series metrics scraper. It pulls data from instrumented endpoints and from Kubernetes system components at a configured interval. Two categories of data worth separating: infrastructure metrics (CPU utilization, memory pressure, pod restart counts, deployment replicas) collected automatically via kube-state-metrics and node-exporter, and application metrics (request rate, error rate, queue depth, cache hit ratio) which require explicit instrumentation in the application code. Most observability content blurs this line. The distinction matters when something goes wrong.</p><p style="text-align: justify;"><strong>Loki</strong> is a log aggregator. It runs a DaemonSet-based agent called Promtail on each Kubernetes node, collecting container stdout and stderr. Unlike Elasticsearch,<a href="https://grafana.com/oss/loki/"> Loki indexes only labels &#8212; not log content</a>. Log lines are grouped into streams and tagged with labels like pod name, namespace, and container. That keeps storage costs lower and makes logs available for querying within milliseconds.</p><p style="text-align: justify;"><strong>Grafana</strong> connects to both Prometheus and Loki as data sources and is where the actual debugging happens. You see a CPU spike in Prometheus, jump to the same time window in Loki, read the log lines from the pod that caused it. Without that correlation, you are looking at two separate interfaces with no direct link.</p><p style="text-align: justify;">One thing this stack does not cover: distributed tracing. Following a request through five microservices requires Tempo or Jaeger plus OpenTelemetry instrumentation &#8212; a separate layer entirely. Teams that set up Prometheus and Loki and consider themselves done will eventually hit a slow request they cannot explain, because they have no way to trace it through the service graph.</p><h3>Why Multi-Environment Observability Breaks Down Without a Platform</h3><p style="text-align: justify;">The initial setup takes a day or two. The maintenance does not stop there.</p><h4 style="text-align: justify;">Environment drift </h4><p style="text-align: justify;">Prometheus 0.62 on production, 0.58 on staging, because someone updated one and not the other. Different scrape configurations. Different alert rule formats. Dashboards exported from production as JSON fail on import to staging because label names shifted between versions. You find this out during an incident when you need staging to tell you something and it cannot.</p><p style="text-align: justify;">The less visible failure mode is this: a developer ships a new feature and moves on. No metrics added, no log events instrumented, no alerts defined. The feature runs in production with no visibility into how it actually behaves under load. The gap does not surface until something breaks, at which point the investigation starts from scratch with no baseline to work from.</p><h4 style="text-align: justify;">The node replacement problem</h4><p style="text-align: justify;">Prometheus stores time-series data on the local disk of whichever node it lands on. In an EKS managed node group, nodes get replaced during version updates or when the ASG replaces an unhealthy instance. If there is no PersistentVolumeClaim backed by an EBS volume that survives pod restarts, the metrics history is gone.<a href="https://dasroot.net/posts/2026/04/observability-stack-prometheus-grafana-loki/"> Production setups require specifying a StorageClass like gp3 with a persistent volume claim</a> to keep data across restarts. Most Helm-based tutorials skip this step. Teams learn it the first time a cluster update wipes two weeks of metrics.</p><h4 style="text-align: justify;">The scrape configuration failure mode </h4><p style="text-align: justify;">When Prometheus fails to scrape a target, it does not throw an error. It just has no data. An engineer adds a ServiceMonitor, deploys a service, sees nothing in Grafana, and spends 45 minutes checking RBAC permissions, port declarations, pod annotations, and label selector mismatches &#8212; all of which produce the same symptom. Silence. It is one of the more tedious debugging loops in Kubernetes.</p><h4 style="text-align: justify;">Per-environment provisioning cost</h4><p style="text-align: justify;">Every new environment is another Prometheus, Loki, and Grafana to install, configure, and connect. Dev, staging, production, a canary, and a few customer-dedicated deployments adds up to a non-trivial maintenance surface.</p><p style="text-align: justify;"><a href="https://docs.localops.co/environment/inside?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">LocalOps handles this by provisioning </a>Prometheus, Loki, and Grafana as Kubernetes companion deployments inside every environment, running in the same cluster as the application. It does not eliminate the underlying tools or their operational characteristics, but it removes the per-environment setup and the drift that accumulates when configuration is manual.</p><h3>How IDP Handle Grafana and Prometheus Monitoring Out of the Box</h3><p style="text-align: justify;">&#8220;Out of the box&#8221; can mean a lot of things. The architecture is worth being specific about.</p><p style="text-align: justify;">In a provisioned environment using EKS on AWS, an internal developer platform gives you Prometheus, Loki, and Grafana running as Kubernetes workloads inside the same VPC and EKS cluster as your application services. Prometheus scrapes internal endpoints. Loki receives logs from Promtail on each node. Grafana comes up with both already registered as data sources.</p><p style="text-align: justify;">The co-location has practical consequences beyond tidiness. Prometheus scrape calls stay internal to the cluster. Loki log ingestion happens over the cluster network. For BYOC and single-tenant deployments, this matters: log and metric data does not need to cross the VPC boundary. That is often a hard requirement in enterprise procurement, not a preference.</p><p style="text-align: justify;"><a href="https://docs.localops.co/environment/monitoring/logs?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">LocalOps follows this model</a> &#8212; Prometheus, Loki, and Grafana are provisioned as companion Kubernetes deployments inside every environment, with data sources pre-registered, running in the same cluster as the application.</p><p style="text-align: justify;">&#8220;Pre-configured&#8221; means Grafana has Prometheus and Loki registered as data sources before anyone logs in. No separate step where someone types the Prometheus service name into the UI, tests the connection, and troubleshoots an unhelpful error because the URL had a typo. That step is where a significant portion of manual setups fail.</p><p style="text-align: justify;">Worth being clear about one thing: infrastructure metrics and logs are available immediately. Custom application metrics still require instrumentation at the code level. The platform handles the plumbing; it does not write your /metrics endpoint for you.</p><h3>Infrastructure Metrics vs. Application Metrics</h3><p style="text-align: justify;">A Grafana dashboard showing CPU, memory, and pod restart counts does not mean your application is working correctly. A pod running at 40% CPU with zero restarts can still return database timeout errors on every third request. Infrastructure metrics will not show that. Prometheus will not show it unless someone instrumented the application.</p><p style="text-align: justify;"><strong>Infrastructure metrics</strong> are collected automatically once Prometheus is running: node CPU, memory, pod phase, deployment replicas, persistent volume capacity. They tell you whether the cluster is healthy. They do not tell you whether the application is doing what users expect.</p><p style="text-align: justify;"><strong>Application metrics</strong> require the application to expose a /metrics endpoint using a Prometheus client library. Go, Java, Python, and Rust have official libraries. Node.js, Ruby, and others have community-supported ones. The application defines counters, gauges, and histograms and exposes them at the endpoint. Prometheus scrapes it on a configured interval.</p><p style="text-align: justify;">The metrics that reflect actual user experience sit in this second category. Request rate per endpoint. p95 and p99 latency. Background job processing time. External API failure rate. Queue depth. These are the signals that tell you whether the system is working from a user&#8217;s perspective &#8212; not just from the cluster&#8217;s.</p><p style="text-align: justify;">Getting application metrics into Grafana manually involves: instrumenting the application with a client library, exposing /metrics, creating a ServiceMonitor CRD, matching label selectors to the correct Prometheus instance, verifying RBAC for cross-namespace access, and confirming scrape status in the Prometheus targets UI. When any of these steps is wrong, the metrics do not appear. There is no error that tells you which step failed.</p><p>Here&#8217;s how <a href="https://docs.localops.co/environment/services/instrument-service?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">LocalOps handles this with a declaration in ops.json</a>:</p><p>json</p><p>{</p><p>  &#8220;metrics&#8221;: {</p><p>    &#8220;endpoint&#8221;: &#8220;/metrics&#8221;,</p><p>    &#8220;interval&#8221;: 15</p><p>  }</p><p>}</p><p style="text-align: justify;">The platform registers the endpoint with Prometheus. The custom metrics appear in Grafana. The ServiceMonitor, RBAC binding, and Prometheus configuration are handled without a separate debugging loop.</p><p style="text-align: justify;">If you want to walk through this on your own codebase,<a href="https://go.localops.co/tour"> our engineers can show you how it works</a> in a live environment.</p><h3>How Do You Give Developers Log and Metric Access Without Exposing Cloud Infrastructure?</h3><p style="text-align: justify;">The obvious answers create problems. Giving developers kubectl access to production is a large blast radius. Giving broad IAM read access to the AWS account raises audit and compliance concerns. Neither is a clean answer.</p><p style="text-align: justify;">Grafana works as the access layer because it separates observability from infrastructure control. Developers query logs in LogQL and metrics in PromQL through the Grafana UI. They get visibility into system behavior without needing direct cluster or cloud console access.</p><p style="text-align: justify;">Through Grafana, a developer can see application logs from their services, infrastructure metrics for the cluster, deployment timestamps, and resource utilization. With proper access controls configured, they cannot touch the Kubernetes control plane, access cloud account credentials, or see data from unrelated services or environments.</p><p style="text-align: justify;">The separation matters for a specific reason: observability tells you what happened. It does not give you the ability to change anything. Developers can investigate. Operational control stays restricted.</p><p style="text-align: justify;">This carries over to customer-dedicated environments. A vendor&#8217;s engineering team can access Grafana for a specific customer environment, review logs and metrics, and debug a support issue &#8212; without needing IAM access to the customer&#8217;s AWS account. The observability layer has the data. The underlying infrastructure stays isolated.</p><h3>Per-Customer Observability: Why Centralized Monitoring Breaks Down for BYOC Deployments</h3><p style="text-align: justify;">When a B2B SaaS company starts supporting enterprise customers who need their own cloud infrastructure &#8212; for data residency, compliance, or isolation &#8212; the observability model gets complicated fast.</p><p style="text-align: justify;">The common reaction is Prometheus federation: a central Prometheus instance in the vendor&#8217;s account scrapes from per-customer Prometheus instances.<a href="https://developers.mattermost.com/blog/cloud-monitoring/"> Mattermost documented this pattern</a> across multiple Kubernetes clusters and multiple AWS VPCs. The implementation involved a central monitoring cluster, cross-VPC networking, private load balancers, Route 53 private hosted zones, and a Lambda function to handle dynamic cluster registration. It works. It is also a substantial ongoing infrastructure commitment.</p><p style="text-align: justify;">And it still does not fully solve the log problem. In regulated industries like financial services or healthcare, application logs frequently cannot leave the customer&#8217;s cloud account. Metrics are sometimes acceptable to aggregate centrally. Logs often are not.</p><p style="text-align: justify;">A per-environment, in-cluster model fits this constraint better. Each customer environment runs its own Prometheus, Loki, and Grafana within its VPC. Logs and metrics stay within the account boundary. Vendor engineers access that environment&#8217;s Grafana when debugging.</p><p style="text-align: justify;">The tradeoff is real: there is no centralized view across all customer environments. Aggregating insight across customers requires additional work. For teams where data residency is a hard requirement, that tradeoff is usually unavoidable.</p><p style="text-align: justify;"><a href="https://docs.localops.co/use-cases/byoc?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">LocalOps provisions the observability stack inside every environment it creates</a>, including BYOC deployments. Each environment runs its own Prometheus, Loki, and Grafana within the customer&#8217;s VPC. The provisioning is consistent across environments because it comes from the same template &#8212; which reduces setup variation without centralizing data.</p><h3>What Internal Developer Platform Architecture Should Include for Observability</h3><p style="text-align: justify;">In platform engineering, an internal developer platform is only as useful as the capabilities it provisions consistently. Observability is one of the first gaps that shows up when that consistency is missing. Not all IDPs handle it the same way, and the differences show up in how much manual work is required and how the system holds up across many environments.</p><p style="text-align: justify;">A per-environment Prometheus instance prevents metric label conflicts between environments and supports the isolation that BYOC deployments require. Loki running inside the same cluster keeps log ingestion internal to the cluster network and makes logs available quickly without routing data outside the VPC.</p><p style="text-align: justify;">Grafana should come pre-configured with Prometheus and Loki as data sources &#8212; not because this is difficult to do manually, but because it is reliably skipped or done incorrectly in manual setups. Persistent storage for Prometheus needs a PersistentVolumeClaim backed by something durable like EBS, with appropriate retention and capacity planning. Without it, node replacement erases your metrics history.</p><p style="text-align: justify;">There should be a way to declare application metrics endpoints without writing ServiceMonitor resources. This lowers the bar for teams that want custom instrumentation but do not want to debug Kubernetes resource configurations to get there. Access to observability should flow through Grafana with role-based controls, not through direct cluster access.</p><p style="text-align: justify;">Consistency across environments is worth treating as a requirement, not a nice-to-have. Dashboards and queries built on staging should work on production without modification. That only holds if labeling, naming, and configuration are consistent across environments from the start.</p><p style="text-align: justify;">One constraint worth stating plainly: in BYOC and single-tenant architectures, the observability system should not route customer logs or metrics through the vendor&#8217;s cloud account unless the customer has explicitly agreed to that. In regulated industries, it is a procurement blocker.</p><p style="text-align: justify;"><a href="https://docs.localops.co/use-cases/dedicated-infrastructure">LocalOps provisions the observability stack inside the target cloud account for each environment</a>. Each environment runs its own Prometheus, Loki, and Grafana within the customer&#8217;s VPC.</p><h3>DIY Observability vs. a Cloud-Native IDP That Provisions It for You</h3><p style="text-align: justify;">One question that comes up often when teams think about how to build an internal developer platform is where observability fits, whether it gets provisioned upfront or bolted on later. Building the Prometheus + Loki + Grafana stack yourself is not technically hard. Helm charts exist, documentation is reasonable, and most engineers can get a working setup in a day.</p><p style="text-align: justify;">The problem is not the first installation. It is the second, third, and eighth.</p><p style="text-align: justify;">Every new environment &#8212; staging, canary, customer-dedicated deployment &#8212; repeats the same process. Different engineers make slightly different choices. Chart versions differ. Storage configurations vary. Six months later, Prometheus versions differ across environments, scrape intervals are inconsistent, and dashboards built on staging do not work on production because label names drifted.</p><p style="text-align: justify;">DIY also means owning the operational surface. Prometheus runs out of memory on a high-cardinality workload: your alert, your fix. Loki fills its disk because someone added verbose logging to a worker: your PVC resize, your pod restart, your lost logs. These are ongoing responsibilities, not one-time setup tasks.</p><p style="text-align: justify;">A cloud-native IDP that provisions observability as part of environment creation reduces that maintenance overhead. The stack comes from a consistent template. Configuration drift is reduced because the manual step that causes drift is removed &#8212; not because the tools behave differently.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/GCV7F/2/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/407cab11-2571-4cbb-adf9-0807c949d9af_1220x1548.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76cf33f3-1009-40b3-9085-5a43c8cdb028_1220x1548.png&quot;,&quot;height&quot;:783,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/GCV7F/2/" width="730" height="783" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p style="text-align: justify;">The tradeoff is real. You give up some configuration flexibility in exchange for not owning the full operational burden. For teams whose job is building product rather than maintaining monitoring infrastructure, that is often a reasonable trade &#8212; though it is worth understanding what you are giving up before making it.</p><h3>FAQs</h3><p style="text-align: justify;"><strong>1. What observability tools should be built into an internal developer platform?</strong></p><p style="text-align: justify;">At minimum: Prometheus for metrics, Loki for log aggregation, and Grafana as the visualization and correlation layer. These three cover infrastructure metrics automatically and application metrics when services expose a /metrics endpoint. The best internal developer platforms include all three as part of environment creation, not as a post-setup task. Distributed tracing requires a separate tool like Tempo or Jaeger plus OpenTelemetry, and is worth planning for before you need it.</p><p style="text-align: justify;"><strong>2. How do internal developer platforms provide Grafana and Prometheus monitoring out of the box?</strong></p><p style="text-align: justify;">By provisioning Prometheus, Loki, and Grafana as Kubernetes workloads during environment creation, running inside the same cluster as the application, with Grafana already configured to connect to both. No manual data source setup, no scrape configuration to write. The stack is functional before any application code is deployed.</p><p style="text-align: justify;"><strong>3. How do you get logs from multiple Kubernetes environments without configuring Grafana manually each time?</strong></p><p style="text-align: justify;">Use an IDP that provisions a per-environment Loki and Grafana stack as part of environment creation. Each environment gets an identical stack with Loki already registered as a Grafana data source. Developers access logs through that environment&#8217;s Grafana. No separate login, no data source configuration, no inconsistencies between environments.</p><p style="text-align: justify;"><strong>4. What is the difference between an internal developer portal and an internal developer platform?</strong></p><p style="text-align: justify;">A portal like Backstage is a UI layer: software catalog, documentation links, embedded dashboards. Teams evaluating a Backstage internal developer platform setup often find that Backstage handles the portal layer well but still requires a separate solution for provisioning, environment management, and observability. A platform handles all of that. A portal surfaces information about your stack. A platform creates and maintains it.</p><p style="text-align: justify;"><strong>5. Does an open source internal developer platform work for production observability?</strong></p><p style="text-align: justify;">Yes. Prometheus, Loki, and Grafana are open source and run on standard Kubernetes. The tools are production-ready. The question is whether your team has capacity to provision, configure, and maintain them consistently across every environment you run. The tooling cost is zero. Ensuring they are provisioned, configured, and maintained consistently across environments is where the effort accumulates.</p><h3>Conclusion</h3><p style="text-align: justify;">Most teams spend a day or two getting Prometheus and Grafana running on a new cluster. That feels like a one-time investment. It is not.</p><p style="text-align: justify;">Every environment added is another Grafana instance to update, another Prometheus scrape configuration to maintain, another persistent volume to size correctly, and another set of dashboards to keep in sync with production. That cost scales with the number of environments, not the size of the team. A four-person team running eight environments carries a monitoring surface that grows with every new deployment.</p><p style="text-align: justify;">According to the 2024 DORA report, elite engineering teams recover from failed deployments significantly faster than low performers. Observability is one contributing factor in that gap. Teams that can quickly see what broke, where, and when spend less time navigating fragmented monitoring setups and more time fixing the issue.</p><p style="text-align: justify;">An internal developer platform does not replace Prometheus, Loki, or Grafana. It reduces the repeated provisioning work and limits the configuration drift that makes these tools harder to operate across multiple environments.</p><p style="text-align: justify;">If you are running a single environment with dedicated infrastructure support, a manual setup can be sufficient. As the number of environments grows across stages, regions, or customer accounts, the provisioning overhead compounds, and the maintenance cost tends to surface during incidents when time matters most.</p><p style="text-align: justify;">If you&#8217;re thinking through how to standardize observability across multiple environments or reduce the maintenance overhead that comes with scaling clusters, then LocalOps team can help you work through it:</p><p style="text-align: justify;"><a href="https://go.localops.co/tour">Book a Demo</a> - Walk through how environments, deployments, and AWS infrastructure are handled in practice for your setup.</p><p style="text-align: justify;"><a href="https://console.localops.co/signup">Get started for free</a> - Connect an AWS account and stand up an environment to see how it fits into your existing workflow.</p><p style="text-align: justify;"><a href="https://docs.localops.co/">Explore the Docs</a> - A detailed breakdown of how LocalOps works end-to-end, including architecture, environment setup, security defaults, and where engineering decisions still sit.</p><h4>Suggested Articles</h4><ol><li><p><a href="https://blog.localops.co/p/what-is-an-internal-developer-platform-idp">What Is an Internal Developer Platform (IDP)?</a></p></li><li><p><a href="https://blog.localops.co/p/internal-developer-platform-build-vs-buy-cost-comparison">How Much Does It Cost to Build an Internal Developer Platform In-House vs Buying One?</a></p></li><li><p><a href="https://blog.localops.co/p/standardize-dev-staging-prod-internal-developer-platform">How to Standardize Dev, Staging, and Production Environments with an Internal Developer Platform</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Rails Hosting After Heroku: The Best Alternatives for Production Ruby Applications]]></title><description><![CDATA[What actually breaks on Heroku for Rails at scale, and how production teams rebuild their stack for reliability, performance, and control.]]></description><link>https://blog.localops.co/p/rails-hosting-after-heroku</link><guid isPermaLink="false">https://blog.localops.co/p/rails-hosting-after-heroku</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Thu, 23 Apr 2026 08:02:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!toy3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.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_!toy3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!toy3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png 424w, https://substackcdn.com/image/fetch/$s_!toy3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png 848w, https://substackcdn.com/image/fetch/$s_!toy3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png 1272w, https://substackcdn.com/image/fetch/$s_!toy3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!toy3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png" width="1984" height="1648" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1648,&quot;width&quot;:1984,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5806768,&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://blog.localops.co/i/195206970?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f228470-745b-4713-96d7-1c54e2ba6bca_1984x2400.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_!toy3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png 424w, https://substackcdn.com/image/fetch/$s_!toy3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png 848w, https://substackcdn.com/image/fetch/$s_!toy3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.png 1272w, https://substackcdn.com/image/fetch/$s_!toy3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b8d65b4-b361-42e1-bec5-165a3e975df4_1984x1648.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><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> Why Heroku&#8217;s architecture creates specific failure modes for Rails applications at production scale, what capabilities a genuine Rails hosting alternative must provide, how modern platforms handle the workloads Heroku manages with fragile add-ons, and what a production-grade CI/CD pipeline looks like for a Rails team moving off Heroku.</p><p><strong>Who it is for:</strong> CTOs and VPs of Engineering running Ruby on Rails applications on Heroku who are evaluating production alternatives, specifically teams with Postgres databases, Sidekiq background workers, and growth-stage traffic that is making Heroku&#8217;s limitations visible.</p><p><strong>The conclusion:</strong> Heroku was the right Rails hosting choice for a long time. It understood the Rails application model, handled Procfile-based process management naturally, and abstracted infrastructure decisions that most Rails teams did not need to make. The reason teams move off it is not that Heroku stopped understanding Rails, it is that Rails applications at production scale need infrastructure capabilities that Heroku&#8217;s architecture cannot provide: persistent stateful workloads that survive dyno cycling, background job queues that do not depend on fragile add-on integrations, Active Storage and Action Cable deployments that work without platform workarounds, and CI/CD workflows that match modern Git-based development practices. This guide covers what those capabilities look like on a modern alternative.</p><blockquote><p>See what your Rails stack looks like on AWS (EKS + RDS + Redis + S3), fully set up in your own account<br>&#8594; <a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get a live environment in under 30 minutes</a></p></blockquote><h2><strong>The Best Heroku Alternative for Rails in Production: What the Stack Needs to Cover</strong></h2><p>For a Rails application running in production with Postgres, Sidekiq, and real traffic, the hosting alternative needs to satisfy a specific set of requirements. The list is not long, but each item is non-negotiable for a production-grade deployment.</p><p><strong>A genuine Rails hosting alternative in 2026 needs to handle the full application model: </strong></p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/AH398/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/48368e40-3fc8-4a18-a81c-8f97d5b52649_1220x954.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aaee38b9-30f4-4c3b-8975-3fde2e98e633_1220x954.png&quot;,&quot;height&quot;:475,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/AH398/1/" width="730" height="475" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>Want to see how this full Rails stack is provisioned (EKS, RDS, Redis, S3) without writing Terraform or Kubernetes YAML?<br>&#8594; <a href="https://localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Explore how LocalOps sets up production-ready infrastructure</a></p><p><strong>The platform that comes closest to this for Rails teams is an AWS-native Internal Developer Platform like LocalOps.</strong> Not because AWS is the only option, but because the combination of EKS for persistent workloads, RDS for Postgres, ElastiCache for Redis, and S3 for Active Storage maps the Rails application model to managed AWS services that are production-proven, priced on actual consumption rather than arbitrary tiers, and controllable by the platform team in ways Heroku does not allow.</p><p><strong>Why EKS specifically for Rails workloads:</strong></p><p>Kubernetes on EKS allows the Rails application model to be expressed correctly. Web processes, Sidekiq workers, scheduled jobs (Whenever or Sidekiq-Scheduler), and cable servers can all run as separate Kubernetes Deployments with independent scaling policies, independent resource allocation, and independent restart behaviour. A Sidekiq worker that needs to process a memory-intensive job can be allocated 2GB RAM without affecting the web dyno&#8217;s resource allocation. A web process under traffic pressure can scale to fifteen replicas without triggering a Redis tier jump. None of this requires application code changes; it requires a hosting model that cleanly expresses the Rails multi-process architecture.</p><p></p><p>See how Rails workloads map to Kubernetes in practice (web, Sidekiq, schedulers, Action Cable)<br>&#8594; <a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Book a walkthrough with an engineer</a></p><h2><strong>Unified Platform for Rails, Node.js, Python, Django, and Go: Why It Matters for Platform Teams</strong></h2><p>Most engineering organisations running Rails are not running only Rails. The Rails application is the core product, but the surrounding architecture includes Node.js services for specific workloads, Python services for data processing or ML inference, Go services for high-performance API layers, and Django applications for internal tooling.</p><p>The failure mode of Heroku at this scale is not that it cannot run these workloads; it can, but that each language runtime requires a separate buildpack, each buildpack has its own behaviour and failure modes, and the operational model across language runtimes is inconsistent enough to create cognitive overhead for the platform team.</p><p>More significantly, Heroku&#8217;s observability story is fragmented across services regardless of language. A Rails service and a Python service running on the same Heroku team both send logs to the same Papertrail drain, and both have their own New Relic agents, but correlating a request that touches both services during an incident requires stitching together data from multiple places with no unified service map.</p><p>Running multiple services beyond Rails?<br>&#8594; <a href="https://localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles multi-service deployments on one platform</a></p><p><strong>What a unified platform looks like across language runtimes:</strong></p><p>A container-native deployment platform is inherently language-agnostic. Docker containers encapsulate the runtime; the platform does not know or care whether the application inside is Rails, Django, Node.js, or Go. The deployment model is identical: push to branch, platform builds the container image, deploys to Kubernetes, serves traffic.</p><p>LocalOps handles multi-language stacks with a consistent deployment model across all services. A Rails web process, a Python background worker, a Node.js API service, and a Go microservice all deploy through the same pipeline, log to the same Loki instance, and surface metrics in the same Grafana dashboard. An incident that crosses service boundaries, a Rails request that calls a Python inference service that produces a slow response, is traceable in a single observability interface.</p><p>For platform teams managing heterogeneous stacks, this consistency is the difference between having a platform model and having a collection of separately managed services with a common billing account.</p><p><strong>CI/CD consistency across language runtimes:</strong></p><p>The CI/CD story on Heroku is language-runtime-specific. Rails applications use the Ruby buildpack. Node.js applications use the Node.js buildpack. When buildpack versions change, when build-time dependencies differ across services, and when environment variable requirements differ between language runtimes, the CI/CD behaviour is inconsistent in ways that are difficult to reason about at the platform level.</p><p>A container-native platform uses Dockerfiles (or auto-generated container builds) that fully specify the build environment per service. The build environment for a Rails application, Ruby version, bundler version, Node.js version for asset compilation, and system library dependencies is explicitly declared and reproducible. The same Dockerfile builds the same image in every environment, eliminating the class of &#8220;works on staging, fails on production because the buildpack version differs&#8221; failures that Heroku&#8217;s buildpack model produces.</p><h2><strong>How Modern Alternatives Handle Rails-Specific Workloads Heroku Manages Badly</strong></h2><h3><strong>Active Storage: From Workaround to Native</strong></h3><p>On a container-native platform using AWS EKS, Active Storage&#8217;s persistent storage requirement is satisfied without application-level workarounds. The Rails application mounts S3 as its Active Storage backend, not as a compromise, but as the correct production architecture. File uploads go directly to S3. Variant generation stores outputs to S3. Temporary files in the container filesystem are genuinely temporary and do not affect application state.</p><p>The operational difference from Heroku is that the ephemeral filesystem constraint no longer shapes application behaviour. Variant generation works predictably. Direct upload flows do not depend on temp file staging that survives in some dyno configurations and fails in others. The application behaves consistently across all replicas because no replica depends on local filesystem state.</p><p>LocalOps environments include S3 bucket provisioning as part of the standard environment setup. Teams configure config/storage.yml to point at the provisioned S3 bucket. Active Storage works in production from day one without add-on configuration, drain setup, or architectural accommodations.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/wCbI4/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0eb48386-191f-4b5f-a18d-4bcfc7bbfff1_1220x636.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fbd34267-0f7c-474c-9769-cc3dc8453209_1220x636.png&quot;,&quot;height&quot;:313,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/wCbI4/1/" width="730" height="313" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><h3><strong>Action Cable: Persistent Connections Without Platform Constraints</strong></h3><p>Action Cable on Kubernetes eliminates the connection timeout constraints that shape Action Cable architecture on Heroku. Kubernetes pods support long-lived WebSocket connections natively. The platform does not impose connection timeouts that require client-side reconnection logic as a reliability mechanism.</p><p>The Redis connection count problem from Heroku also resolves structurally. On EKS with ElastiCache, Redis connection limits are governed by the ElastiCache node type&#8217;s actual capacity, not by Heroku&#8217;s tier pricing model, which forces Redis upgrades based on connection count thresholds rather than actual resource consumption. A Rails application with 500 concurrent Action Cable subscribers connecting through 10 web pods uses 10 Redis connections from the server side. ElastiCache at an appropriate node type handles this without tier-jump pricing pressure.</p><h3><strong>Sidekiq: Persistent Workers Without Daily Interruption</strong></h3><p>Sidekiq workers on Kubernetes run as persistent Deployments. They are not subject to daily restarts as part of normal platform operation. They restart only when a new deployment is pushed or when a pod fails health checks.</p><p>When a new deployment is pushed, Kubernetes performs a rolling update: new Sidekiq pods start and become healthy before old ones terminate. Sidekiq&#8217;s shutdown signal handling (SIGTERM) gives in-flight jobs a configurable timeout to complete before the process exits. Jobs that cannot complete within the timeout are requeued for processing by the new pod.</p><p>This is meaningfully more reliable than Heroku&#8217;s daily dyno restart model for Sidekiq workloads. Teams running batch processing, data pipelines, or long-running background jobs on Sidekiq find that the daily restart window on Heroku requires explicit engineering investment to handle safely, retry logic, idempotency guarantees, and job state persistence. On Kubernetes, the restart behaviour is controlled, predictable, and aligned with how long-running background workloads should behave.</p><h3><strong>Asset Pipeline: Reproducible Builds Without Buildpack Fragility</strong></h3><p>Container-based builds for Rails applications handle asset precompilation in a Dockerfile layer that is fully specified and reproducible. The build environment, Ruby version, Node.js version, and system library versions are declared explicitly in the Dockerfile. The assets: precompile step runs in the same environment on every build, in every environment. There is no buildpack version drift, no build-time environment variable injection that affects compilation behaviour, and no memory pressure from shared build infrastructure.</p><p>Teams running Webpacker, Shakapacker, or Vite Ruby alongside Sprockets benefit directly from this model. The JavaScript build toolchain is specified in the Dockerfile, Node.js version pinned, npm dependencies installed from package-lock.json, Webpack or Vite build executed in the same layer that has access to the full build environment. The compiled assets are baked into the container image and deployed consistently to every replica. There is no per-dyno asset compilation, no CDN configuration required to make assets available across dynos, and no compile-time failures caused by environment configuration differences between the build environment and the runtime.</p><h2><strong>Why Heroku Is Architecturally Unsuitable for Persistent, Stateful Workloads</strong></h2><p>This is the structural incompatibility that underlies most of the Rails-specific failure modes described above, and it is worth stating clearly rather than leaving it implicit.</p><p>Heroku&#8217;s architecture is designed for stateless, ephemeral processes. The dyno model treats compute as fungible: dynos start, serve requests or process jobs, and stop. The ephemeral filesystem means no state persists between dyno restarts. The daily restart cycle means no process runs indefinitely. This model is intentional; it makes Heroku simple to reason about and resilient to individual process failures.</p><p>The problem is that production Rails applications are not fully stateless and ephemeral. They have components that are legitimately persistent and stateful:</p><p><strong>Background job queues (Sidekiq)</strong> maintain in-progress job state in memory during execution. A job interrupted mid-execution is in an indeterminate state. Heroku&#8217;s restart model treats this as acceptable because the ephemeral design expects processes to be interruptible. Sidekiq&#8217;s operational model expects processes to complete in-flight work before restarting.</p><p><strong>WebSocket connections (Action Cable)</strong> are inherently persistent. A WebSocket connection to a Heroku dyno is subject to the dyno&#8217;s connection timeout policies and restart behaviour. The connection abstraction that Heroku provides is not designed for long-lived stateful connections.</p><p><strong>File system operations</strong> (temp file staging, variant generation, direct upload flows) assume that the local filesystem persists at least for the duration of a request-response cycle and in many cases across requests. Heroku&#8217;s ephemeral filesystem satisfies the first assumption but not reliably the second, particularly across dyno restarts.</p><p><strong>What modern infrastructure design does instead:</strong></p><p>Kubernetes pods on EKS are persistent by default. A pod runs until explicitly replaced by a deployment update or until it fails a health check. Pods are not subject to scheduled daily restarts. Persistent volumes can be mounted for workloads that genuinely need local filesystem persistence. Long-lived connections are supported without platform-imposed timeouts.</p><p>The design principle is different: instead of treating all compute as ephemeral and requiring applications to accommodate that, Kubernetes allows workloads to declare their persistence requirements explicitly. Stateless web processes use rolling deployments and horizontal autoscaling. Stateful background workers use persistent pod lifecycles with graceful shutdown handling. Workloads with persistent storage requirements mount persistent volumes. Each workload type gets the persistence model it needs.</p><p>For Rails applications, this means the application can be designed around what the feature needs rather than around what the platform will reliably support. That is the structural difference between Heroku and modern alternatives for production Rails workloads.</p><h2><strong>Why CI/CD Workflows Built on Heroku Fail at Scale, and What Production-Grade Looks Like</strong></h2><p>Heroku&#8217;s deployment model was built around a specific Git-based workflow: push to a branch, Heroku deploys. For individual developers or small teams, this is simple and effective. For engineering organisations with multiple teams, feature branch workflows, review environments, and deployment promotion across staging and production, the model breaks in specific ways.</p><p><strong>The specific CI/CD failure modes on Heroku:</strong></p><p><em>No native review app reliability at scale.</em> Heroku&#8217;s review apps feature spins up ephemeral environments per pull request. In practice, review apps on Heroku have reliability problems at scale: slow provisioning, environment variables that do not correctly inherit from the parent app configuration, and ephemeral environments that do not accurately replicate production because Heroku&#8217;s add-on provisioning in review apps does not match production configuration.</p><p><em>The deployment pipeline lacks integration with modern Git workflows.</em> Heroku Pipelines, the mechanism for promoting builds from staging to production, works for simple linear workflows. Teams using trunk-based development with feature flags, teams with multiple staging environments for different workstreams, or teams that need to deploy specific commits rather than the latest main branch find that Heroku&#8217;s pipeline model does not accommodate their workflow without significant workarounds.</p><p><em>Build failures are opaque.</em> When a Heroku build fails, during slug compilation, during buildpack execution, or during asset precompilation, the failure message is often insufficient to diagnose the root cause quickly. Buildpack builds are black boxes with limited introspection. Teams spend engineering time decoding build failures that a container build with explicit Dockerfile layers would surface clearly.</p><p><em>No native canary or blue-green deployment.</em> Heroku Pipelines support build promotion but not sophisticated deployment strategies. Blue-green deployments require manual Heroku preboot configuration. Canary deployments, routing a percentage of traffic to a new version to validate before full rollout, are not natively supported. For teams deploying to production multiple times per day with reliability requirements, the absence of native traffic-splitting deployment strategies is a meaningful operational gap.</p><p><strong>What a production-grade Rails CI/CD pipeline looks like:</strong></p><p>A production-grade CI/CD pipeline for a Rails application in 2026 has a few defining characteristics:</p><p><em>Container-based builds that are environment-consistent.</em> The same Docker image that is tested in CI is deployed to staging and then to production. There is no slug re-compilation, no buildpack re-execution, no environment-specific build behaviour. The image is built once, tested, and promoted. What passes CI is exactly what runs in production.</p><p><em>Branch-triggered environment provisioning.</em> Feature branches trigger the provisioning of isolated review environments automatically. The review environment is not a stripped-down approximation of production; it is the same Kubernetes deployment with the same configuration, the same managed Postgres instance, and the same observability stack. Developers can test against an environment that accurately represents production behaviour.</p><p><em>Deployment strategy configuration per service.</em> Rolling deployments by default. Blue-green for services where zero-downtime cutover is critical. Canary traffic splitting for high-risk releases. These are configuration choices per service, not platform limitations that require workarounds.</p><p><em>Integrated observability in the deployment event stream.</em> Deployments appear as events in the metrics and log timeline. When a deployment at 2:35 PM correlates with an error rate spike at 2:36 PM, that correlation is visible in Grafana without cross-referencing deployment logs in a separate interface.</p><p>LocalOps delivers this pipeline model for Rails teams. Push to branch triggers a Docker build, image push to ECR, and deployment to the target EKS environment automatically. Review environments are provisioned on pull request open and torn down on merge. Deployments are visible as events in the Grafana dashboard. Rolling deployments run by default. The pipeline configuration is per-service and per-environment, not global and opaque.</p><h2><strong>How LocalOps Addresses the Full Rails Production Stack</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform built for teams, replacing Heroku. For Rails teams specifically, it handles the full production stack:</p><p><strong>Web processes</strong> run on EKS with horizontal autoscaling driven by CPU and request rate metrics. Web dynos scale out under traffic pressure and back in during off-peak periods. No manual dyno count management.</p><p><strong>Sidekiq workers</strong> run as persistent Kubernetes Deployments with independent resource allocation from web processes. Daily restarts do not occur. Rolling deployments give in-flight jobs time to complete before old pods terminate.</p><p><strong>Postgres</strong> runs on Amazon RDS with automated backups, read replica support, Multi-AZ availability, and storage autoscaling. Pricing scales with actual resource consumption, not with row count tiers.</p><p><strong>Redis</strong> runs on Amazon ElastiCache with connection count driven by actual workload, not by pricing tier thresholds. Sidekiq, Action Cable, and Rails cache all share the ElastiCache instance with appropriate namespace separation.</p><p><strong>Active Storage</strong> connects to S3 buckets provisioned as part of the environment. No architectural workarounds. No ephemeral filesystem fragility.</p><p><strong>Action Cable</strong> runs on web pods without platform-imposed connection timeouts. Redis pub/sub backend connects to ElastiCache.</p><p><strong>Asset pipeline</strong> builds inside Docker during CI. Compiled assets are baked into the container image. No per-dyno compilation, no buildpack fragility.</p><p><strong>Observability</strong>, Prometheus, Loki, and Grafana are included in every environment. Rails application metrics, Sidekiq job throughput and error rates, database performance, and Redis connection metrics are all available from day one without add-on configuration.</p><p>Sign up for free at LocalOps, and connect your AWS account. Connect your GitHub repository. LocalOps provisions the full environment automatically in under 30 minutes. First Rails application deployed to AWS without writing Terraform, Helm charts, or Kubernetes YAML.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221; </em>&#8211; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, all of which LocalOps has saved for us.&#8221; </em>&#8211; Gaurav Verma, CTO and Co-founder, SuprSend</p><p> <a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get a live environment in under 30 minutes</a></p></blockquote><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>What is the best Heroku alternative for Rails in production with Postgres, Sidekiq, and autoscaling?</strong></p></li></ol><p>For teams that need production-grade Rails hosting with all three, Postgres, Sidekiq, and horizontal autoscaling, an AWS-native Internal Developer Platform like LocalOps is the strongest option. It maps the full Rails application model to managed AWS services: EKS for web and worker processes, RDS for Postgres, ElastiCache for Redis and Sidekiq, and S3 for Active Storage. Autoscaling runs horizontally on EKS rather than vertically through dyno tiers. Sidekiq workers run as persistent Kubernetes Deployments without daily interruption. The developer experience stays close to Heroku, push to branch, service deploys, without requiring Kubernetes expertise from the engineering team.</p><ol start="2"><li><p><strong>How does the Sidekiq migration from Heroku to Kubernetes actually work?</strong></p></li></ol><p>Sidekiq on Kubernetes runs as a separate Kubernetes Deployment from the Rails web process. The Procfile convention from Heroku maps directly: worker: bundle exec sidekiq becomes a separate Deployment in Kubernetes with its own replica count, resource allocation, and scaling policy. LocalOps reads the Procfile and generates the corresponding Kubernetes resources automatically during environment setup. The Sidekiq configuration, concurrency, queue weights, and Redis connection URL are passed through environment variables or Kubernetes secrets exactly as on Heroku. The operational difference is that Sidekiq workers are no longer subject to daily dyno restarts, and rolling deployments give in-flight jobs time to finish before old pods terminate.</p><ol start="3"><li><p><strong>Can teams run Rails, Node.js, and Python services from the same deployment platform on LocalOps?</strong></p></li></ol><p>Yes, LocalOps deploys any containerised workload to the same EKS cluster. A Rails API, a Node.js frontend server, and a Python ML inference service all deploy through the same pipeline, log to the same Loki instance, and surface metrics in the same Grafana dashboard. Language runtime differences are encapsulated in each service&#8217;s Dockerfile. The platform layer is language-agnostic. For platform teams managing heterogeneous stacks, this means a consistent deployment model, consistent observability, and consistent incident response across all services regardless of language runtime.</p><ol start="4"><li><p><strong>What does the Rails asset pipeline look like in a Docker-based deployment?</strong></p></li></ol><p>The standard pattern for Rails asset precompilation in Docker uses a multi-stage build: a build stage installs all dependencies, runs bundle exec rails assets: precompile, and produces compiled assets; a production stage copies only the compiled assets and production dependencies from the build stage, leaving build tooling behind. This produces a smaller container image than single-stage builds and ensures that asset compilation always runs in a controlled, reproducible environment. Node.js is available during the build stage for Webpacker, Shakapacker, or Vite Ruby compilation. The compiled assets are baked into the image and consistent across all replicas, no per-dyno compilation, no CDN required to serve assets consistently across a multi-replica deployment.</p><ol start="5"><li><p><strong>How do review environments on LocalOps compare to Heroku Review Apps for Rails applications?</strong></p></li></ol><p>LocalOps provisions review environments as full Kubernetes deployments in isolated namespaces upon opening a pull request. The review environment includes the Rails application, a Postgres database (RDS instance or shared cluster with namespace isolation), Redis, and the full observability stack. It is not a stripped-down approximation of production; it is the same deployment configuration. Environment variables are inherited from the parent environment&#8217;s configuration. The review environment tears down automatically on PR merge or close. For Rails teams doing feature branch development, the practical difference from Heroku Review Apps is reliability: review environments on Kubernetes are provisioned consistently and behave like production rather than like an approximation of it.</p><ol start="6"><li><p><strong>Why is Heroku architecturally unsuitable for long-running Rails background jobs?</strong></p></li></ol><p>Heroku&#8217;s dyno model is built for ephemeral processes that start, do work, and stop. Daily dyno restarts are a feature of this model, not a bug; the platform is designed to treat compute as interruptible. Sidekiq workers are not interruptible without consequences: a job interrupted mid-execution may leave application state in an inconsistent condition, and the engineering investment required to make every job safely interruptible is significant. On Kubernetes, pods are persistent and only restart when explicitly replaced by a deployment update or when health checks fail. Deployment updates use rolling restart with a configurable termination grace period that allows Sidekiq to finish in-flight jobs before the old pod exits. The platform&#8217;s restart model is aligned with how long-running background workloads actually behave.</p><h2><strong>Key Takeaways</strong></h2><p>Rails teams leave Heroku for a specific set of reasons that are tied to the Rails application model, not to generic infrastructure concerns. Sidekiq workers that cannot run persistently. Active Storage that requires application-level workarounds for ephemeral filesystem constraints. Action Cable deployments shaped by connection timeout policies and Redis tier pricing. Asset pipeline builds that fail in opaque ways due to buildpack environment drift. CI/CD workflows that do not accommodate modern Git-based development practices at the team scale.</p><p>These failure modes share a common root: Heroku&#8217;s architecture optimises for stateless, ephemeral processes. Production Rails applications need a hosting model that correctly handles persistent, stateful workloads alongside the stateless web tier.</p><p>Modern alternatives built on AWS address this structurally. EKS runs persistent workloads with graceful shutdown handling. RDS provides Postgres without tier-jump pricing. ElastiCache provides Redis without connection-count-driven pricing pressure. S3 makes Active Storage work correctly without filesystem workarounds. Container-based builds make asset precompilation reproducible. Rolling deployments with graceful termination make Sidekiq migrations safe.</p><p>What changes when Rails teams move to LocalOps: the infrastructure is in the team&#8217;s AWS account, workloads run persistently without daily interruption, observability is integrated rather than assembled from add-ons, and the CI/CD pipeline accommodates modern Git workflows rather than constraining them.</p><p>What stays the same: the deployment model. Push to branch, service deploys. The Rails application does not know it moved.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started with LocalOps</a> &#8594;</strong> First Rails production environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call</a> &#8594;</strong> Our engineers walk through your specific Rails stack, Sidekiq configuration, Active Storage setup, Action Cable deployment, and map the migration path.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Heroku Migration Guide</a> &#8594;</strong> Full technical walkthrough: database migration, Sidekiq configuration, DNS cutover, asset pipeline setup.</p>]]></content:encoded></item><item><title><![CDATA[How to Provision a Production-Grade AWS Environment Without Writing Terraform]]></title><description><![CDATA[What a production-grade AWS environment actually requires, and why an internal developer platform is a better alternative to owning Terraform at scale.]]></description><link>https://blog.localops.co/p/provision-aws-environment-without-terraform</link><guid isPermaLink="false">https://blog.localops.co/p/provision-aws-environment-without-terraform</guid><dc:creator><![CDATA[Madhushree Sivakumar]]></dc:creator><pubDate>Thu, 23 Apr 2026 04:16:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!WIsJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.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_!WIsJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WIsJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png 424w, https://substackcdn.com/image/fetch/$s_!WIsJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png 848w, https://substackcdn.com/image/fetch/$s_!WIsJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png 1272w, https://substackcdn.com/image/fetch/$s_!WIsJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WIsJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png" width="1456" height="1504" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/af30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1504,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6486573,&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://blog.localops.co/i/195199472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.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_!WIsJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png 424w, https://substackcdn.com/image/fetch/$s_!WIsJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png 848w, https://substackcdn.com/image/fetch/$s_!WIsJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.png 1272w, https://substackcdn.com/image/fetch/$s_!WIsJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf30ef8d-b3ec-4805-a3ae-d7a282294f6a_2324x2400.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>If you are running a 15 to 50-person engineering team, there is a good chance someone on your team is maintaining Terraform instead of building product. Not because they want to. Because someone has to.</p><p>Spinning up a production-grade environment on AWS is not a weekend project. The networking alone &#8212; VPC, subnets, NAT gateway, security groups &#8212; takes time to get right. Add EKS, IAM roles, secrets management, observability, and per-environment configuration, and you are looking at several days to a week of infrastructure work before the first feature deploys. Each new environment after that adds incremental overhead and increases the risk of configuration drift between staging and production.</p><p>At some point, the question stops being &#8220;how do we configure this correctly&#8221; and starts being &#8220;why is this our problem to own.&#8221;</p><p>Internal developer platforms exist to answer that question. This post covers what a production-grade AWS environment actually requires, what it costs to maintain that setup in-house across environments, and how an IDP changes the tradeoffs for engineering teams that would rather be building.</p><h3>TL;DR</h3><ul><li><p>A production-grade AWS environment needs more than most teams plan for: a full networking stack (VPC, private and public subnets, NAT gateway), a managed Kubernetes cluster (EKS), compute nodes, a load balancer, IAM, secrets management, encryption, observability, and backup configuration.</p></li><li><p>Setting up this stack in Terraform typically takes several days to a week depending on complexity and team experience. The second and third environments are where state management overhead and configuration drift start compounding.</p></li><li><p>Every environment your team cannot spin up quickly is a bottleneck: slower staging, slower customer onboarding, slower incident isolation.</p></li><li><p>Internal developer platforms handle the provisioning layer so application developers do not have to. Developers get self-serve environments, GitHub-push deployments, and AWS resource access without managing infrastructure code directly.</p></li></ul><h3>What a Production-Grade AWS Environment Actually Needs</h3><p>Most teams start with a rough mental model: a cluster, a database, some networking. The actual list of what constitutes a production-grade AWS environment is longer, and the gaps between what teams think they need and what they actually need tend to surface at the worst possible time.</p><p>Here is what a complete setup requires.</p><h4>Networking</h4><p>A dedicated VPC with a defined CIDR block. Private subnets for application workloads, with no public IP on application nodes. Public subnets for ingress components like load balancers. A NAT gateway with an Elastic IP in the public subnet so private subnet nodes can make outbound calls for pulling container images and reaching external APIs. An Internet gateway attached to the VPC. For private clusters, VPC endpoints for services like STS, ECR, and S3 are often required for integrations to work reliably.</p><h4>Compute and orchestration</h4><p>A managed Kubernetes cluster (EKS), where AWS runs the control plane (API server, etcd, scheduler) across multiple availability zones. Worker nodes run as EC2 instances in private subnets, attached to the cluster as a node group, with EBS volumes. Inbound traffic reaches workloads through an ALB or NLB provisioned via Kubernetes ingress or a Service of type LoadBalancer, not at the cluster level directly.</p><h4>IAM</h4><p>Node instance profiles for baseline EC2 permissions. IRSA (IAM Roles for Service Accounts) for pod-level AWS access, using OIDC-based access control so individual pods get scoped permissions rather than sharing the node role. Least-privilege policies per resource. Getting this wrong is how production incidents happen.</p><h4>Secrets management</h4><p>AWS Secrets Manager or SSM Parameter Store for credentials and environment-specific config. AWS&#8217;s own guidance for EKS uses IRSA and OIDC for Secrets Manager access from pods, so this ties directly to the IAM setup above.</p><h4>Security</h4><p>Encryption at rest on EBS volumes and managed data stores. Security groups in AWS are stateful allow rules, so the practical goal is tightly scoped ingress, minimal egress, and private-only access for databases and caches. Cluster endpoint access control to limit who can reach the Kubernetes API.</p><h4>Observability</h4><p>Prometheus for cluster and node metrics, Loki or CloudWatch for log aggregation, Grafana as the unified interface. Without this, debugging a live incident means guessing. AWS supports Prometheus-based metrics collection through Container Insights, but it still requires setup.</p><h4>Backup and recovery</h4><p>Automated backups for managed data stores with defined retention. AWS Backup can cover EKS cluster state and persistent storage, but a backup without a tested restore procedure is not a recovery plan.</p><h4>Autoscaling and node lifecycle</h4><p>Cluster autoscaler or Karpenter for node scaling. A defined strategy for node upgrades, because EKS minor version support windows are finite and upgrades require planning.</p><p>The sum of this is not exotic. It is the baseline. But it is also a significant number of infrastructure concerns that need to be correctly configured and kept consistent across every environment you run: production, staging, preview, and any customer-dedicated environments.</p><p>That gap between what teams plan for and what production actually requires is where most of the infrastructure overhead lives.</p><p>See what&#8217;s <a href="https://docs.localops.co/environment/inside?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">inside a LocalOps environment</a></p><h3>The Real Cost of Owning Terraform at a Scaling Startup</h3><p>The Terraform problem at a scaling startup is not that Terraform is hard. It is that owning it has a compounding cost that most teams only feel after they are already committed to it.</p><h4>The First Environment Is Manageable</h4><p>Community modules like terraform-aws-modules/vpc and terraform-aws-modules/eks handle a lot of the scaffolding. A senior engineer who knows what they are doing can get a well-configured first environment running in several days to a week. The work is real but it is bounded.</p><h4>The Second Environment Is Where It Gets Complicated</h4><p>Each environment needs its own state file. Teams typically end up with either Terraform workspaces, which have state isolation problems, or a directory structure like environments/prod and environments/staging where configuration is duplicated and diverges over time. Staging drifts from production. Nobody fully documents what changed or why. The engineer who built the original setup has usually moved on to other work by the time environment three is needed.</p><h4>State Management Fails Quietly</h4><p>Two engineers running terraform apply concurrently without remote state locking (S3 + DynamoDB) can corrupt state. Recovering from corrupted state means manual terraform state mv and terraform import operations. It is recoverable, but it takes time and focus that should be going elsewhere.</p><h4>EKS Add-On Management Is a Separate Problem</h4><p>Managed add-ons like CoreDNS, kube-proxy, VPC CNI, and the EBS CSI driver have independent version lifecycles from the EKS module. They fall behind cluster version requirements in ways that cause node registration failures or pod networking issues that are hard to diagnose if you have not seen them before.</p><h4>Observability Is Almost Always Deferred</h4><p>Terraform provisions the cluster. It does not install or configure Prometheus, Loki, or Grafana. That requires a separate Helm chart workflow. Most teams put it on the backlog and add it later under pressure, usually after a live incident makes it unavoidable.</p><h4>The Actual Cost Is Not the Setup Time</h4><p>It is the ongoing maintenance tax: keeping environments consistent, managing module version upgrades, handling state issues, and making sure the one person who understands the full setup is not a single point of failure. At a 20 to 40-person company, that tax comes directly out of product velocity.</p><p>A team with a dedicated platform engineer can run this well. Most scaling startups do not have that luxury.</p><p>For teams that go further, building an internal developer platform in-house adds another layer of cost on top of infrastructure: hiring for it, maintaining it, and keeping it current.</p><p>That investment is hard to justify when the underlying goal is simply to ship product reliably on AWS.</p><h3>What Is an Internal Developer Platform and How Does It Change the Provisioning Model?</h3><p>An internal developer platform is a layer that sits between application developers and cloud infrastructure. It owns the provisioning model, enforces production defaults, and gives developers a self-service interface that does not require infrastructure knowledge to use.</p><p>The term gets used loosely, so it is worth being precise about what an IDP actually does versus what it does not do.</p><h4>What an IDP Is Not</h4><p>The internal developer portal vs platform distinction is a common source of confusion. A portal gives teams a UI to browse services, view documentation, and track ownership. Backstage is a good example: it is a developer portal framework, not a platform. It does not provision infrastructure. Building a full IDP on top of Backstage means writing and maintaining plugins for environment provisioning, CI/CD, cloud resource management, and observability. That is a significant internal build investment, not a solved problem.</p><p>An IDP is also not a PaaS wrapper that puts a UI on top of managed services and abstracts away the cloud account. The distinction matters for engineering leaders: a real IDP provisions into your own cloud account, so you retain ownership of the infrastructure, the data, and the billing relationship with AWS.</p><h4>What an IDP Actually Does</h4><p>It owns a set of production-hardened provisioning templates and creates environments idempotently from those templates. Any engineer on the team can spin up a new environment without understanding VPC design, EKS configuration, or IAM. The platform handles what those things map to in AWS.</p><p>This is where platform engineering and internal developer platforms intersect. The goal is not to eliminate infrastructure complexity but to centralise ownership of it.</p><p>The critical distinction is between shallow and deep abstraction. A shallow abstraction wraps Terraform in a UI and still requires someone who understands the underlying resource model to maintain it. A deep abstraction owns the resource model entirely, enforces production defaults, and exposes only what developers need to configure.</p><h4>What a Production-Grade IDP Provisions on AWS</h4><p>When connected to AWS, Internal developer platform provisions a complete, exclusive infrastructure stack: a dedicated VPC, private and public subnets, a NAT gateway, an Internet gateway, a managed Kubernetes cluster, compute node groups with attached storage, a load balancer for inbound traffic, and a pre-configured observability suite. Each environment gets its own isolated stack. There is no shared multi-tenant infrastructure between environments.</p><p>This gives you network, data, and compute isolation by default, which matters for teams running staging environments alongside production, or operating customer-dedicated deployments.</p><p>The provisioning happens without Terraform files to write, without state to manage, and without IAM roles to configure manually. Your team connects an AWS account, creates an environment, and the platform handles the provisioning from there.</p><h3>How IDPs Give Developers Self-Serve Access to AWS Without Exposing Infrastructure Complexity</h3><p>Once an environment exists, application teams still need to declare what cloud resources their services depend on: databases, caches, queues, object storage. This is where most platforms fall short. They handle the networking layer but leave AWS service dependencies to the developer to figure out.</p><p>A well-built IDP solves this through a declarative service configuration file committed to the application repository. Developers declare what their service needs. The platform provisions it within predefined guardrails, wires the permissions, and injects the connection details at runtime. Without requiring routine AWS console access. Without needing to manually write IAM policies in most cases. Without credentials to rotate manually.</p><p>Here is what that looks like in practice.</p><h4>Cloud Resource Dependencies</h4><p>A developer declares an S3 bucket, an RDS instance, an ElastiCache cluster, an SNS topic, or an SQS queue directly in the service config file. The platform provisions these resources inside the environment&#8217;s VPC, configures encryption at rest, sets private-only network access, enables monitoring, and turns on automated backups. The IAM policies required to access each resource are generated automatically and attached to the pre-configured role the service containers run with.</p><p>This replaces a non-trivial amount of manual work. Wiring IAM for S3 access from EKS pods manually involves setting up an OIDC identity provider, creating an IAM role with a trust policy, annotating the Kubernetes service account, and mounting it correctly in the pod spec. The declarative config approach reduces this to a few lines that any developer can write without knowing what is happening underneath.</p><p>See how<a href="https://docs.localops.co/environment/services/ops-json?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp#automatic-provisioning-of-cloud-resources"> LocalOps provisions cloud resources</a></p><h4>Environment Variable Injection</h4><p>Resource connection details, ARNs, endpoints, hostnames, and ports are injected automatically as environment variables into the service containers. Application code reads from environment variables at runtime. There are no credentials stored in code, no secrets to manually sync across environments, and no risk of a developer hardcoding a production database URL in a staging config file.</p><h4>Database Migrations and Init Jobs</h4><p>Schema migrations run as init containers before the main service starts, in the correct order, with the option to run once across all pods rather than once per pod. This behavior is not straightforward to implement correctly in Kubernetes without additional logic. The developer specifies the command. The platform handles the execution model.</p><h4>Health Checks</h4><p>HTTP, TCP, gRPC, or shell-based health checks with configurable failure thresholds and automatic container restarts. This maps to Kubernetes liveness and readiness probes under the hood, but the developer does not need to know that or write a Helm chart to configure it.</p><h4>Preview Environment Dependencies</h4><p>For pull request preview environments, the service config supports a separate block for ephemeral dependencies: Postgres, MySQL, Redis, Memcache, or RabbitMQ instances that spin up per PR and are torn down when the PR closes. These run as lightweight in-cluster containers rather than managed AWS services, suited for faster, lower-cost testing rather than production parity. Production resources are explicitly excluded from preview environments via config flags, so there is no risk of a preview service accidentally pointing at production data.</p><p>The net result for engineering leaders is that developers can configure, deploy, and connect AWS-backed services without infrastructure knowledge, without routine AWS console access, and without waiting on a platform team to provision resources for them. The self-service model works because the platform owns the complexity that would otherwise require infrastructure expertise.</p><h3>How Do You Let Developers Deploy to AWS With Just a GitHub Push?</h3><p>The deployment model is where an IDP either earns its place or exposes its limits. Self-serve infrastructure means nothing if shipping code still requires a platform engineer to be in the loop.</p><p>A well-built IDP connects directly to the application repository. A developer pushes to a configured branch. The platform pulls the latest commit, builds the container image, and deploys it to the Kubernetes cluster automatically, without requiring developers to write or maintain Dockerfiles, Helm charts, or CI/CD pipelines directly.</p><p>For most developers, the primary interaction with the deployment system becomes a git push.</p><h4>How the Deployment Pipeline Actually Works</h4><p>The platform builds the container image from the application source, pushes it to a registry, and schedules the new version on the cluster. Health checks run against the new containers before traffic is gradually shifted. If they fail, the deployment does not proceed and the previous version continues running.</p><p>This is not a novel concept. It is how deployment should work for application teams. The reason it is worth stating explicitly is that most teams building on raw AWS end up owning a significant amount of CI/CD configuration to get here: GitHub Actions workflows, ECR push credentials, EKS deploy steps, rollback logic. Each of those is a maintenance surface.</p><h4>Branch-Based Environment Mapping</h4><p>Each service in an environment typically maps to a specific GitHub branch. Push to the staging branch and the staging environment updates. Push to the production branch and production updates. Different team members can work on separate branches mapped to separate environments without stepping on each other.</p><p>For pull requests, a full-stack preview environment can be provisioned automatically per PR, with its own ephemeral dependencies, and torn down on merge. Developers get an isolated environment for every PR without any manual setup or infrastructure request.</p><h4>For Teams Migrating From PaaS</h4><p>Teams moving from Heroku, Render, Vercel, or Fly.io are often already used to push-to-deploy workflows. The gap they hit when moving to raw AWS is that the deployment simplicity disappears and gets replaced with infrastructure work. An IDP preserves that deployment experience while moving the actual infrastructure to a dedicated AWS account that the team owns and controls.</p><p>Moving to an IDP significantly reduces the amount of re-platforming work by preserving the push-to-deploy experience while shifting infrastructure complexity away from developers and onto the platform.</p><h3>What Happens When You Need Custom Infrastructure Beyond the Platform?</h3><p>No platform covers every infrastructure requirement a growing engineering team will have. At some point, a service needs a resource the platform does not natively support: a DynamoDB table, an MSK cluster, a custom VPC endpoint, a third-party data pipeline. This is the lock-in question every engineering leader should ask before committing to any IDP.</p><p>The answer depends entirely on whether the platform gives you the primitives to extend it.</p><h4>Extending the Environment With Custom IaC</h4><p>A well-built IDP exposes the underlying infrastructure identifiers for every environment it provisions: the VPC ID, subnet IDs, and resource tags. With those, a team can write Terraform or Pulumi scripts that provision additional resources within the same VPC and private subnets, privately accessible from application containers, without disturbing anything the platform manages.</p><p>The custom resources sit cleanly alongside the platform-managed infrastructure. They share the same network boundary. Application services can reach them without any additional networking configuration.</p><p>The lifecycle of those custom resources is the team&#8217;s responsibility. The platform does not import or manage them. If the team deletes the environment, they need to tear down their custom Terraform stack first, before the platform removes the VPC and underlying networking. That is a reasonable tradeoff, not a gotcha.</p><h4>Taking Full Ownership of the Infrastructure</h4><p>Beyond extending environments, a trustworthy IDP documents a full eject path: the ability to take complete ownership of the provisioned AWS infrastructure and move it outside the platform entirely.</p><p>This matters for two reasons. First, it tells you something about how the platform is designed. A platform confident enough to document a clean exit is one that expects to earn continued use rather than trap it. Second, it de-risks the adoption decision. Committing to an IDP is easier when the downside scenario is controlled rather than open-ended.</p><h4>How Often This Actually Comes Up</h4><p>For most engineering teams, the custom infrastructure question comes up less often than anticipated. The declarative service config model handles the majority of AWS resource dependencies that application services need. The cases that genuinely require custom IaC tend to be specific integrations or compliance requirements that are well-defined enough to manage separately.</p><p>The right question to ask is not whether the platform handles everything. It is whether the escape hatch is clean enough to use when you need it</p><h3>Internal Developer Platform Architecture</h3><p>An IDP that handles AWS environment provisioning operates across three layers. Knowing where each layer sits tells you what you are delegating to the platform and what you are keeping.</p><h4>The Infrastructure Layer</h4><p>VPC, subnets, NAT gateway, EKS cluster, EC2 nodes, EBS volumes, load balancer, observability stack. The platform provisions these into your AWS account using internal templates. Your account gets billed. You own the resources. The platform manages their configuration and lifecycle.</p><p>This is not hosting. The infrastructure runs in your account, not the vendor&#8217;s.</p><h4>The Platform Layer</h4><p>Kubernetes orchestration, container scheduling, service deployment, health check enforcement, auto-scaling, auto-healing. This layer runs on top of the infrastructure. Developers do not touch it. The platform operates it.</p><p>This is also the layer that costs the most to build and maintain in-house. Teams that roll their own IDP on top of Backstage or raw Kubernetes end up owning this in full, which means hiring for it, maintaining it, and being on call for it.</p><h4>The Developer Layer</h4><p>A service configuration file in the application repo, a GitHub integration, and a dashboard. This is the only surface developers interact with. They declare what their service needs, push code, and check deployment status. Everything below is handled by the platform.</p><h4>For the Build vs Buy Decision</h4><p>Building in-house means owning all three layers. Using a platform means owning the developer layer, retaining the infrastructure layer through your AWS account, and handing the platform layer to the vendor.</p><p>The platform layer is the one most teams do not want to own. It requires Kubernetes expertise, on-call coverage, and ongoing maintenance that has nothing to do with the product being built. That is the core of the IDP value proposition, stated plainly.</p><p>See how <a href="https://docs.localops.co/environment/shared-responsibilities?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">LocalOps handles shared responsibilities</a></p><h3>FAQ</h3><p><strong>1. What happens to our existing Terraform setup if we move to an IDP?</strong></p><p>You do not have to throw it away. A well-built IDP provisions and manages the core infrastructure layer: VPC, subnets, EKS cluster, observability. Any custom resources your team has already built in Terraform can continue to run alongside the platform, as long as they sit within the same VPC. The IDP exposes VPC IDs, subnet IDs, and resource tags so your existing Terraform scripts can reference them directly. The practical split is: the platform owns the environment baseline, your team owns anything custom on top of it.</p><p><strong>2. Can we trust the platform to enforce security defaults we would otherwise configure ourselves?</strong></p><p>This depends on how the platform is built. A production-grade AWS internal developer platform should enforce encryption at rest on all storage, private-only network access for databases and caches, least-privilege IAM policies per resource, and security group rules with tightly scoped ingress by default. These should not be optional configurations. They should be on by default for every environment the platform provisions, without requiring your team to audit or maintain them manually.</p><p><strong>3. What is the difference between an open source internal developer platform and a commercial one?</strong></p><p>Open source options like Backstage are portal frameworks, not full platforms. They provide a service catalog and developer UI but the provisioning and operational layers still need to be built on top. That is a significant internal build investment. A commercial internal developer platform includes the full stack out of the box: infrastructure provisioning, Kubernetes orchestration, observability, and CI/CD. The tradeoff is customisability versus the ongoing cost of building and maintaining the platform layer yourself.</p><p><strong>4. How do you choose the best internal developer platform for your AWS environment?</strong></p><p>A few things worth evaluating. Does it provision into your own AWS account or the vendor&#8217;s? You want to retain ownership of the infrastructure and the billing relationship. How deep is the abstraction? A platform that wraps Terraform in a UI still requires someone to understand the underlying resource model. What is the escape hatch when you need custom infrastructure? And does observability come pre-configured or is it something your team sets up separately? The best internal developer platforms answer all four of these cleanly.</p><p><strong>5. Can Terraform and an IDP coexist in the same AWS account?</strong></p><p>Yes, and for most teams they should. An IDP handles the environment baseline that every team needs: networking, compute, Kubernetes, observability. Terraform handles the exceptions: custom integrations, compliance-specific resources, or anything outside the platform&#8217;s native support. The key is that the IDP exposes the infrastructure primitives (VPC ID, subnet IDs) so custom Terraform resources sit inside the same network boundary and are privately accessible from application services without additional configuration.</p><h3>Conclusion</h3><p>Most engineering leaders do not set out to own a complex infrastructure setup. It tends to happen incrementally: one environment becomes two, staging drifts from production, the engineer who built the original setup moves on, and maintaining it becomes a background cost that nobody explicitly budgeted for.</p><p>The IDP model does not make infrastructure disappear. The VPC still exists. The EKS cluster still runs. IAM policies still govern access. What changes is who is responsible for configuring and maintaining those things, and whether that responsibility sits with the people building the product or with a platform built specifically to handle it.</p><p>The tradeoff is real. You give up some direct control over the infrastructure layer in exchange for not having to maintain it yourself. Whether that is the right call depends on your team size, your infrastructure requirements, and how much engineering capacity you have available for platform work.</p><p>For teams with a dedicated platform engineer who wants to own this, building and maintaining the stack in-house is a reasonable path. For teams without that, an IDP is worth evaluating not because it solves every infrastructure problem, but because it solves the provisioning and environment management problem well enough that the rest of the team can stay focused on the product.</p><p>If you&#8217;re figuring out how this would fit into your setup, then LocalOps team can help you work through it:</p><p><a href="https://go.localops.co/tour">Book a Demo</a> -- Walk through how environments, deployments, and AWS infrastructure are handled in practice for your setup.</p><p><a href="https://console.localops.co/signup">Get started for free</a> -- Connect an AWS account and stand up an environment to see how it fits into your existing workflow.</p><p><a href="https://docs.localops.co/">Explore the Docs</a> -- A detailed breakdown of how LocalOps works end-to-end, including architecture, environment setup, security defaults, and where engineering decisions still sit.</p><h3>Suggested Articles</h3><ol><li><p><a href="https://blog.localops.co/p/golden-path-deployments-internal-developer-platform">Golden Path Deployments: Ship Faster Without Managing Kubernetes or Terraform</a></p></li><li><p><a href="https://blog.localops.co/p/kubernetes-vs-internal-developer-platform-aws">Kubernetes vs Internal Developer Platform: Do You Need Both for AWS Deployments?</a></p></li><li><p><a href="https://blog.localops.co/p/how-to-scale-saas-engineering-team-without-hiring-more-devops">How to Scale a SaaS Engineering Team Without Hiring More DevOps</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Heroku Observability Is Broken at Scale - Here's What Production Teams Use Instead]]></title><description><![CDATA[What production-grade observability actually looks like beyond Heroku]]></description><link>https://blog.localops.co/p/heroku-observability-is-broken-at-scale</link><guid isPermaLink="false">https://blog.localops.co/p/heroku-observability-is-broken-at-scale</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Wed, 22 Apr 2026 12:24:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kPtq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.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_!kPtq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kPtq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png 424w, https://substackcdn.com/image/fetch/$s_!kPtq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png 848w, https://substackcdn.com/image/fetch/$s_!kPtq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png 1272w, https://substackcdn.com/image/fetch/$s_!kPtq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kPtq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png" width="1303" height="807" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:807,&quot;width&quot;:1303,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2575280,&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://blog.localops.co/i/194996625?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5d48ef1-8b07-44c7-a4aa-2e70357fa841_1303x2399.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_!kPtq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png 424w, https://substackcdn.com/image/fetch/$s_!kPtq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png 848w, https://substackcdn.com/image/fetch/$s_!kPtq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.png 1272w, https://substackcdn.com/image/fetch/$s_!kPtq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe5674ad-3dac-447e-bb64-e2ecc9f15a1d_1303x807.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><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> Why Heroku&#8217;s observability model fails at production scale, what the real financial and operational cost of the standard Heroku monitoring stack is, what natively integrated observability looks like on a modern alternative, and how AWS maps to the full Heroku stack without requiring Kubernetes expertise.</p><p><strong>Who it is for:</strong> CTOs and VPs of Engineering running production SaaS workloads on Heroku who are evaluating alternatives, specifically teams that want better observability without a post-migration setup project before they can operate in production.</p><p><strong>The conclusion:</strong> Heroku&#8217;s monitoring story is not weak because Heroku chose bad add-ons. It is structurally weak because Heroku&#8217;s architecture requires you to assemble observability from disconnected third-party tools, each with its own data model, pricing tier, and alert configuration. At production scale, that model creates financial overhead, incident response friction, and operational blind spots that integrated platforms eliminate by design.</p><h2><strong>Why Heroku&#8217;s Monitoring Story Collapses at Production Scale</strong></h2><p>Heroku&#8217;s observability model made sense when most Heroku applications were single services with modest traffic. A Papertrail log drain, a basic New Relic agent, and a status page were enough to know whether the application was healthy.</p><p>The problem is not that these tools are bad. The problem is the architectural model: Heroku provides no native observability layer. Every observability capability, logs, metrics, APM, error tracking, and uptime monitoring must be sourced from independent third-party add-ons, each billing separately, each storing data in its own system, each requiring separate configuration.</p><p>At a low scale with a single service, this is manageable. At production scale with five, ten, or fifteen services, the model breaks in three specific ways.</p><p><strong>Fragmentation makes incidents slower to resolve.</strong></p><p>When an incident occurs, the first task is correlation: which service is affected, what changed recently, and what does the error pattern look like relative to traffic and resource usage?</p><p>On Heroku, answering these questions requires switching between tools. Logs are in Papertrail. Application metrics and traces are in New Relic or Scout. Infrastructure metrics, if they exist at all, are in a separate monitoring add-on. Each tool has its own data model, its own time axis, and its own filtering interface.</p><p>The act of correlating a spike in error rates with a recent deployment, a specific service, and an underlying resource constraint requires context-switching between three or four separate interfaces. Every switch adds friction. Under incident pressure at 2 AM, that friction adds minutes to the mean time to resolution. For SaaS applications with customer-facing SLAs, those minutes are the difference between an incident that resolves cleanly and one that triggers a customer escalation.</p><p><strong>Add-on cost compounds with service count, not with revenue.</strong></p><p>This is the financial dynamic that surprises engineering leaders when they examine the Heroku invoice carefully. Observability costs on Heroku do not scale with your revenue. They scale with your service count and your log volume, both of which grow with product complexity, not with business growth.</p><p>Every new service adds a New Relic agent at the APM tier pricing. Every new service adds log volume that pushes Papertrail closer to the next pricing tier. Every additional engineer writing more verbose log output accelerates the compounding. The observability bill grows faster than the application bill, and faster than revenue, at precisely the growth stage where unit economics start mattering to the board.</p><p><strong>Coverage gaps appear exactly when you need visibility most.</strong></p><p>Heroku&#8217;s add-on model creates a specific failure mode: teams instrument the things they thought to instrument and are blind to everything else. The standard Heroku observability stack provides application-level logs and request-level APM traces. It does not provide container-level resource utilisation, memory pressure per service, pod restart counts, or infrastructure-level metrics that distinguish &#8220;application bug&#8221; from &#8220;resource constraint&#8221; during an incident.</p><p>Teams discover these coverage gaps at the worst possible time: during an incident that turns out to be a memory leak or a resource exhaustion pattern that no application-level log or APM trace would ever surface. The gap between what the monitoring shows and what is actually happening is the gap that turns a 15-minute incident into a two-hour war room.</p><blockquote><p><strong>Want to see what integrated observability looks like on LocalOps?</strong> <a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a walkthrough &#8594;</a></p></blockquote><blockquote><p><strong>The Real Cost of the Standard Heroku Observability Stack</strong></p></blockquote><p>The standard production observability stack on Heroku is assembled from three to five tools. Each carries its own cost. The combined cost compounds with service count in ways that most teams do not fully account for until they audit the invoice line by line.</p><p><strong>The standard stack and what it actually costs:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YXc6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YXc6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png 424w, https://substackcdn.com/image/fetch/$s_!YXc6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png 848w, https://substackcdn.com/image/fetch/$s_!YXc6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png 1272w, https://substackcdn.com/image/fetch/$s_!YXc6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YXc6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png" width="1336" height="772" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:772,&quot;width&quot;:1336,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:121944,&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://blog.localops.co/i/194996625?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.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_!YXc6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png 424w, https://substackcdn.com/image/fetch/$s_!YXc6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png 848w, https://substackcdn.com/image/fetch/$s_!YXc6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.png 1272w, https://substackcdn.com/image/fetch/$s_!YXc6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7253e781-59b3-4994-bc4c-271c2be3767d_1336x772.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><h3><strong>Papertrail (Log Management)</strong></h3><p>Papertrail pricing is structured around log volume: lines per month, retention period, and search capability. At low log volume with a single service, the cost is manageable. The problem is that log volume does not scale linearly with traffic. It scales with service count; more services mean more internal log output independent of external request volume, and with engineering team size, since more engineers writing more instrumentation produces higher baseline log output.</p><p>A team running five production services with reasonable log verbosity typically sits in a Papertrail tier that costs meaningfully more per month than the entry-level plan. Each additional service adds log volume that may or may not trigger a tier jump, but always moves the team closer to one.</p><h3><strong>New Relic or Scout APM (Application Performance Monitoring)</strong></h3><p>APM pricing on Heroku add-ons scales with host count or agent count. Adding a new service adds a new APM agent. Adding a new dyno for horizontal scaling adds another agent at the same per-agent rate.</p><p>For teams that run multiple services with multiple dynos each, the APM bill can easily exceed the compute bill. This is the observability cost that most surprises engineering leaders during a cost audit: the monitoring costs more than the compute it monitors.</p><h3><strong>Additional Tools: Error Tracking, Uptime Monitoring, Alerting</strong></h3><p>A production-ready observability setup also typically includes Sentry or Rollbar for error tracking, an uptime monitoring tool, and a separate alerting layer since Heroku&#8217;s native alerting capabilities are limited.</p><p>Each tool adds a billing line item. Each tool adds a configuration surface that someone on the team needs to maintain. Each tool is a separate place to look during an incident.</p><p><strong>The combined financial picture:</strong></p><p>For a typical five-service production stack on Heroku, the assembled observability stack costs between $400 and $900 per month, depending on traffic volume, service count, and the specific tools chosen. This number is not fixed; it grows with every new service, every traffic spike that pushes log volume past a tier boundary, and every new engineer that joins and starts writing logs.</p><p>The observability line item on a Heroku invoice is frequently larger than teams expect when they first examine it carefully, and it is one of the fastest-growing line items as the product scales.</p><p><strong>The operational cost beyond the financial one:</strong></p><p>The financial cost is real and calculable. The operational cost is often larger and harder to quantify.</p><p>The operational cost of a fragmented observability stack shows up in three places:</p><p><em>Initial configuration time.</em> Setting up Papertrail drain correctly, instrumenting New Relic across services, configuring alert thresholds, and wiring everything together is a non-trivial engineering project. Teams typically underestimate this when they first assemble the stack and then absorb the cost invisibly over time as new services require the same configuration cycle.</p><p><em>Maintenance overhead.</em> Each tool has its own configuration format, its own agent version requirements, and its own deprecation cycles. When New Relic releases a breaking change to their agent API, someone has to update every service. When Papertrail changes its drain configuration format, someone has to update the drain setup for every application. Multiply this by the number of tools in the stack.</p><p><em>Incident response friction.</em> As described above, the cost of context-switching between three or four separate monitoring interfaces during an incident is paid in minutes of additional incident duration on every incident. For a team running ten incidents per month at an average of fifteen minutes of additional context-switching overhead per incident, that is 2.5 hours of senior engineering time per month spent on avoidable tool friction during the highest-stress moments of the operational cycle.</p><h2><strong>What Natively Integrated Observability Looks Like on a Modern Heroku Alternative</strong></h2><p>The architectural difference between Heroku&#8217;s assembled monitoring model and natively integrated observability is not a difference of tools. Prometheus, Loki, and Grafana are open-source projects that exist outside of any platform. The difference is where the assembly and configuration happen: in the platform layer versus in every customer&#8217;s environment.</p><p>On a modern Heroku alternative with integrated observability, the monitoring stack is part of the platform. It is not a list of recommended tools teams should configure after migration. It is infrastructure that exists and runs from day one, covering every service deployed to the platform without additional setup.</p><p><a href="https://docs.localops.co/environment/services/deploy?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles observability out of the box &#8594;</a></p><p><strong>What this looks like in practice with LocalOps:</strong></p><p>LocalOps provisions Prometheus, Loki, and Grafana automatically as part of every environment, development, staging, and production. There is no observability setup step after migration. There is no drain configuration, no agent installation, and no dashboard provisioning. The stack is ready when the environment is ready.</p><p><strong>Prometheus: Metrics Without Agent Installation</strong></p><p>Prometheus collects metrics automatically from every service deployed to the platform: CPU utilisation, memory consumption, request rate, error rate, response latency, and any custom application metrics exposed on a standard metrics endpoint.</p><p>The difference between New Relic and Scout on Heroku is structural. New Relic requires agent installation and configuration per service. Prometheus on Kubernetes scrapes metrics from services automatically using service discovery, no agent, no per-service configuration, no per-service billing.</p><p>Teams get infrastructure-level and application-level metrics in the same system with the same data model. A memory pressure problem that triggers a pod restart and causes elevated error rates is visible as a single correlated event in Prometheus, not as two separate signals in two separate monitoring tools.</p><p><strong>Loki: Log Aggregation Without Drain Configuration</strong></p><p>Loki aggregates logs from all services through standard output. Services write logs to stdout. Loki collects them automatically. There is no Papertrail drain to configure, no log format requirement, and no volume-based pricing tier to worry about.</p><p>The operational difference from Papertrail is meaningful. Papertrail requires configuring a log drain URL per application, managing drain credentials, and monitoring log volume to avoid unexpected tier jumps. Loki on Kubernetes collects logs from every container automatically through standard Kubernetes log aggregation. New services are covered the moment they deploy.</p><p><strong>Grafana: Unified Dashboards for Logs and Metrics</strong></p><p>Grafana provides dashboards that query both Prometheus and Loki simultaneously. When an incident occurs, the engineer opens a single interface, selects the relevant service, and sees metrics and logs side by side with the same timestamps.</p><p>The incident response workflow changes fundamentally. Instead of opening Papertrail, filtering to the relevant service, opening New Relic, correlating the timeline, and switching back and forth, the workflow is: open Grafana, select the service and timeframe, and see the full picture.</p><p>LocalOps includes pre-built dashboards for infrastructure health, service-level metrics, and deployment events. Teams get operational visibility from day one without building dashboards from scratch as a separate project.</p><h2><strong>What AWS Looks Like as a Heroku Alternative, Without Requiring Kubernetes Expertise</strong></h2><p>The most common objection to AWS-based Heroku alternatives is not cost or capability; it is operational complexity. AWS is powerful but not self-serve for developers. A developer who can deploy a Heroku app in five minutes cannot deploy the same app to EKS in five minutes without a platform layer that abstracts the Kubernetes and AWS operations.</p><p>This objection is valid when applied to raw AWS. It does not apply to AWS accessed through an Internal Developer Platform like LocalOps, where the platform layer handles the Kubernetes and AWS operations automatically.</p><p><strong>The developer experience comparison:</strong></p><p><em>On Heroku today:</em> Developer pushes to the main branch. Heroku detects the push, runs the buildpack, creates a slug, and deploys the dyno. The developer can view logs from the Heroku dashboard. Service is running.</p><p><em>On LocalOps (AWS + IDP):</em> Developer pushes to main branch. LocalOps detects the push, builds a Docker image, pushes to ECR, and deploys to EKS. The developer can view logs and metrics from the LocalOps dashboard. Service is running.</p><p>The developer experience is structurally identical. The infrastructure underneath is in the team&#8217;s AWS account, with all the compliance and control implications that it carries. But the developer never writes a Dockerfile, never touches kubectl, and never configures a Kubernetes deployment manifest unless they choose to.</p><p>Teams where developers need to understand Kubernetes to deploy services have not implemented a Heroku alternative with a platform layer. They have implemented Kubernetes and asked their product engineers to become platform engineers. That is a different and significantly more expensive outcome.</p><h2><strong>How AWS Services Map to the Full Heroku Stack</strong></h2><p>For engineering leaders evaluating the migration, the question is not whether AWS can replace Heroku technically; it clearly can, but how each component of the Heroku stack maps to its AWS equivalent, and what the operational complexity difference looks like in practice.</p><p><strong>The full stack mapping:</strong></p><h3><strong>Heroku Dynos &#8594; Amazon EKS (Kubernetes on AWS)</strong></h3><p>Heroku dynos are the compute layer: containerised processes that run application code, receive traffic, and scale based on configuration.</p><p>Amazon EKS is the AWS-native equivalent: managed Kubernetes that runs containerised workloads, handles load balancing, and autoscales based on real resource metrics rather than manual dyno count adjustments.</p><p>The operational complexity difference on raw AWS is significant; Kubernetes requires configuration that Heroku handles automatically. Through LocalOps, the EKS cluster is provisioned, configured, and managed as part of the platform. Developers deploy to it without writing Kubernetes YAML.</p><p>The capability difference favours EKS meaningfully at scale:</p><ul><li><p>Horizontal autoscaling responds dynamically to CPU and memory pressure rather than requiring manual dyno count changes</p></li><li><p>Workloads scale to zero during off-peak periods rather than running at minimum dyno count continuously</p></li><li><p>Pod resource limits can be set per service rather than per dyno tier</p></li><li><p>Deployment strategies (rolling, blue-green) are configurable rather than fixed</p></li></ul><h3><strong>Heroku Postgres &#8594; Amazon RDS</strong></h3><p>Heroku Postgres is a managed PostgreSQL service with pricing structured around row limits, connection limits, and storage tiers that force upgrades as databases grow.</p><p>Amazon RDS is the AWS-native managed PostgreSQL equivalent. The structural pricing difference is significant: RDS charges based on instance type and actual storage consumed, not on arbitrary row count and connection limit tiers. A database at 7 million rows costs the same instance rate as a database at 5 million rows, as long as the instance type handles both workloads. There are no forced tier jumps driven by row counts.</p><p>Operational capabilities on RDS exceed Heroku Postgres at production scale: automated backups with configurable retention, read replica support for read-heavy workloads, Multi-AZ deployment for high availability, and storage autoscaling that expands capacity automatically without manual intervention.</p><h3><strong>Heroku Redis &#8594; Amazon ElastiCache</strong></h3><p>Heroku Redis pricing scales with connection count. As more services connect to Redis, the connection count drives tier upgrades that are significant price jumps relative to the actual resource consumption increase.</p><p>Amazon ElastiCache prices are based on node type and replication configuration. Connection count does not drive pricing. A five-service application with 200 total Redis connections costs the same ElastiCache rate as a two-service application with 50 connections, if the node type handles both workloads.</p><p>For multi-service architectures, this pricing difference is substantial. Every service in a Heroku stack that uses Redis adds to the connection count. ElastiCache pricing is indifferent to connection count within node capacity limits.</p><h3><strong>Heroku Monitoring Stack &#8594; Prometheus + Loki + Grafana (included in LocalOps)</strong></h3><p>As covered in detail above, the assembled Heroku monitoring stack of Papertrail, New Relic or Scout, and additional tools is replaced on LocalOps by an integrated observability stack that is part of the platform at no additional cost.</p><p>The financial comparison: $400&#8211;$900/month for the assembled Heroku observability stack versus zero additional cost on LocalOps, where Prometheus, Loki, and Grafana are included in the platform.</p><p>The operational comparison: multiple tools with separate configuration, separate data models, and separate alert configurations versus a unified stack with integrated dashboards, automatic service discovery, and correlated metrics and logs in a single interface.</p><h3><strong>Heroku Scheduler &#8594; Amazon ECS Scheduled Tasks or Kubernetes CronJobs</strong></h3><p>Heroku Scheduler handles time-based job execution with limited configurability: jobs run at defined intervals, there is minimal execution history, and there is no native retry logic or failure alerting beyond basic log output.</p><p>On AWS via LocalOps, scheduled jobs run as Kubernetes CronJobs: execution history is retained and queryable, failure alerting integrates with the platform&#8217;s observability stack, retry logic is configurable per job, and job resource allocation is separate from web dyno configuration, so scheduled jobs do not compete with request-serving workloads for resources.</p><h3><strong>Heroku Add-Ons (Miscellaneous) &#8594; AWS-Native Services</strong></h3><p>The broader Heroku add-on ecosystem, search, queuing, email, feature flags, and maps to AWS-native services or best-in-class managed services that run independently of the deployment platform. The key operational difference is that these integrations are not intermediated by Heroku&#8217;s add-on marketplace pricing layer. Teams connect directly to AWS SQS, OpenSearch, SES, or their preferred SaaS tools at the provider&#8217;s pricing without a platform markup.</p><h2><strong>How LocalOps Delivers This in Practice</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform built specifically for teams replacing Heroku. It handles the EKS cluster, VPC, load balancers, IAM roles, and observability stack automatically, and delivers the developer experience that makes Heroku compelling, running on infrastructure the business controls.</p><p><strong>The setup path:</strong></p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and the full observability stack, Prometheus, Loki, and Grafana, automatically. No Terraform. No Helm charts. No manual configuration. First environment ready in under 30 minutes.</p><p>From that point, the developer workflow is identical to Heroku. Push to your configured branch. LocalOps builds, containerises, and deploys to AWS automatically. Logs and metrics are available in Grafana from day one. Autoscaling and auto-healing run by default. Secrets management runs through AWS Secrets Manager with audit logging.</p><p>The observability stack that costs $400&#8211;$900/month in Heroku add-ons is included in LocalOps as infrastructure. There is no add-on to configure. There is no additional cost. There is no vendor to manage.</p><p>The infrastructure runs in your AWS account. If you stop using LocalOps, it keeps running.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221; </em>&#8211; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, all of which LocalOps has saved for us.&#8221; </em>&#8211; Gaurav Verma, CTO and Co-founder, SuprSend</p></blockquote><p><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get started for free &#8212; first environment live in under 30 minutes &#8594;</a></p><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>Why does Heroku&#8217;s monitoring break at production scale specifically, rather than at early stages?</strong></p></li></ol><p>At early stages, with one or two services, modest traffic, and a small engineering team, the assembled Heroku monitoring stack is manageable. The financial cost is limited, the configuration overhead is a one-time investment, and incident correlation across two tools is not prohibitively slow. The model breaks at the production scale because each of its weaknesses compounds with the service count. Financial cost multiplies per service. Configuration overhead recurs with every new service. Incident correlation becomes slower as the number of services generating signals increases and the number of tools required to correlate them grows. The same architectural model that works at low scale becomes operationally and financially indefensible when the number of services in production grows past five to ten.</p><ol start="2"><li><p><strong>Can teams get Prometheus, Grafana, and Loki without using an IDP like LocalOps?</strong></p></li></ol><p>Yes, all three are open-source projects and can be self-hosted. The operational cost of doing so is the relevant variable. Setting up Prometheus correctly on Kubernetes with appropriate scrape configurations, retention policies, and alert rules is a non-trivial engineering project. Integrating Loki with a log aggregation pipeline that covers all services requires additional configuration. Building Grafana dashboards from scratch that surface the metrics and logs relevant to production operations requires additional time. The open-source tools are available; the pre-configured, production-ready integration is what LocalOps provides as part of the platform. Teams that want to do this work themselves can. Teams that want to be in production on day one without an observability setup project use LocalOps.</p><ol start="3"><li><p><strong>What does the migration path from Heroku Postgres to Amazon RDS look like?</strong></p></li></ol><p>The core migration has three steps: provisioning an RDS instance with the same engine version, migrating data using pg_dump and pg_restore or AWS Database Migration Service, and updating application connection strings. The most important operational consideration is connection pooling: Heroku Postgres bundles PgBouncer connection pooling in its managed tiers. On RDS, connection pooling is configured separately using RDS Proxy or a self-managed PgBouncer instance. LocalOps handles the RDS provisioning and configuration automatically. The data migration guide in LocalOps&#8217;s documentation covers the full process with step-by-step instructions for typical Heroku Postgres configurations.</p><p><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the full migration guide &#8594;</a></p><ol start="4"><li><p><strong>How does the observability model change for teams running Rails applications on Heroku?</strong></p></li></ol><p>Rails applications on Heroku are typically instrumented with the New Relic Ruby agent for request tracing and rely on Heroku&#8217;s log output with Papertrail for log management. On LocalOps, Rails applications are instrumented with the OpenTelemetry Ruby SDK or use Prometheus&#8217;s Ruby client for custom metrics. Logs are written to stdout and are collected automatically by Loki. The instrumentation model is more explicit than New Relic&#8217;s automatic instrumentation, but it is also more flexible and not tied to a proprietary agent. Teams migrating Rails applications from Heroku typically find that the instrumentation migration takes one to two days. The observability visibility post-migration is meaningfully better than Heroku + New Relic + Papertrail because logs and metrics are correlated in a single interface.</p><ol start="5"><li><p><strong>What is the realistic total cost of ownership comparison between Heroku observability and LocalOps for a five-service production stack?</strong></p></li></ol><p>For a five-service production stack on Heroku, the observability component alone typically runs $400&#8211;$900/month: Papertrail at a tier appropriate for multi-service log volume, New Relic or Scout at per-agent pricing across five services and their dynos, plus error tracking and uptime monitoring tools. On LocalOps, the observability stack, Prometheus, Loki, and Grafana, is included at zero additional cost. The total infrastructure cost for the same five-service stack runs at AWS list pricing (typically $200&#8211;$400/month for compute and managed services) plus the LocalOps platform fee, replacing both the Heroku compute bill and the observability add-on bill. The observability saving alone typically exceeds the LocalOps platform fee.</p><ol start="6"><li><p><strong>Does using LocalOps create vendor lock-in that is worse than Heroku?</strong></p></li></ol><p>The opposite. Heroku&#8217;s lock-in is architectural: your infrastructure runs in Heroku&#8217;s cloud, your databases are Heroku Postgres instances, and your monitoring is Heroku-intermediated add-ons. If you stop using Heroku, everything must be rebuilt on a different platform. LocalOps provisions infrastructure in your AWS account. If you stop using LocalOps, the EKS cluster, VPC, RDS instances, ElastiCache clusters, and Prometheus stack all continue running in your AWS account. The dependency is on the platform&#8217;s operational interface, not on the platform&#8217;s infrastructure. Your Heroku dependency includes the infrastructure. Your LocalOps dependency does not.</p><h2><strong>Key Takeaways</strong></h2><p>Heroku&#8217;s observability model is broken at production scale, not because of any single tool&#8217;s weakness, but because the architectural model, assembling monitoring from disconnected third-party add-ons, creates compounding financial cost, operational fragmentation, and coverage gaps that grow with every service added to the production stack.</p><p>The $400&#8211;$900/month observability bill for a five-service Heroku production stack is the visible portion. The invisible portion is the engineering time spent on configuration, maintenance, and incident response friction across disconnected tools, costs that compound silently and rarely surface in infrastructure reviews.</p><p>Natively integrated observability on a modern Heroku alternative resolves this at the architectural level. When Prometheus, Loki, and Grafana are part of the platform rather than add-ons assembled after the fact, the financial cost disappears, the configuration overhead disappears, and the incident response workflow improves from three tools to one.</p><p>The AWS-to-Heroku stack mapping is complete: EKS replaces dynos with autoscaling that matches real workload patterns, RDS replaces Heroku Postgres without tier-jump pricing, ElastiCache replaces Heroku Redis without connection-count pricing penalties, and the LocalOps observability stack replaces the assembled Heroku monitoring stack at zero additional cost.</p><p>What platform teams gain: infrastructure in their AWS account, compliance posture for enterprise customers, and observability that is better than anything the Heroku add-on stack provides.</p><p>What developers keep: a deployment experience that is identical to Heroku, push to branch, service deploys, logs and metrics are immediately available.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started with LocalOps</a> &#8594;</strong> First production environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call</a> &#8594;</strong> Our engineers model your current Heroku observability costs against LocalOps + AWS and walk through the migration for your specific stack.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Heroku Migration Guide</a> &#8594;</strong> Full technical walkthrough: database migration, environment setup, DNS cutover.</p><p><em><strong>Related reading:</strong></em></p><ol><li><p><strong><a href="https://blog.localops.co/p/herokus-hidden-infrastructure-limitations">Heroku&#8217;s Hidden Infrastructure Limitations: What CTOs Only Discover at Scale</a></strong></p></li><li><p><strong><a href="https://blog.localops.co/p/heroku-alternatives">Heroku Alternatives the Engineering Community Actually Recommends in 2026</a></strong></p></li><li><p><strong><a href="https://blog.localops.co/p/the-real-cost-of-heroku-at-scale">The Real Cost of Heroku at Scale: A Teardown for CTOs Evaluating Alternatives</a></strong></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Internal Developer Platform vs PaaS]]></title><description><![CDATA[What's the Difference and Which One Does Your Engineering Team Actually Need?]]></description><link>https://blog.localops.co/p/internal-developer-platform-vs-paas</link><guid isPermaLink="false">https://blog.localops.co/p/internal-developer-platform-vs-paas</guid><dc:creator><![CDATA[Madhushree Sivakumar]]></dc:creator><pubDate>Wed, 22 Apr 2026 12:20:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!i_CT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.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_!i_CT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i_CT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png 424w, https://substackcdn.com/image/fetch/$s_!i_CT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png 848w, https://substackcdn.com/image/fetch/$s_!i_CT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png 1272w, https://substackcdn.com/image/fetch/$s_!i_CT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i_CT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png" width="1200" height="673" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:673,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1091174,&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://blog.localops.co/i/195022114?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.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_!i_CT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png 424w, https://substackcdn.com/image/fetch/$s_!i_CT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png 848w, https://substackcdn.com/image/fetch/$s_!i_CT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.png 1272w, https://substackcdn.com/image/fetch/$s_!i_CT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7aabd49-1a9b-4303-a836-98b3ec1cfbac_1200x673.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>PaaS and internal developer platforms are not the same thing, but most teams treat them as if they are. That confusion leads to either staying on a platform too long or jumping to something the team is not ready for.</p><p>A PaaS runs your application on the vendor&#8217;s infrastructure. An internal developer platform automates how your team provisions and operates infrastructure inside your own cloud account. The distinction is not just technical. It affects cost, compliance, and how much control your engineering team actually has over what runs in production.</p><p>This post covers what each one does, where PaaS typically stops working, and how to figure out which one fits your team right now.</p><h3>TL;DR</h3><ul><li><p>A PaaS deploys your code on the vendor&#8217;s infrastructure. An IDP automates how your team provisions and operates infrastructure inside your own cloud account.</p></li><li><p>PaaS works well for small teams with simple stacks. It starts breaking down around 10 to 20 engineers, multiple services, or any compliance requirement.</p></li><li><p>PaaS compute typically costs 2 to 5x more than equivalent cloud resources.</p></li><li><p>Building an IDP from scratch with Backstage takes 6 to 12 months and requires 3 to 15 engineers to maintain.</p></li><li><p>Managed IDPs exist specifically for teams that have outgrown PaaS but don&#8217;t have the capacity to build a platform from scratch.</p></li></ul><h3>What Is the Difference Between an Internal Developer Platform and a PaaS?</h3><p>The core difference is where your infrastructure lives and who controls it.</p><p>With a PaaS, the vendor owns the infrastructure. You deploy code onto their platform, and they handle the runtime, networking, scaling, and maintenance. You work within whatever constraints they have set. Heroku, Render, Railway, and Fly.io all follow this model.</p><p>With an internal developer platform, the infrastructure runs inside your own cloud account. The IDP is the automation and workflow layer on top of it. Developers get a self-service path to deploy services and provision environments without touching the underlying infrastructure directly. The platform team sets the guardrails. Developers work within them.</p><p>The CNCF defines an internal developer platform as an integrated collection of capabilities defined around the needs of the platform&#8217;s users, not the vendor&#8217;s convenience. That distinction matters when evaluating options.</p><h3>What PaaS Gives Your Engineering Team</h3><p>PaaS removes the infrastructure setup problem entirely. You connect a GitHub repository, configure a few environment variables, and you have a running application. No VPC setup, no container orchestration, no server provisioning. For a small team focused on shipping product, that is genuinely useful.</p><p>Most PaaS platforms give you:</p><ul><li><p>Automatic deployments triggered by code pushes</p></li><li><p>Managed runtimes for common languages and frameworks</p></li><li><p>Built-in SSL, load balancing, and basic autoscaling</p></li><li><p>Add-on marketplaces for databases, caching, and monitoring</p></li><li><p>Preview environments for pull requests</p></li></ul><p>The developer experience is fast to set up and easy to understand. A new engineer can push their first deployment on day one without knowing anything about the underlying infrastructure.</p><p>That simplicity is the point. PaaS makes sense when your team is small, your stack is straightforward, and infrastructure complexity is not yet a bottleneck. The trade-off is that you are working within the vendor&#8217;s model. Their networking, their compute, their scaling behavior, their pricing. As long as your requirements fit inside those constraints, it works.</p><p>Where PaaS genuinely earns its place is in the early stages of a product. You are not hiring a DevOps engineer to set up EKS. You are not writing Terraform to provision a VPC. You are shipping features. The platform handles deployments, restarts failed containers, and scales up when traffic increases. For a team of three to five engineers, that is a reasonable trade.</p><p>The problems appear later. PaaS platforms abstract the infrastructure, but that abstraction has hard edges. You cannot configure custom networking. You cannot control where your data lives at the subnet level. You cannot integrate with internal tooling that the add-on marketplace does not support. Heroku, for example, does not support persistent storage on standard plans, limits applications to a single port, and requires containers to boot in under 60 seconds. These are not edge cases. They are constraints that growing teams hit regularly.</p><p>When your requirements start pushing against those edges, the platform stops being an accelerator and starts being a ceiling.</p><h3>What an Internal Developer Platform Gives Your Engineering Team</h3><p>An internal developer platform gives developers a self-service path to deploy and operate services without depending on a DevOps engineer for every infrastructure request. The infrastructure still exists and runs on your cloud account. The IDP is what makes it accessible to the rest of the team.</p><p>In practice, a production-grade IDP on AWS provisions the following inside your account when a new environment is created:</p><ul><li><p>Dedicated VPC with private and public subnets</p></li><li><p>Managed EKS cluster with EC2 compute nodes</p></li><li><p>Load balancer for inbound traffic</p></li><li><p>Prometheus, Loki, and Grafana for metrics, logs, and dashboards</p></li><li><p>Managed AWS services on demand: RDS, S3, SQS, Elasticache</p></li><li><p>CI/CD pipeline wired to branch pushes</p></li><li><p>SSL certificates, encrypted secrets, and role-based access control</p></li></ul><p>Developers push code. The platform handles everything underneath. No Dockerfile, no Terraform, no Helm required from the developer&#8217;s side.</p><p>The operational difference shows up most clearly during onboarding and <a href="https://docs.localops.co/environment/inside?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">environment provisioning</a>. On a PaaS, a new engineer is productive quickly but is constrained by what the vendor supports. On an IDP, a new engineer gets the same self-service experience but against infrastructure your team controls. They can spin up a staging environment, deploy a service, and check logs without filing a ticket or waiting on anyone.</p><p>The platform team sets the golden paths once. Every developer on the team benefits from them without needing to understand the infrastructure underneath. When something breaks at the Kubernetes level, the platform handles recovery. Engineers who need deeper access can get it. Engineers who don&#8217;t, never have to think about it.</p><p>That split is what makes IDPs useful at scale. The abstraction is not hiding complexity permanently. It is putting it in the right hands.</p><h3>PaaS vs Internal Developer Platform:</h3><p>Infrastructure Control, Customization, and Team Fit Compared</p><p>Comparing PaaS and an IDP on features alone misses the point. The real difference is in what your team can and cannot do when requirements change. Here is how they stack up across the dimensions that actually matter.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/G43Xy/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4379f825-ef22-4f9f-9186-d8aa2278f9c4_1220x1430.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42771f27-b190-41bd-bf0f-11b0dfad165a_1220x1430.png&quot;,&quot;height&quot;:720,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/G43Xy/1/" width="730" height="720" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>The networking and compliance rows are where most teams feel the gap first. VPC isolation, custom subnets, and IAM boundaries are not optional for teams handling sensitive data or working toward SOC 2. PaaS platforms either don&#8217;t support these controls or lock them behind enterprise tiers.</p><h2>Why Engineering Teams Outgrow PaaS</h2><p>The shift rarely happens all at once. It starts with one requirement the platform cannot meet, and then another, until the workarounds cost more time than the platform saves.</p><p>The most common breaking points:</p><h4>Networking constraints</h4><p>PaaS platforms abstract networking entirely. That works until you need VPC peering, private subnets, static IPs, or custom security group rules. Heroku&#8217;s standard plans have no private networking at all. Getting it requires upgrading to Private Spaces, which is an enterprise-only feature with a significant price jump. Teams building B2B products that need to connect to customer VPCs hit this wall early.</p><h4>Compliance requirements</h4><p>SOC 2, HIPAA, and similar frameworks require infrastructure isolation, audit trails, and control over where data is processed and stored. Standard PaaS tiers run on shared infrastructure. You cannot tell an auditor exactly where your data lives or demonstrate VPC-level isolation on a shared runtime. Heroku&#8217;s HIPAA-compliant offering requires Shield Private Spaces, available only on enterprise plans.</p><h4>Multi-service complexity</h4><p>PaaS works well for a single application. At 10 or more services, environment management becomes a problem. Keeping dev, staging, and production environments consistent across services, managing shared dependencies, and coordinating deployments across a growing codebase is difficult on a platform that treats each application as an independent unit.</p><h4>Observability gaps</h4><p>Most PaaS platforms give you application logs and basic CPU and memory metrics. That is enough for simple workloads. It is not enough when you need distributed tracing, custom metrics, or correlated logs across services. TRM Labs, running on Render, had to build a custom log ingestion pipeline with OTEL Collectors just to get logs into their observability stack because Render&#8217;s log drains support only a single destination.</p><h3>The Real Cost Difference Between PaaS and an IDP</h3><p>A typical small production app on Heroku runs two Standard dynos at $50 per month, a<a href="https://www.heroku.com/pricing"> Postgres Standard-0 plan at $50 per month</a>, Redis Mini at $15 per month, and basic monitoring add-ons at $15 to $30 per month. That puts you at $130 to $160 per month for a minimal setup. Postgres plans escalate quickly in practice &#8212; Standard-2 runs $200 per month, and most production workloads land somewhere in between. Add-ons stack faster than teams expect.</p><p>The same setup on AWS sits closer to $130 to $220 per month depending on usage. Two t3.medium instances run around $60 per month on-demand. RDS for a production database with storage and automated backups is realistically $50 to $150 per month, not $30. An Application Load Balancer starts at $20 per month but increases with traffic.<a href="https://northflank.com/blog/heroku-vs-aws"> AWS can be 30 to 70% cheaper than Heroku depending on scale and usage patterns</a> &#8212; the gap is smaller at low scale and wider as you add services.</p><p>Here is how the numbers compare across a typical mid-size production setup:</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/loXs9/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1e5e27ee-8f5e-413b-92ca-d7660371a44d_1220x1002.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/255ac3fa-83d9-42e5-9318-f7084e76e540_1220x1002.png&quot;,&quot;height&quot;:500,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/loXs9/1/" width="730" height="500" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>The savings are real, but the more honest case for moving to an IDP is not just compute cost. It is what you cannot get on PaaS at any price point: VPC isolation, custom networking, compliance controls, and infrastructure you actually own.</p><p>The other cost CTOs consistently underestimate is what it takes to build an IDP from scratch. Self-hosting Backstage requires 3 to 5 dedicated engineers to manage infrastructure, handle upgrades, and maintain the codebase, according to Roadie&#8217;s survey of the Backstage community. Some organisations staff teams of 12 people just for Backstage.<a href="https://roadie.io/blog/7-best-developer-portals-for-enterprise-engineering-teams"> Total cost of ownership for a self-hosted Backstage installation can exceed $1 million per year</a> in operational overhead at scale.</p><p>That is the real trade-off. PaaS removes upfront infrastructure cost but adds a compute premium that compounds with scale. Building your own IDP removes the compute premium but adds significant engineering overhead. Managed IDPs sit in between: raw cloud compute pricing, without the internal build cost.</p><p>For teams under 10 engineers with a straightforward stack, PaaS is still the cheaper option when you factor in engineering time. The math shifts once you are scaling services, handling sensitive data, or selling to enterprise customers.</p><h3>When Teams Move from PaaS to an Internal Developer Platform</h3><p>The decision to move off PaaS rarely comes from a single problem. It usually builds up over several months, one workaround here, one missing feature there, until the cost of staying outweighs the cost of switching.</p><p>Two cases illustrate how this plays out in practice.</p><p><strong><a href="https://www.algolia.com/blog/engineering/challenging-migration-heroku-google-kubernetes-engine">Algolia</a></strong> was running on Heroku when an enterprise customer required crawling from a fixed IP address for firewall whitelisting. Standard Heroku does not support static outbound IPs. The alternative was Heroku Private Spaces, an enterprise-only tier that came with a significant price increase for a single networking requirement. The team moved to Kubernetes instead. One infrastructure gap triggered a full platform migration.</p><p><strong><a href="https://www.checklyhq.com/blog/heroku-to-aws-migration/">Checkly</a></strong> had been on Heroku since 2016. By 2022 the platform had become a recurring operational burden. Upgrading PostgreSQL versions required Heroku support involvement. Disk size plans were fixed, requiring a full plan upgrade just for storage. Essential database tasks needed senior engineer involvement every time. Moving to AWS resolved all three issues and reduced the dependency on senior engineers for routine maintenance.</p><p>Both cases point to the same pattern. The trigger is rarely cost alone. It is cost combined with a capability the platform cannot provide: networking control, compliance requirements, enterprise customer demands, or operational flexibility.</p><p>If any of this sounds familiar, you are likely already in the transition phase, not approaching it.</p><p>The common signals that indicate a team is ready to move:</p><ul><li><p>Running multiple services, often 10 or more, with inconsistent environment configurations across dev, staging, and production</p></li><li><p>Hitting networking constraints that require workarounds or enterprise tier upgrades</p></li><li><p>Facing a compliance audit that requires VPC isolation or audit trails</p></li><li><p>Selling to enterprise customers who require dedicated infrastructure or BYOC deployments</p></li><li><p>Spending a significant portion of engineering time, often 20% or more, on deployment tooling and infrastructure maintenance</p></li><li><p>Onboarding new engineers taking longer than expected due to infrastructure complexity</p></li></ul><p>When several of these apply at the same time, teams are usually closer to needing a shift than they realize.</p><p>If your team is currently on Heroku and evaluating the move to AWS,<a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp"> this migration guide</a> covers the exact steps involved.</p><h4>The BYOC Problem</h4><p>Spinning Up Dedicated Infrastructure for Every Enterprise Customer</p><p>For teams selling to enterprise customers, PaaS creates a specific problem. Enterprise deals often require dedicated infrastructure inside the customer&#8217;s own cloud account. On a standard PaaS, that is not possible. On a shared runtime, there is no path to VPC isolation per customer, no way to provision inside a customer&#8217;s AWS account, and no mechanism for the customer to maintain control over their own data residency.</p><p>SuprSend, a notification infrastructure company, ran into this directly. Every new enterprise deal required spinning up dedicated infrastructure manually. The engineering team was spending significant time on per-customer setup that had nothing to do with the product. Using an IDP, they provisioned per-customer AWS environments in under 30 minutes using the same git-push workflow their engineers already used. The operational overhead that previously blocked enterprise deals was removed without changing how the engineering team worked.<strong> <a href="https://localops.co/case-study/suprsend-unlocks-enterprise-revenue-byoc?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">Read the case study here</a></strong></p><h3>Should You Build Your Own IDP or Buy One?</h3><p>Once a team decides to move toward an IDP, the next question is whether to build it internally or use an existing platform. Both are valid paths. The right answer depends on your team size, engineering capacity, and how much time you can spend on platform work versus product work.</p><h4>Building in-house</h4><p>Gives you full control. You can design golden paths around your exact stack, integrate with internal tooling, and own every layer of the platform.</p><p>The most common starting point for teams figuring out how to build an internal developer platform is Backstage, the open source internal developer platform originally built by Spotify and now a CNCF project. Self-hosting the Backstage internal developer platform requires 3 to 5 dedicated engineers to manage infrastructure, handle upgrades, and maintain the codebase, according to Roadie&#8217;s survey of the Backstage community. Getting a usable instance into production typically takes 6 to 12 months. Total cost of ownership can exceed $1 million per year at scale.</p><p>Building from scratch makes sense in specific cases:</p><ul><li><p>Compliance requirements so unusual that no managed platform can meet them</p></li><li><p>Multi-cloud or hybrid infrastructure with complex dependency graphs</p></li><li><p>Regulatory constraints that prevent sending any metadata to a third-party vendor</p></li></ul><p>Outside these cases, a full DIY build adds significant overhead without adding proportional value, even for teams with dedicated platform engineering capacity. The time spent maintaining platform infrastructure is time not spent on the actual developer experience improvements that make an IDP worth having.</p><h4>Buying a managed IDP</h4><p>The best internal developer platforms handle infrastructure provisioning, observability, CI/CD wiring, and environment management out of the box, running entirely inside your own AWS account. Engineers get a self-service path to deploy services without touching Terraform or Helm. The platform team sets guardrails once. Every developer benefits from them without needing to understand what is running underneath.</p><p>This approach makes sense when:</p><ul><li><p>Your engineering team&#8217;s time is better spent on product work</p></li><li><p>You do not have a dedicated platform team</p></li><li><p>You need production-ready AWS environments quickly without accumulating infrastructure debt</p></li><li><p>You want infrastructure your team controls, without the cost of building the tooling around it</p></li></ul><h4>The hybrid approach</h4><p>This is what most mature platform teams end up adopting, including those with dedicated platform engineering staff. Use a managed IDP as the foundation for environment provisioning, CI/CD, and observability. Build custom tooling only for the parts that are genuinely specific to your organisation, such as internal approval workflows, custom cost allocation logic, or proprietary security controls.</p><p>This keeps the platform team focused on high-value work rather than maintaining infrastructure that already exists elsewhere. The best internal developer platform for most teams is not the one with the most features. It is the one that removes the most friction without creating new kinds of it.</p><p>Not sure which approach fits your team?<a href="https://cal.com/anand-localops/tour"> Book a quick demo</a> and see how LocalOps handles this in practice.</p><h3>FAQs</h3><p><strong>1. Internal Developer Portal vs Platform: What&#8217;s the Difference?</strong></p><p>An internal developer portal is a UI layer that surfaces information about existing infrastructure, service catalogs, documentation, ownership. Backstage is a portal. An internal developer platform provisions and manages cloud resources. It gives developers a self-service path to deploy services, spin up environments, and access observability without filing a ticket. A portal shows you what exists. A platform automates what happens. Most teams searching for the best internal developer platforms end up landing on Backstage first and discovering this distinction only after months of setup.</p><p><strong>2. Do you need a platform engineering team to run an internal developer platform?</strong></p><p>For a DIY IDP built on an open source internal developer platform like Backstage, yes. You need engineers who can maintain the codebase, manage upgrades, and build integrations. Platform engineering and internal developer platform adoption are closely linked in enterprise organisations for this reason. But managed IDPs change the equation. A small team without a dedicated platform function can run a production-grade IDP on AWS if the platform handles provisioning, observability, and CI/CD out of the box. The platform engineering investment shifts from building infrastructure to configuring a platform that already exists.</p><p><strong>3. Can PaaS handle compliance requirements like SOC 2 or HIPAA?</strong></p><p>Standard PaaS tiers cannot. Most run on shared infrastructure without VPC isolation, which is a baseline requirement for SOC 2 and HIPAA audits. Heroku&#8217;s HIPAA-compliant offering requires Shield Private Spaces, an enterprise-only tier with a significant price jump. An AWS internal developer platform provisions dedicated VPCs, private subnets, encrypted volumes, and role-based access controls inside your own account by default. For teams heading toward a compliance audit, this is usually one of the clearest signals that PaaS is no longer the right fit.</p><p><strong>4. At what point does PaaS become more expensive than running on your own cloud?</strong></p><p>It depends on scale, but the gap typically becomes significant around 10 or more services. At that point PaaS compute markups, per-seat charges, and add-on costs add up faster than the raw AWS equivalent. A typical mid-size production setup on Heroku runs $400 to $800 per month. The equivalent setup on AWS via an IDP runs $150 to $350 per month. The internal developer platform architecture on AWS also includes observability, private networking, and compliance controls that would require enterprise PaaS tiers to replicate.</p><p><strong>5. Is an internal developer platform only for large engineering teams?</strong></p><p>No. The common assumption is that IDPs are enterprise tools requiring large platform engineering teams and months of setup. That was true when building one meant assembling Backstage, Argo CD, Terraform, and Prometheus from scratch. Managed IDPs have changed this. A team of 10 engineers on AWS can run a production-grade internal development platform without a dedicated DevOps hire. The shift is less about team size and more about infrastructure complexity. Once you are running multiple services, selling to enterprise customers, or facing compliance requirements, an IDP starts making sense regardless of headcount.</p><h3>Conclusion</h3><p>PaaS is not a bad choice. It is a starting point. For small teams moving fast with a simple stack, it does exactly what it promises. The problems start when your requirements outgrow what the vendor supports, and by the time most teams realize that, they have already spent months working around the limitations.</p><p>An internal developer platform does not replace PaaS simplicity. The best ones preserve it while giving your team infrastructure they actually control. Developers still push code. Environments still spin up automatically. The difference is that the infrastructure runs in your AWS account, compliance controls are built in from the start, and enterprise customers can bring their own cloud without requiring manual setup for every deal.</p><p>The question is not really IDP vs PaaS. It is whether your current platform is still working for you or quietly becoming the ceiling.</p><p>If you are at the point where PaaS is starting to feel like a constraint rather than a convenience, LocalOps is worth looking at. It provisions production-grade AWS environments without Terraform, Helm, or Dockerfiles, and runs entirely inside your own AWS account.</p><p><strong><a href="https://cal.com/anand-localops/tour">Book a Demo</a></strong> &#8212; Walk through how environments, deployments, and AWS infrastructure are handled in practice for your setup.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">Get Started for Free</a></strong> &#8212; Connect an AWS account and stand up an environment to see how it fits into your existing workflow.</p><p><strong><a href="https://docs.localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp">Explore the Docs</a></strong> &#8212; A detailed breakdown of how LocalOps works end-to-end, including architecture, environment setup, security defaults, and where engineering decisions still sit.</p><h3>Suggested Articles</h3><ol><li><p><a href="https://blog.localops.co/p/what-is-an-internal-developer-platform-idp">What Is an Internal Developer Platform (IDP)?</a></p></li><li><p><a href="https://blog.localops.co/p/self-hosted-heroku-alternatives-build-vs-buy">Self-Hosted Heroku Alternatives in 2026: Build vs. Buy</a></p></li><li><p><a href="https://blog.localops.co/p/heroku-alternatives">Heroku Alternatives the Engineering Community Actually Recommends in 2026</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Internal Developer Platforms vs. Heroku: What Changes, What Improves, and What to Expect]]></title><description><![CDATA[What actually changes when you move from Heroku&#8217;s abstraction to an IDP running in your own AWS account]]></description><link>https://blog.localops.co/p/internal-developer-platforms-vs-heroku</link><guid isPermaLink="false">https://blog.localops.co/p/internal-developer-platforms-vs-heroku</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Fri, 17 Apr 2026 10:54:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!p0sc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.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_!p0sc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p0sc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png 424w, https://substackcdn.com/image/fetch/$s_!p0sc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png 848w, https://substackcdn.com/image/fetch/$s_!p0sc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png 1272w, https://substackcdn.com/image/fetch/$s_!p0sc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p0sc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png" width="2400" height="1292" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0384d574-e755-4567-b714-b5aeae024486_2400x1292.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1292,&quot;width&quot;:2400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6572774,&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://blog.localops.co/i/194500476?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8ddc67-07be-4e68-86a9-fa8ee10dd21a_2400x1808.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_!p0sc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png 424w, https://substackcdn.com/image/fetch/$s_!p0sc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png 848w, https://substackcdn.com/image/fetch/$s_!p0sc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.png 1272w, https://substackcdn.com/image/fetch/$s_!p0sc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0384d574-e755-4567-b714-b5aeae024486_2400x1292.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><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> What Internal Developer Platforms (IDPs) are, how they structurally replace Heroku, what changes for developers and platform teams, what improves, and how to evaluate whether an IDP is genuinely production-ready versus only suited to hobbyist workloads.</p><p><strong>Who it is for:</strong> CTOs and VPs of Engineering evaluating Heroku alternatives in 2026, specifically teams that need self-serve infrastructure running on their own AWS account without rebuilding their platform from scratch.</p><p><strong>The conclusion:</strong> Heroku&#8217;s model of abstracting infrastructure entirely worked well at low scale. IDPs replace that model with one that delivers equal developer self-service while giving platform teams the control, compliance, and cost efficiency that enterprise growth demands. The transition is structural, not just a tool swap.</p><blockquote><p><strong>Ready to see what this looks like for your stack?</strong><a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Schedule a free migration call &#8594;</a> Our engineers walk through your current Heroku setup and model the AWS equivalent in under 30 minutes.</p></blockquote><h2><strong>What Is an Internal Developer Platform, and How Does It Replace Heroku?</strong></h2><p>Heroku&#8217;s core promise was infrastructure abstraction: developers deploy applications without thinking about servers, networking, or scaling. That promise was genuinely useful. For teams moving past Heroku, the goal is not to abandon that promise; it is to fulfil it on infrastructure the business actually owns and controls.</p><p>An Internal Developer Platform (IDP) is the architectural layer that makes this possible.</p><p>Structurally, an IDP sits between the developer and the underlying cloud infrastructure. Developers interact with a self-serve interface, environment provisioning, deployments, log access, and scaling controls, without needing to understand what is running underneath. Platform teams interact with the same infrastructure through an operational layer that gives them visibility, compliance controls, audit logs, IAM policies, and network topology they can actually reason about.</p><p><strong>What this looks like in practice for teams replacing Heroku:</strong></p><p>On Heroku, a developer pushes code to a branch. Heroku builds it, deploys it, and manages the underlying compute, database, and networking. The developer never touches AWS. The infrastructure team never controls AWS. Nobody controls AWS.</p><p>On an IDP built on your own AWS account, like LocalOps, a developer pushes code to a branch. The IDP builds it, containerises it, and deploys it to your EKS cluster inside your VPC. The developer experience is identical. The difference is that the infrastructure lives in your AWS account, under IAM policies your team controls, inside a network topology your security team can audit.</p><p>The structural replacement is not about rebuilding Heroku internally. It is about inserting a platform layer that translates developer intent, &#8220;deploy this service&#8221;, into infrastructure operations on AWS that the business controls.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/ga6pg/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6265adce-855c-4666-a86b-1352fc30adf2_1220x868.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d108ac7e-8b7e-465a-bc72-7b2bd8aef741_1220x988.png&quot;,&quot;height&quot;:492,&quot;title&quot;:&quot;Key structural differences between Heroku and an IDP on AWS:&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/ga6pg/1/" width="730" height="492" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>The IDP is what makes this transition work without creating a new bottleneck. Without it, moving off Heroku typically means developers lose self-service entirely, every environment provision, every deployment change, every scaling decision routes through the platform team. That is the bottleneck IDPs are specifically designed to prevent.</p><blockquote><p><strong>Want to see this infrastructure model in action?</strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Get your first AWS environment running in under 30 minutes &#8594;</a> No Terraform. No Helm charts. No credit card required.</p></blockquote><h2><strong>How IDPs Solve the Platform Engineering Bottleneck That Heroku Migrations Create</strong></h2><p>This is the problem that most Heroku migration plans underestimate, and the one that causes migration projects to stall or fail.</p><p>When teams leave Heroku without an IDP layer, the self-serve model does not transfer to AWS by default. AWS is not self-serve for developers. It is a powerful infrastructure platform that requires IAM knowledge, networking concepts, and operational context to use safely. Developers who could deploy independently on Heroku cannot deploy independently on AWS without a platform layer that abstracts those requirements.</p><p>The result is predictable: deployments stop being developer-driven and start routing through whoever owns the Terraform or Helm charts. For product teams with release velocity targets, this is an immediate regression.</p><p><strong>What the bottleneck looks like in practice:</strong></p><p>A developer needs a new staging environment. On Heroku, they fork the app in the UI. Takes three minutes. Post-migration without an IDP, they open a ticket for the platform team, who queue it behind other infrastructure work. Three days later, the environment exists.</p><p>A backend team needs to change the memory allocation for a production service. On Heroku, they adjust the dyno slider. Post-migration without an IDP, they update a Terraform variable, submit a PR, wait for review, and hope nothing else depends on that configuration.</p><p>These are not hypothetical regressions. They are the documented patterns of teams that migrate to AWS without a developer platform layer. The platform engineering team becomes a deployment bottleneck, release velocity drops, and the product organisation quickly starts asking whether the migration was a good idea.</p><p><strong>How an IDP prevents the bottleneck:</strong></p><p>An IDP on AWS maintains the contract that made Heroku useful: developers self-serve for the things they own, platform teams control the things the business needs to govern.</p><p>Concretely, this means:</p><ul><li><p><strong>Environment provisioning remains developer-driven.</strong> Developers create environments through the IDP interface without filing tickets. The IDP translates that into VPC, EKS namespace, and IAM resource creation in your AWS account.</p></li><li><p><strong>Deployments remain branch-triggered.</strong> Push to main. The IDP builds, containerises, and deploys. Developers do not write Kubernetes YAML.</p></li><li><p><strong>Scaling adjustments remain self-serve.</strong> Developers adjust replicas or resource limits through the platform interface. Platform teams set the guardrails.</p></li><li><p><strong>Platform teams retain governance without becoming a bottleneck.</strong> They define policies, which instance types are available, what resource limits apply, which secret scopes exist, and the IDP enforces them automatically.</p></li></ul><p>The IDP is the mechanism that makes &#8220;we moved to AWS&#8221; and &#8220;developers are still unblocked&#8221; simultaneously true. Without it, one of those statements is usually false.</p><blockquote><p><strong>See how LocalOps keeps developer self-service intact on AWS.</strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Talk to an engineer about your migration &#8594;</a> We&#8217;ve helped teams move off Heroku without losing a single day of deployment velocity.</p></blockquote><h2><strong>What Native Capabilities Does a Platform Need Before It&#8217;s a Viable Heroku Replacement?</strong></h2><p>This is the evaluation question that separates production-ready IDPs from tools that work well in demos and break under real workloads.</p><p>Heroku at its best provides a complete operational surface: deployment, scaling, database management, secrets, logs, and basic metrics out of the box. A platform that replaces Heroku needs to match that surface on all dimensions before it can be trusted with production workloads. Teams that migrate to platforms with capability gaps discover those gaps at the worst possible times: during incidents, during audits, and during the security reviews of enterprise deals.</p><h3><strong>CI/CD That Developers Don&#8217;t Have to Configure</strong></h3><p>Heroku&#8217;s git-push deploy model is one of its most underrated capabilities. Developers who have never written a CI pipeline can still ship code. A Heroku replacement needs to match this for the teams that currently rely on it.</p><p>What this means in practice: the platform should build Docker images from source, push to a registry, and deploy to the target environment automatically on branch push. Developers should not be required to write Dockerfiles, configure GitHub Actions workflows, or manage pipeline YAML as a prerequisite to deploying. Those capabilities should exist for teams that want them, but they should not be required for basic deployments.</p><p>Platforms that require significant CI/CD configuration before the first deployment are not Heroku replacements. They are infrastructure platforms that require a platform engineering layer to be usable, which recreates the bottleneck IDPs are supposed to solve.</p><h3><strong>Observability That Is Included, Not Assembled</strong></h3><p>A critical capability gap in most Heroku alternatives is observability. Heroku&#8217;s native observability is weak: log drains exist, basic metrics are available, but production observability requires assembling Papertrail, New Relic, and additional monitoring tools at significant additional cost.</p><p>The failure mode in most alternatives is that they replace Heroku&#8217;s weak observability with no observability at all. Teams migrate, get to production, and realise they have no log aggregation, no application metrics, and no dashboards. Setting up Prometheus, Loki, and Grafana on Kubernetes correctly is meaningful infrastructure work, not something a product team should absorb mid-migration.</p><p>A production-ready IDP includes integrated observability as part of the platform, not as an optional add-on configuration step. Metrics collection from all services, log aggregation from standard output, and dashboards showing infrastructure and application health should be available from day one without additional configuration.</p><p>LocalOps includes Prometheus, Loki, and Grafana pre-configured in every environment at no additional cost. The observability stack that costs hundreds of dollars per month in Heroku add-ons is part of the infrastructure.</p><blockquote><p><strong>Stop paying $400&#8211;$900/month for Heroku monitoring add-ons.</strong><a href="https://docs.localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> See how built-in observability works on LocalOps &#8594;</a> Prometheus, Loki, and Grafana. Included. No configuration required.</p></blockquote><h3><strong>Autoscaling That Matches Real Workload Patterns</strong></h3><p>Heroku&#8217;s scaling model, manual dyno count adjustments with limited automatic response to traffic, is one of the concrete limitations that drives teams to evaluate alternatives.</p><p>A production-ready IDP should provide:</p><ul><li><p><strong>Horizontal Pod Autoscaler (HPA) by default.</strong> Services should scale out when CPU or memory pressure rises and scale back when it drops. No manual intervention. No scheduled scaling windows.</p></li><li><p><strong>Scale to zero for non-production environments.</strong> Staging and development environments should not run at full capacity continuously. Scale-to-zero reduces cost and eliminates the &#8220;why is my staging environment billed like production&#8221; problem.</p></li><li><p><strong>No tier-jump cost model.</strong> Autoscaling on Kubernetes scales proportionally to actual load. Teams are not forced to jump to the next compute tier when they cross an arbitrary threshold.</p></li></ul><h3><strong>Secrets Management That Doesn&#8217;t Create Compliance Exposure</strong></h3><p>Heroku&#8217;s config vars model works at low scale. At production scale with enterprise customers, it creates compliance problems: secrets are visible in the Heroku dashboard to anyone with platform access, there is no audit log of who accessed or modified which secrets, and there is no integration with enterprise identity providers for access control.</p><p>A production-ready Heroku alternative needs a secrets management story that satisfies enterprise security questionnaires:</p><ul><li><p>Secrets stored in a managed secrets service (AWS Secrets Manager or equivalent), not in environment variable stores</p></li><li><p>Audit logs of secret access and modification</p></li><li><p>IAM-based access control that scopes secret access per service, not per team</p></li><li><p>No plaintext secrets in deployment configurations or CI/CD logs</p></li></ul><p>Platforms that handle secrets by surfacing them in a dashboard with no audit log are not production-ready for B2B SaaS teams with enterprise customers. This capability gap shows up in security reviews and cost deals.</p><h3><strong>Networking Primitives That Enterprise Customers Require</strong></h3><p>Heroku applications share Heroku&#8217;s network. There is no VPC isolation. There is no private networking between services. There is no data residency control.</p><p>For most B2B SaaS teams, this becomes a deal-blocking problem when enterprise procurement asks about network isolation. A production-ready IDP should provide:</p><ul><li><p>Dedicated VPC per environment</p></li><li><p>Private service-to-service networking (services communicate on private IPs, not through public endpoints)</p></li><li><p>Security group controls that restrict inbound access to application ports</p></li><li><p>Region control for data residency requirements</p></li></ul><blockquote><p><strong>Does your current Heroku setup pass the enterprise security questionnaire?</strong><a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Talk to our team about compliance-ready AWS infrastructure &#8594;</a> VPC isolation, IAM controls, and audit logging &#8212; included from day one, not as an enterprise add-on.</p></blockquote><h2><strong>How to Evaluate Whether a Heroku Alternative Is Genuinely Production-Ready</strong></h2><p>The gap between &#8220;works for early-stage projects&#8221; and &#8220;production-ready for a $10M ARR SaaS company&#8221; is significant and not obvious from documentation or demos.</p><p>Most Heroku alternatives look capable in the setup experience. The differentiation surfaces under three conditions: high-concurrency production traffic, compliance review, and late-night incidents.</p><h3><strong>Test 1: Zero-to-Production Without Platform Engineering Involvement</strong></h3><p>Run the self-serve path end to end. Can a developer who has never used your AWS account go from a git repository to running a production service without filing a ticket, writing Kubernetes YAML, or getting help from a platform engineer?</p><p>If the answer is no, the platform is not a Heroku replacement. It is an infrastructure platform that requires a platform layer to be usable. The missing platform layer is the product you will end up building internally, which is the outcome IDPs are supposed to prevent.</p><h3><strong>Test 2: The Incident Simulation at 2 AM</strong></h3><p>Simulate a production incident. A service is returning 500 errors. How long does it take to identify the root cause using only the tools the platform provides?</p><p>On a platform with integrated observability, this means: open the metrics dashboard, identify the service with the elevated error rate, switch to the logs view for that service filtered to the incident timeframe, and identify the error pattern. Three to five minutes.</p><p>On a platform that requires assembling Papertrail and New Relic, this means: open Papertrail, filter to the relevant service, open New Relic, correlate the timeline, and cross-reference the timestamps. Context switching between tools adds minutes to every incident. At 2 AM, under pressure, those minutes matter.</p><h3><strong>Test 3: The Enterprise Security Questionnaire</strong></h3><p>Get a copy of a standard enterprise security questionnaire; any vendor security questionnaire from a Fortune 500 procurement team will do. Go through it against the platform you are evaluating.</p><p>Can you honestly answer yes to: dedicated VPC, private service networking, IAM-based access control, audit logs for secrets access, data residency in a specified region, and SOC 2 compliance evidence?</p><p>If the answers are no, the platform will block enterprise deals. The question is not whether this matters. It is when some teams discover this on the first significant enterprise opportunity; others discover it when a large existing customer expands their security review program.</p><h3><strong>Test 4: Cost at Scale, Not Cost at Launch</strong></h3><p>Many platforms price attractively for small workloads and scale badly. The cost model to evaluate is not the starting price; it is the cost for a five-service production stack with staging environments, observability, and managed databases.</p><p>On Heroku, this stack costs $800&#8211;$1,500/month at conservative estimates, excluding APM add-ons. On AWS via LocalOps, the same stack runs at AWS list pricing with no platform margin, typically $200&#8211;$500/month for the infrastructure, plus the LocalOps platform fee.</p><p>Evaluate the model, not the number: does cost scale proportionally with actual usage, or does it jump at tier boundaries that bear no relationship to your actual workload? Platforms that inherit Heroku&#8217;s tier-based cost model are not solving the cost problem; they are replicating it.</p><blockquote><p><strong>Want to model what your Heroku stack costs on LocalOps + AWS?</strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Get a cost comparison for your specific setup &#8594;</a> Our engineers calculate the infrastructure cost and add-on savings side by side &#8212; no guesswork.</p></blockquote><h3><strong>Test 5: What Happens When You Leave</strong></h3><p>Ask every platform vendor the same question: if we stop using your platform, what does our infrastructure look like?</p><p>For platforms that own your infrastructure, where the resources are in the vendor&#8217;s cloud account, the answer is that you need to migrate again. Your team has built operational familiarity with a platform that disappears along with its vendor relationship.</p><p>For platforms like LocalOps that run in your AWS account, the answer is that your infrastructure keeps running. The EKS cluster, the VPC, the databases, the observability stack, all of it continues operating in your account. You are not locked to the platform layer; you are locked to AWS, which is a much safer dependency.</p><h2><strong>What Changes When You Move From Heroku to an IDP</strong></h2><p>For developers, the daily experience changes less than teams expect. Push to branch, service deploys, logs are available, metrics are visible. The most common developer response to the transition is that things work the same, and then they notice the observability is better.</p><p>For platform teams, the change is significant and positive. Instead of managing Heroku add-ons and filing support tickets for infrastructure questions, they configure policies and controls in a platform that runs on infrastructure they own. They gain the visibility and governance that enterprise customers require without losing the developer self-service model that keeps product teams unblocked.</p><p>For the business, the change is structural. Infrastructure that once sat in Heroku&#8217;s cloud now runs in the company&#8217;s AWS account. Security questionnaires that were previously impossible to answer honestly become straightforward. Enterprise deals that previously stalled on infrastructure compliance can close. Cost structures that grew faster than revenue on Heroku scale proportionally to actual usage on AWS.</p><blockquote><p><strong>See what the first 90 days after a Heroku migration look like.</strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Read the LocalOps migration guide &#8594;</a> Full walkthrough: database migration, environment setup, DNS cutover, and what to expect at each stage.</p></blockquote><h2><strong>How LocalOps Delivers This in Practice</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform built for teams, replacing Heroku. It is designed specifically to maintain the developer self-service model while moving infrastructure to a customer-owned AWS account.</p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and a complete observability stack, Prometheus, Loki, and Grafana, automatically. No Terraform. No Helm charts. No manual configuration. First environment ready in under 30 minutes.</p><p>From that point, the developer experience is identical to Heroku. Push to your configured branch. LocalOps builds, containerises, and deploys to AWS automatically. Logs and metrics are available from day one. Autoscaling and auto-healing run by default. Secrets management runs through AWS Secrets Manager with audit logging.</p><p>The infrastructure runs in your AWS account. If you stop using LocalOps, it keeps running.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221;</em> <strong>&#8212; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</strong></p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, all of which LocalOps has saved for us.&#8221;</em> <strong>&#8212; Gaurav Verma, CTO and Co-founder, SuprSend</strong></p><p><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Start for free &#8212; first environment on AWS in under 30 minutes &#8594;</a> No credit card required.</p></blockquote><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>What is an Internal Developer Platform, and is it the same as a PaaS like Heroku?</strong></p></li></ol><p>An Internal Developer Platform is a layer that sits between developers and cloud infrastructure, providing self-serve capabilities for environment management, deployments, scaling, and observability. Like Heroku, it abstracts infrastructure complexity from developers. Unlike Heroku, it runs on infrastructure the business owns, typically in the company&#8217;s AWS account, and gives platform and security teams the visibility and controls that hosted PaaS platforms like Heroku cannot provide.</p><ol start="2"><li><p><strong>Will developers need to learn Kubernetes or AWS to use an IDP?</strong></p></li></ol><p>No, that is the point. A well-designed IDP abstracts Kubernetes and AWS in the same way Heroku abstracts them. Developers interact with a self-serve interface: deploy, scale, view logs, and manage environment variables. The Kubernetes and AWS operations happen underneath without developer involvement. Teams that require developers to understand Kubernetes to deploy services have not implemented an IDP; they have implemented Kubernetes with a dashboard.</p><ol start="3"><li><p><strong>How does an IDP differ from self-hosted Heroku alternatives like Coolify or Dokku?</strong></p></li></ol><p>Self-hosted alternatives eliminate the platform margin on infrastructure, but they shift the operational burden to the engineering team. The team must provision the host infrastructure, maintain the platform software, manage security patching, and handle on-call response for the platform itself. For teams without dedicated platform engineering capacity, the engineering cost of running a self-hosted alternative consistently exceeds the platform fee of a managed IDP once all hours are included. Managed IDPs like LocalOps provide the same cost efficiency, direct AWS pricing, and no platform margin on infrastructure, without the operational burden of running the platform layer.</p><ol start="4"><li><p><strong>What does the migration from Heroku to an IDP actually involve?</strong></p></li></ol><p>The core migration has three phases. First, environment setup: connecting your AWS account, configuring the IDP, and provisioning the first environment. With LocalOps, this takes under 30 minutes. Second, application migration: containerising applications if they are not already containerised, updating deployment configurations, and migrating managed services (Postgres, Redis). Third, DNS cutover: routing production traffic to the new environment and validating that everything runs as expected. The database migration is typically the most time-intensive step. LocalOps provides a full migration guide covering each phase.</p><ol start="5"><li><p><strong>How do Internal Developer Platforms handle the compliance requirements that Heroku fails to satisfy?</strong></p></li></ol><p>IDPs built on AWS inherit the compliance posture of the AWS infrastructure they run on. VPC isolation is structural; every environment runs in a dedicated VPC in the customer&#8217;s AWS account. IAM-based access control governs who can do what at both the platform and infrastructure levels. Secrets management runs through AWS Secrets Manager with full audit logging. Network topology, access logs, and resource configurations are all auditable through standard AWS tooling. For teams pursuing SOC 2, ISO 27001, or responding to enterprise security questionnaires, the compliance posture of AWS-native infrastructure is fundamentally more defensible than Heroku&#8217;s shared-infrastructure model.</p><ol start="6"><li><p><strong>What should CTOs expect in the first 90 days after migrating from Heroku to an IDP?</strong></p></li></ol><p>The first two weeks are operational: environments are provisioned, applications are containerised and deployed, and the team validates that production behaviour matches expectations. The next four to six weeks surface the improvements: observability is better than it was on Heroku, incident response is faster, and developers start noticing that environment provisioning no longer requires tickets. By 90 days, the cost difference from the AWS infrastructure and eliminated add-ons is visible in the invoices, and the platform team is spending meaningfully less time on deployment and environment management. For B2B SaaS teams, the first enterprise security questionnaire that arrives post-migration is the validation moment, the answers are honest, and the deals can move forward.</p><h2><strong>Key Takeaways</strong></h2><p>Heroku&#8217;s model of complete infrastructure abstraction was a genuine innovation. It lowered the barrier to shipping software significantly for a generation of product teams.</p><p>The reason teams move past it is not that the model was wrong; it is that the model hits structural limits as businesses scale. No control over infrastructure. No compliance posture for enterprise customers. Cost that scales with product complexity rather than with revenue. Observability is assembled from disconnected paid add-ons.</p><p>Internal Developer Platforms are the architecture that replaces this model at scale. They maintain the self-serve developer experience that made Heroku valuable while running on infrastructure that the business controls. Platform teams get the governance and visibility that enterprise growth requires. Developers keep the deployment simplicity that keeps product velocity high. The business gets infrastructure that can answer an enterprise security questionnaire.</p><p><strong>What changes:</strong> where the infrastructure lives (your AWS account, not Heroku&#8217;s), who controls it (your platform team, with guardrails), and what it costs (AWS list pricing, no platform margin, observability included).</p><p><strong>What stays the same:</strong> the developer experience, the self-serve model, and the ability to ship without becoming an infrastructure expert.</p><p><strong>What improves:</strong> observability, compliance posture, cost predictability, autoscaling behaviour, secrets management, and the ability to close enterprise deals that currently stall on infrastructure questions.</p><h2><strong>Get Started</strong></h2><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started for Free &#8594;</a></strong> First production environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call &#8594;</a></strong> Our engineers model your current Heroku costs against LocalOps + AWS and walk through the migration for your specific stack.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Heroku Migration Guide &#8594;</a></strong> Full technical walkthrough: database migration, environment setup, DNS cutover.</p><p><em><strong>Related reading:</strong></em></p><ol><li><p><strong><a href="https://blog.localops.co/p/herokus-hidden-infrastructure-limitations">Heroku&#8217;s Hidden Infrastructure Limitations: What CTOs Only Discover at Scale</a> </strong></p></li><li><p><strong><a href="https://blog.localops.co/p/heroku-alternatives">Heroku Alternatives the Engineering Community Actually Recommends in 2026</a></strong></p></li><li><p><strong><a href="https://blog.localops.co/p/the-real-cost-of-heroku-at-scale">The Real Cost of Heroku at Scale: A Teardown for CTOs Evaluating Alternatives</a></strong></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Golden Path Deployments: Ship Faster Without Managing Kubernetes or Terraform]]></title><description><![CDATA[How an internal developer platform removes infrastructure from the developer's critical path]]></description><link>https://blog.localops.co/p/golden-path-deployments-internal-developer-platform</link><guid isPermaLink="false">https://blog.localops.co/p/golden-path-deployments-internal-developer-platform</guid><dc:creator><![CDATA[Madhushree Sivakumar]]></dc:creator><pubDate>Thu, 16 Apr 2026 12:19:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nE0X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.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_!nE0X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nE0X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png 424w, https://substackcdn.com/image/fetch/$s_!nE0X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png 848w, https://substackcdn.com/image/fetch/$s_!nE0X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png 1272w, https://substackcdn.com/image/fetch/$s_!nE0X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nE0X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png" width="1456" height="1097" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1097,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:&quot;Surreal Desert Landscape.png&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="Surreal Desert Landscape.png" srcset="https://substackcdn.com/image/fetch/$s_!nE0X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png 424w, https://substackcdn.com/image/fetch/$s_!nE0X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png 848w, https://substackcdn.com/image/fetch/$s_!nE0X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.png 1272w, https://substackcdn.com/image/fetch/$s_!nE0X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe34ce636-b2df-493a-8b42-aae432b702d6_2048x1543.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>Setting up infrastructure shouldn&#8217;t take longer than building the feature.</p><p>For engineering teams without a dedicated DevOps function, it often does. Spinning up a new environment means configuring VPCs, provisioning EKS clusters, wiring up monitoring, and writing CI/CD pipelines from scratch. That&#8217;s before a single line of application code gets deployed.</p><p>The concept of a golden path exists to fix this. A golden path is a standardized, pre-paved route from code to production that removes the guesswork from deployment. An internal developer platform is the mechanism that makes it real.</p><p>This post covers what a golden path deployment workflow looks like, how internal developer platforms implement one, and what the right level of abstraction looks like for engineering teams that want to ship faster without taking on unnecessary infrastructure complexity.</p><h3>TL;DR</h3><ul><li><p>A golden path is a standardized, pre-paved route from code to production that removes infrastructure decisions from the developer&#8217;s critical path</p></li><li><p>An internal developer platform is what actually implements it. It provisions environments, automates CI/CD, and handles cloud complexity by default</p></li><li><p>Building a golden path the traditional way (Backstage + Terraform + ArgoCD) requires a dedicated platform team and 6-18 months of build time</p></li><li><p>For teams without a dedicated DevOps function, an IDP gives you the same outcome without assembling it yourself</p></li><li><p>The right IDP doesn&#8217;t just abstract Kubernetes and Terraform. It makes every environment identical, every deployment consistent, and observability available from day one</p></li><li><p>Golden paths are not mandates. The best ones are defaults developers choose because they work</p></li></ul><h3>What Is a Golden Path Deployment Workflow in Platform Engineering?</h3><p>A golden path is a predefined deployment workflow with sensible defaults already configured. Infrastructure provisioned. CI/CD wired. Observability running. The developer pushes code. The platform handles the rest.</p><p>Spotify built the concept because their autonomous team model created a different problem. Teams moved fast but independently. There was no standard way to ship a service. If you wanted to know how deployments worked, you asked whoever had done it most recently and hoped their answer still applied.</p><p>The fix was a supported, opinionated path from code to production. Not a mandate. A default. The path covered scaffolding, environment setup, CI/CD configuration, and monitoring. Teams could go off it when they needed to. Most didn&#8217;t, because the path was faster.</p><p>Netflix built the same idea and called it the <strong>Paved Road</strong>. Different name, same principle: make the right way the easy way.</p><p>What both companies had that most SaaS teams don&#8217;t is a dedicated platform team maintaining those workflows. Golden paths aren&#8217;t a one-time setup. They get versioned, updated, and extended as infrastructure changes. That maintenance work is real and ongoing.</p><div class="pullquote"><p>An internal developer platform is how you operationalize a golden path without doing all of that yourself.</p></div><h3>From Golden Path to IDP: How the Two Connect</h3><p>A golden path describes the preferred developer workflow. In platform engineering, an internal developer platform is the automation, self-service tooling, and integrations that make that workflow the default rather than a document people are expected to remember.</p><h4>How do internally built workflows break?</h4><p>You can define a golden path without an IDP. Document your Terraform module structure. Standardize your CI templates. Put conventions in Confluence and tell every team to follow them. It holds until someone is under deadline pressure and skips a step. Someone else copies that pattern. Six months later you have three different deployment configurations across five services and no clear owner.</p><p>An IDP encodes those decisions into repeatable automation. When a developer connects a GitHub repo and spins up a new environment, the platform provisions a VPC, creates an EKS cluster, configures subnets, deploys Prometheus, Loki, and Grafana, and applies security defaults. The developer doesn&#8217;t make those decisions. The platform already made them.</p><p>That said, IDPs don&#8217;t force uniformity across every service. Mature platforms standardize the baseline and allow explicit variation for different workload types, compliance requirements, or regions. The goal is reducing unmanaged drift, not eliminating all configuration differences.</p><p>To build an internal developer platform this way means maintaining Terraform modules, running ArgoCD, operating the Backstage internal developer platform, and owning every integration point connecting all three.<a href="https://roadie.io/blog/the-true-cost-of-self-hosting-backstage/"> Roadie&#8217;s analysis of self-hosting Backstage</a> puts the minimum team size at 3 dedicated engineers, with salary and overhead alone running around $450,000 annually, and time to something teams would actually use at 6-12 months.</p><p>For a 15-person SaaS team, that&#8217;s a significant operational commitment before a single application gets deployed.</p><h3>How IDP Abstract Cloud Complexity from Application Developers</h3><p>Abstraction in an IDP isn&#8217;t about hiding how infrastructure works. It&#8217;s about removing decisions that don&#8217;t belong in the application developer&#8217;s critical path.</p><p>On a team without an IDP, a developer who needs a new service has to answer questions that have nothing to do with the service itself. Which VPC does this go in? What node group size? How does the CI pipeline get wired? Where do logs ship? Who sets up the IAM role? These are solved problems at the infrastructure level. They shouldn&#8217;t require a decision every time a new service gets created.</p><p>An IDP moves those decisions upstream. The platform team, or in the case of a bought IDP, the vendor, makes those calls once. EKS cluster configuration, VPC topology, subnet layout, observability stack, security group defaults. They get encoded into the environment provisioning layer and applied consistently across every environment.</p><p>For example, when you are deploying on AWS, an internal developer platform handles EKS cluster provisioning, VPC configuration, IAM role setup, and observability wiring. Those are decisions the internal developer platform architecture makes once and applies consistently across every environment.</p><p>What the developer interacts with is a service abstraction. Define the service type: web service, background worker, cron job. Point it at a GitHub repo and branch. The platform builds the container image, deploys it to the cluster, wires up the load balancer, and starts routing traffic. By default, no Dockerfile is required. Teams that need custom build behavior can bring their own container image instead.</p><p>This is the right abstraction level for application developers. They retain full visibility into what&#8217;s running. Logs, metrics, and deployment history are accessible. But the infrastructure layer that doesn&#8217;t change between services is handled by the platform, not re-solved by each team independently.</p><p>The escape hatch matters too. When a team needs something outside the standard baseline, a custom RDS configuration or a specific SQS queue setup, the platform exposes VPC and subnet IDs so teams can extend using their own Terraform or Pulumi scripts without disrupting what the platform already manages.</p><h3>What Is the Right Level of Abstraction in an IDP?</h3><p>Too little abstraction and the IDP is just a thin wrapper around Kubernetes that still requires developers to understand node groups, ingress controllers, and Helm chart structure. Too much and developers lose visibility into what&#8217;s actually running, which makes debugging production incidents harder than it needs to be.</p><p>The right level is where infrastructure decisions that are identical across services get made once by the platform, and decisions that are legitimately different per service stay with the developer.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/eYxCQ/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/217c25c2-d486-498f-a2df-7d830a285b70_1220x1270.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0748619a-8009-46e2-853f-7048e551a4c9_1220x1340.png&quot;,&quot;height&quot;:667,&quot;title&quot;:&quot;What the platform owns vs. what the developer owns&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/eYxCQ/1/" width="730" height="667" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>The line between these two isn&#8217;t fixed. It shifts based on team size, compliance requirements, and how much infrastructure variation a team legitimately needs. A fintech team running in a regulated environment will need more explicit control over networking and access policies than a team running a standard web API.</p><p>What matters is that the boundary is explicit. When developers don&#8217;t know where their responsibility ends and the platform begins, you get both: developers making infrastructure decisions they shouldn&#8217;t have to make, and platform teams fielding support tickets for things that should have been self-service.</p><p>A clear shared responsibility model fixes this. Here&#8217;s<a href="https://docs.localops.co/environment/shared-responsibilities"> how LocalOps defines that boundary</a>.</p><h3>How IDPs Balance Developer Autonomy with Infrastructure Standardization</h3><p>This is where golden paths either work or fall apart. Standardize too hard and developers work around the platform. Give too much freedom and you&#8217;re back to every team running their own infrastructure setup with no consistency across environments.</p><p>The way most IDPs resolve this is through opinionated defaults with explicit escape hatches. The platform makes the common case easy and the uncommon case possible, without making the uncommon case the default.</p><p>In practice this means three things.</p><ol><li><p>The standard path covers the majority of workloads. Web services, background workers, cron jobs, and scheduled tasks all deploy through the same pipeline without any custom configuration. A developer shouldn&#8217;t need to touch infrastructure to ship any of these.</p></li><li><p>When a team has a legitimate reason to go off the golden path, the platform provides extension points rather than hard limits. Exposing VPC and subnet IDs so teams can provision their own RDS instances or SQS queues using Terraform is an example of this. The platform manages what it provisions. The team manages what they add. Both sets of resources sit inside the same network boundary.</p></li><li><p>Role-based access keeps the right people in control of the right things. Not every developer needs production deploy permissions. Not every engineer needs access to infrastructure configuration. The IDP enforces those boundaries without requiring a manual access review every time someone joins the team.</p></li></ol><p>The outcome isn&#8217;t uniformity. It&#8217;s consistency at the infrastructure layer and autonomy at the application layer. Teams make decisions about how their service behaves. The platform makes decisions about how infrastructure gets provisioned and secured. Those two concerns stay separate.</p><h3>What Actually Changes for a Developer When an IDP Implements the Golden Path</h3><p>The easiest way to understand what an IDP delivers is to walk through what a developer actually does differently.</p><p>Without a golden path, spinning up a new service looks like this. The developer checks what the last team did, finds a repo with a vaguely similar setup, copies the Terraform, adjusts the variables, hopes the VPC IDs are still valid, writes a Dockerfile, figures out the CI pipeline configuration, sets up IAM roles, and then manually wires up monitoring after the first deployment. That process takes days. Sometimes weeks. And it produces another slightly different configuration that the next person will copy.</p><p>With an IDP implementing the golden path, the same developer creates a service, select the service type, point it at a GitHub repo and branch. The platform builds the container image without a Dockerfile. The first git push deploys the service. Prometheus is already scraping metrics. Loki is collecting logs. Grafana has a dashboard.</p><blockquote><p> The whole thing takes under 30 seconds.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Nni4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nni4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png 424w, https://substackcdn.com/image/fetch/$s_!Nni4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png 848w, https://substackcdn.com/image/fetch/$s_!Nni4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png 1272w, https://substackcdn.com/image/fetch/$s_!Nni4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nni4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png" width="1436" height="1098" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1098,&quot;width&quot;:1436,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Nni4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png 424w, https://substackcdn.com/image/fetch/$s_!Nni4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png 848w, https://substackcdn.com/image/fetch/$s_!Nni4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.png 1272w, https://substackcdn.com/image/fetch/$s_!Nni4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f83e9bd-268a-4372-bb40-d85ede065702_1436x1098.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>No Kubernetes manifest written. No Terraform module copied and modified. No DevOps engineer pulled into a provisioning task. No staging environment that diverges from production because someone tweaked it manually.</p><p>The developer&#8217;s job is to write application code and push it. The platform&#8217;s job is everything else on the golden path. That separation is what the title of this post is actually about.</p><p>Every team&#8217;s setup is different. If you want to see how this maps to your specific stack, <a href="https://cal.com/anand-localops/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">LocalOps engineers can walk through it with you</a>.</p><h3>How to Standardize Deployments Across Engineering Teams Without Slowing Them Down</h3><p>The standardization problem at scale isn&#8217;t philosophical. It&#8217;s operational. When five teams deploy five different ways, debugging a production incident means understanding five different pipeline configurations before you can even start looking at the application.</p><p>Environment drift is where this compounds. Team A&#8217;s staging environment has a different EKS node group configuration than production because someone changed it manually six months ago and nobody updated the baseline. Team B&#8217;s worker service has a different IAM role structure because it was set up by an engineer who has since left. None of this is visible until something breaks.</p><p>A golden path enforced by the platform eliminates this class of problem. Every environment is provisioned from the same template: dedicated VPC, private and public subnets with consistent CIDR ranges, EKS cluster with the same node configuration, Prometheus and Loki wired to the same Grafana instance. Differences between environments are explicit parameters, instance size, replica count, backup policy, not untracked manual changes.</p><p>Deployment pipelines follow the same principle. One artifact gets built per commit. That artifact gets promoted through environments. The pipeline configuration doesn&#8217;t live in a per-team CI script that diverges over time. It lives in the platform.</p><p>The compounding effect matters too. Every service that follows the golden path is one less snowflake configuration for the next engineer to reverse-engineer. At 5 services that&#8217;s manageable. At 50 it&#8217;s the difference between a team that can debug incidents quickly and one that can&#8217;t.</p><p><a href="https://dora.dev/research/2024/dora-report/">The 2024 DORA State of DevOps report</a> found that best internal developer platforms reduce cognitive load and create standardized paths to production. Teams using mature platforms report faster onboarding and more consistent deployment practices across services.</p><p>SuprSend estimated replicating standardized deployment infrastructure for BYOC in-house would have taken 10 to 12 person-months of engineering effort. This figure is  from CTO Gaurav Verma, but the cost structure is real regardless of the specific number. <a href="https://localops.co/case-study/suprsend-unlocks-enterprise-revenue-byoc?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Read the full case study.</a></p><h3>How the Golden Path Handles Day Two Operations</h3><p>Most golden path content stops at first deployment. The service is running. The pipeline works. That&#8217;s where the documentation ends.</p><p>Day two is where things get real. A service starts returning HTTP 500s at 2am. A background worker is consuming more memory than the node can handle. A deployment goes out and latency spikes. Someone needs to roll back but isn&#8217;t sure which commit to target.</p><p>Without a golden path, each of these scenarios requires a different investigation path depending on how that service was deployed and by whom. With a golden path enforced by the platform, the answer is always in the same place.</p><p>Logs are in Loki. Metrics are in Prometheus. Both are accessible from the same Grafana dashboard that every environment gets by default. The on-call engineer doesn&#8217;t need to know which team built the service or how they set up monitoring. The observability stack is identical across every environment because the platform provisioned it the same way every time.</p><p>Rollbacks follow the same principle. Every deployment is triggered by a git commit. Rolling back means redeploying a previous commit from the same pipeline. No custom rollback scripts. No manual kubectl commands. The same path that deployed the service is the path that rolls it back.</p><p>Scaling is handled at the platform layer too. Auto-scaling is configured by default. The developer sets resource limits and replica counts as service parameters. The platform manages the rest.</p><p>Day two operations are where the golden path pays back the most. The initial deployment is a one-time event. Debugging, scaling, and rolling back happen repeatedly. A platform that makes those operations consistent across every service is worth more than one that just makes the first deploy fast.</p><h3>Golden Path: Build It Yourself vs Let the IDP Handle It</h3><p>Here&#8217;s what implementing a golden path looks like across both approaches:</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/qUOJf/2/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43db42e0-1463-414c-875d-b0f822c0292d_1220x1024.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a92baba5-783b-4375-8e2e-8ee402e00f24_1220x1094.png&quot;,&quot;height&quot;:513,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/qUOJf/2/" width="730" height="513" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>Even at 150+ engineers, the answer isn&#8217;t necessarily to build everything. The practical approach is to buy the infrastructure layer, environment provisioning, CI/CD, observability, security defaults, and build on top of it for the parts that are genuinely specific to your organization. Custom compliance workflows, internal service catalogs, bespoke access policies. The IDP handles the golden path baseline. Your platform team owns what sits above it. That split lets a growing engineering org add platform capability incrementally without starting from zero on infrastructure every time the team scales.</p><h3>FAQs</h3><p><strong>1. What is the difference between an internal developer portal vs platform in a golden path setup?</strong></p><p>A portal is a UI. It surfaces a service catalog, documentation, and self-service actions. Backstage is the most common example. A platform is the infrastructure layer underneath: environment provisioning, CI/CD, access control, observability. In a golden path context, the portal is how developers interact with the path. The platform is what runs it. A portal without a platform gives developers a nice interface to request things that still take two weeks to get. The platform is what makes the golden path execute automatically.</p><p><strong>2. How does an open source internal developer platform like Backstage compare to an IDP for golden path delivery?</strong></p><p>Backstage doesn&#8217;t provision infrastructure. It doesn&#8217;t manage EKS clusters, configure VPCs, or wire up Prometheus. It gives you a service catalog and a scaffolding framework. To get a working golden path out of Backstage, you still need Terraform for infrastructure, ArgoCD for deployments, and a monitoring stack. Then you need engineers to maintain all three plus the integration layer connecting them. A purpose-built IDP ships all of that as one product. The golden path is the default behavior, not something you assemble. Build time with Backstage: 6-12 months minimum. With an IDP: under 30 minutes for a production-grade environment.</p><p><strong>3. What is the difference between a golden path and a CI/CD pipeline?</strong></p><p>A CI/CD pipeline handles build and deployment automation for a single service. A golden path covers the full journey: environment provisioning, infrastructure configuration, CI/CD setup, observability, and security defaults. The pipeline gets code deployed. The golden path ensures everything around that deployment is consistent and repeatable across every service and team.</p><p><strong>4. Does using an IDP mean you lose control over your infrastructure?</strong></p><p>No. A well-designed IDP makes the boundary explicit. The platform owns what it provisions: the VPC, the cluster, the observability stack, the security defaults. The team owns everything built on top of it. Most IDPs expose extension points, VPC IDs, subnet IDs, environment tags, so teams can provision additional resources using their own Terraform or Pulumi scripts inside the same network boundary. The platform manages its layer. The team manages theirs. What you give up is the need to make the same infrastructure decisions repeatedly. What you keep is full visibility and control over your application layer and any custom infrastructure your team adds.</p><p><strong>5. When does an engineering team need a golden path and an internal developer platform to support it?</strong></p><p>Three signals. Deployments are inconsistent across services and debugging a production incident means reverse-engineering someone else&#8217;s pipeline before you can even look at the application. New engineers take two weeks to ship their first change because there&#8217;s no documented, working path from code to production. Infrastructure setup is gated on one or two people and every new service requires a coordination round before it can deploy. Any one of these means the team is operating without a golden path. An IDP is how you implement one without a 6-12 month platform build first.</p><h3>Conclusion</h3><p>The golden path concept is simple. Make the right way the easy way. The hard part is implementation.</p><p>For large engineering organizations with dedicated platform teams, building a golden path in-house is a reasonable investment. They have the headcount, the runway, and the complexity that justifies it. For everyone else, assembling Backstage, Terraform, ArgoCD, and a monitoring stack and maintaining the integration layer between them is a significant engineering commitment that compounds over time.</p><p>The more useful question for most engineering leaders isn&#8217;t whether to have a golden path. It&#8217;s whether to build the platform that delivers it or use one that already does.</p><p>An IDP doesn&#8217;t replace engineering judgment. It removes the infrastructure decisions that don&#8217;t require it. VPC configuration, EKS provisioning, CI/CD pipeline setup, and observability wiring are solved problems. They shouldn&#8217;t consume engineering cycles on every new service or environment.</p><p>The teams that ship fastest aren&#8217;t the ones with the most DevOps expertise distributed across every developer. They&#8217;re the ones that encoded that expertise into a platform and got their developers back to writing business code.</p><p>If your team is spending more time on infrastructure setup than on the product itself, that&#8217;s the signal. A golden path won&#8217;t write your code. But it will stop infrastructure from being the reason it doesn&#8217;t ship.</p><p>If you&#8217;re figuring out how this would fit into your setup, then LocalOps team can help you work through it:</p><p><a href="https://go.localops.co/tour">Book a Demo</a> - Walk through how environments, deployments, and AWS infrastructure are handled in practice for your setup.</p><p><a href="https://console.localops.co/signup">Get started for free</a> - Connect an AWS account and stand up an environment to see how it fits into your existing workflow.</p><p><a href="https://docs.localops.co/">Explore the Docs</a> - A detailed breakdown of how LocalOps works end-to-end, including architecture, environment setup, security defaults, and where engineering decisions still sit.</p><h3>Related Articles</h3><ol><li><p><a href="https://blog.localops.co/p/how-to-scale-saas-engineering-team-without-hiring-more-devops">How Internal Developer Platforms Help a Growing SaaS Engineering Team Scale Without Hiring More</a></p></li><li><p><a href="https://blog.localops.co/p/internal-developer-platform-build-vs-buy-cost-comparison">How Much Does It Cost to Build an Internal Developer Platform In-House vs Buying One?</a></p></li><li><p><a href="https://blog.localops.co/p/how-to-deploy-to-aws-without-a-devops-engineer">How to Deploy to AWS Without a Dedicated DevOps Engineer</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Heroku's Hidden Infrastructure Limitations: What CTOs Only Discover at Scale]]></title><description><![CDATA[No VPC. No real compliance. Manual scaling. Here&#8217;s what breaks on Heroku when your company starts growing.]]></description><link>https://blog.localops.co/p/herokus-hidden-infrastructure-limitations</link><guid isPermaLink="false">https://blog.localops.co/p/herokus-hidden-infrastructure-limitations</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Thu, 16 Apr 2026 05:20:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!o7hp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.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_!o7hp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!o7hp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png 424w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png 848w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png 1272w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!o7hp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png" width="2324" height="1869" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1869,&quot;width&quot;:2324,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8064601,&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://blog.localops.co/i/194372835?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff003b2a5-aa46-45d6-b1ee-9a8cd184b269_2324x2400.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_!o7hp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png 424w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png 848w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.png 1272w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39232f0d-0d2e-4ad9-b31c-c295ef0f1ad7_2324x1869.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>Heroku&#8217;s infrastructure limitations are not hidden in the sense that Heroku conceals them. They are hidden in the sense that they are invisible until a specific trigger surfaces them, a failed enterprise deal, a compliance audit, a scaling incident, or an architecture decision that gets made differently because of what Heroku cannot support.</p><p>By the time these limitations become visible, they are no longer theoretical. They are active constraints shaping product decisions, blocking revenue, and accumulating technical debt. The CTO who discovers Heroku&#8217;s compliance ceiling during a live enterprise deal is not making a calm architectural decision; they are managing a crisis that adequate lead time would have prevented.</p><p>This guide covers the five infrastructure limitations that Heroku does not surface until scale, what each one costs when it surfaces, and what the AWS-native architecture that replaces Heroku actually looks like.</p><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> Heroku&#8217;s five hidden infrastructure limitations, VPC isolation, SOC 2 and HIPAA compliance risks, access control and audit logging gaps, stateful workload limitations, and dyno scaling failures and the AWS-native alternatives that solve each structurally</p><p><strong>Who it is for:</strong> CTOs and engineering leaders who are on Heroku, approaching Series A or beyond, and want to understand the infrastructure constraints before they surface as crises</p><p><strong>The pattern:</strong> Every limitation on this list is invisible at the small scale and becomes a strategic constraint at the growth stage. The teams that navigate this well discover the constraints before they become urgent.</p><p><strong>Want to see what your infrastructure looks like on AWS without these limitations?</strong><a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Speak with the LocalOps team &#8594;</a></p><h2><strong>Limitation 1: No VPC Isolation, No Private Networking, No Infrastructure You Control</strong></h2><p>Heroku&#8217;s networking model is simple by design: your application runs on Heroku&#8217;s shared infrastructure and communicates with the outside world over the public internet. There is no VPC. There is no private subnet configuration. There is no IAM-based access control at the network layer. Your application, your database, and your cache all communicate over public endpoints, secured at the application layer with credentials, but not isolated at the network layer.</p><p>For early-stage applications, this model is acceptable. The operational simplicity it provides is genuine and valuable. The limitations become visible when two things happen: the team starts selling to enterprise customers and its architecture begins to evolve toward inter-service communication.</p><p>Enterprise procurement processes require infrastructure controls that Heroku&#8217;s networking model cannot provide. VPC configuration, private subnets between services, network isolation between environments, and the ability to describe your infrastructure&#8217;s security posture in a vendor security review- none of these are possible on Heroku because the infrastructure is not yours to configure.</p><p>The architecture problem surfaces separately. As applications decompose into microservices, the services need to communicate with each other. On Heroku, all inter-service communication traverses the public internet. There is no private DNS. There is no service mesh. Services communicate through public endpoints with application-layer security. For architectures where internal services should never be publicly accessible, Heroku&#8217;s networking model is a fundamental mismatch.</p><p><strong>What AWS-native alternatives provide:</strong></p><p>Moving to AWS via an Internal Developer Platform like LocalOps automatically provisions a dedicated VPC for every environment. Private subnets separate application tiers. Security groups control traffic flow between services at the network layer. Services communicate over private IP addresses, never over the public internet. IAM roles govern access to every AWS resource with least-privilege policies applied automatically.</p><p>From the first deployment, the network architecture around which enterprise security questionnaires are built is in place. VPC configuration, private networking, and network isolation between environments are defaults, not configuration projects.</p><p>Every environment LocalOps provisions follows<a href="https://aws.amazon.com/architecture/well-architected"> AWS Well-Architected standards</a> by default, with private subnets, security group rules, and network ACLs applied automatically without manual configuration.</p><p><a href="https://localops.co/features/secure-by-default?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles network security by default &#8594;</a></p><h2><strong>Limitation 2: Heroku cannot support HIPAA or SOC 2 Workloads, and Most Teams Discover This During an Enterprise Deal</strong></h2><p>This is the limitation with the highest business cost, and the one that surfaces at the worst possible moment.</p><p>Heroku offers a Heroku Shield product for teams with compliance requirements, but even with Shield, the fundamental constraint remains: your infrastructure runs on Heroku&#8217;s systems. Your compliance posture is bound by what Heroku chooses to certify and support. When an enterprise security questionnaire asks about infrastructure ownership, data residency, VPC configuration, or audit logging, the honest answer on Heroku is that the team does not control those things.</p><p>For B2B SaaS teams selling to healthcare organizations, financial institutions, or any enterprise with a structured security review process, this constraint is not a technical inconvenience. It is a revenue blocker.</p><p><strong>HIPAA compliance on Heroku:</strong> HIPAA requires administrative, physical, and technical safeguards around protected health information. The technical safeguards include access controls, audit logging, data integrity mechanisms, and transmission security. On Heroku, the infrastructure implementing these safeguards is Heroku&#8217;s, not the team&#8217;s. A Business Associate Agreement with Heroku provides some coverage, but the team cannot independently audit, configure, or demonstrate control over the infrastructure handling PHI. Enterprise healthcare customers consistently require infrastructure that the vendor controls, not infrastructure that a third party controls on the vendor&#8217;s behalf.</p><p><strong>SOC 2 compliance on Heroku:</strong> SOC 2 Type II requires demonstrating consistent control over infrastructure over time. The controls around logical access, change management, risk assessment, and monitoring all require the ability to configure and audit the underlying infrastructure. Teams on Heroku cannot configure VPC access controls, cannot implement custom IAM policies, and cannot generate infrastructure-level audit logs, because those capabilities belong to Heroku, not the team.</p><p><strong>What AWS-native alternatives eliminate:</strong></p><p>When infrastructure runs in the team&#8217;s own AWS account, the compliance surface is AWS, which holds SOC 2 Type II, HIPAA BAA, GDPR adequacy, PCI DSS, FedRAMP, and dozens of additional certifications. Every environment LocalOps provisions includes private subnets, least-privilege IAM policies, encrypted secrets via AWS Secrets Manager, and audit logging through AWS CloudTrail.</p><p>The compliance architecture is not assembled after migration. It is in place from the first deployment, as a default, not as a configuration project initiated by a compliance audit or an enterprise deal.</p><p>For teams evaluating the best Heroku alternatives for compliance-sensitive workloads, infrastructure ownership in their own AWS account is the only path that satisfies enterprise security requirements without a compliance ceiling defined by a vendor.</p><h2><strong>Limitation 3: Heroku Has No Least-Privilege Access, No Role-Based Permissions, and No Audit Logging</strong></h2><p>Access control and audit logging are the two capabilities that SOC 2, HIPAA, and virtually every enterprise security framework require as baseline infrastructure controls. Heroku provides neither at the infrastructure level.</p><p>On Heroku, access control is application-level. Developers are granted access to Heroku applications, not to the infrastructure running underneath. There is no concept of least-privilege access to specific infrastructure resources. A developer with access to a Heroku application has the same access surface as every other developer with access to that application. Granular, role-based access to specific infrastructure components, the EKS cluster, the RDS database, and specific S3 buckets does not exist.</p><p>Audit logging at the infrastructure layer does not exist on Heroku. There is no equivalent to AWS CloudTrail, no log of who accessed what infrastructure resource, when, from where, and what action was taken. For teams undergoing SOC 2 Type II audits or responding to enterprise security questionnaires asking about infrastructure audit trails, this is a gap that cannot be closed while running on Heroku.</p><p><strong>Implementing least-privilege access on an AWS-native platform:</strong></p><p>AWS Identity and Access Management provides role-based access control at every layer of the infrastructure stack. IAM roles can be scoped to specific resources, specific actions, and specific conditions. A developer role can be granted read access to application logs without granting access to the production database. A CI/CD pipeline role can be granted permission to update a specific EKS deployment without any other AWS access.</p><p>LocalOps provisions IAM roles following least-privilege principles automatically. Every service gets a role scoped to exactly the AWS resources it needs. Developers access infrastructure through the LocalOps interface; the AWS account is always accessible, but direct infrastructure access is governed by IAM policies that the team controls.</p><p>AWS CloudTrail logs every API call to every AWS service, who made the call, when, from which IP, with which credentials, and what the response was. For SOC 2 audits, this audit trail is comprehensive, searchable, and exportable. It exists by default in every AWS account, not as a configuration project.</p><p>For teams evaluating Herokualternatives in 2026 with compliance requirements, the access control and audit logging gap is the most technically specific reason managed PaaS platforms fail enterprise security reviews. AWS-native infrastructure closes this gap structurally.</p><p><a href="https://localops.co/features/secure-by-default?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps implements least-privilege access automatically &#8594;</a></p><h2><strong>Limitation 4: Heroku Is Architecturally Unsuitable for Persistent, Stateful Workloads</strong></h2><p>Heroku&#8217;s application model is built around the twelve-factor app methodology, stateless processes, ephemeral filesystems, and external services for all persistence. This model works well for web applications following these patterns. It creates real constraints for workloads that do not.</p><p>Heroku dynos have an ephemeral filesystem. Any data written to the local filesystem within a dyno is lost when the dyno restarts, which can happen for any number of reasons, including Heroku platform events that are outside the team&#8217;s control. For applications that need to write temporary files, process large datasets, or maintain any local state, this is a constraint that requires architectural workarounds.</p><p>The dyno model also creates problems for workloads that need to maintain connections across restarts. Database connection pools, WebSocket connections, and long-running background jobs all behave differently when the underlying process can be restarted at any time by a platform the team does not control. Teams running these workloads on Heroku accumulate workarounds, connection retry logic, session state externalization, job queue durability mechanisms, that add complexity specifically to compensate for Heroku&#8217;s architectural model.</p><p>Persistent, stateful workloads, databases that need to run close to the application, stateful processing pipelines, machine learning inference services with large model files, legacy applications with filesystem dependencies, are all architecturally difficult on Heroku&#8217;s ephemeral, shared infrastructure model.</p><p><strong>How AWS-native alternatives solve stateful workloads:</strong></p><p>Kubernetes-based platforms running on AWS handle stateful workloads through persistent volumes, storage that survives pod restarts and is available to specific workloads. StatefulSets provide stable network identities and persistent storage for workloads that require them. Amazon EFS provides shared filesystem access across multiple pods when applications need it.</p><p>More significantly, the AWS service ecosystem provides purpose-built managed services for every category of stateful workload. Amazon RDS runs inside the team&#8217;s VPC, private, configurable, and not shared with any other tenant. ElastiCache provides Redis with VPC isolation and persistence configuration. Amazon SQS provides reliable message delivery for background job queues with dead-letter queue handling and retry logic.</p><p>LocalOps supports web services, background workers, cron jobs, internal services, and stateful workloads as first-class service types. Each is configured and scaled independently based on its own workload signals, not forced into Heroku&#8217;s dyno model that treats all workloads the same.</p><p>For teams evaluating Heroku open source alternatives or AWS Heroku alternative platforms for stateful workload support, the Kubernetes persistent volume model, combined with AWS managed services, is the correct architectural foundation. It is what modern production SaaS applications require and what Heroku&#8217;s design explicitly does not support.</p><h2><strong>Limitation 5: Heroku&#8217;s Manual Dyno Scaling Fails Under Real Traffic Patterns</strong></h2><p>Heroku&#8217;s scaling model is vertical and manual. When an application needs more capacity, the options are: upgrade to a larger dyno tier or add more dynos. Both decisions require human intervention. Both result in paying for the selected capacity level continuously, whether or not the traffic justifies it.</p><p>This model has three failure modes at scale that surface consistently across engineering teams.</p><p><strong>The over-provisioning trap.</strong> Teams running workloads with variable traffic, B2B applications that peak during business hours, consumer applications that spike around campaigns, and event-driven systems with bursty processing requirements must provision for peak capacity and pay for it at all times. There is no mechanism to automatically scale down when traffic drops. Teams pay for peak capacity during off-peak periods continuously. The cost compounds with the service count.</p><p><strong>The tier-jump problem.</strong> Heroku&#8217;s pricing scales in discrete tiers, not proportionally with usage. When resource requirements cross a tier boundary, the cost jumps to the next tier regardless of whether actual usage justifies the full tier ceiling. For finance teams preparing infrastructure forecasts, this makes cost modeling unreliable. Infrastructure spend jumps at irregular intervals unrelated to business metrics.</p><p><strong>The response latency problem.</strong> When a traffic spike arrives, and the team has not pre-provisioned adequate capacity, Heroku&#8217;s response time for manual scaling is measured in minutes of human decision-making plus minutes of dyno startup time. For high-concurrency APIs serving real-time workloads, this latency is visible to customers as performance degradation during exactly the moments when reliable performance matters most.</p><p><strong>How event-driven horizontal autoscaling solves this:</strong></p><p>Kubernetes horizontal pod autoscaling responds to real workload signals, CPU utilization, memory pressure, request queue depth, and custom application metrics, automatically and in seconds. When traffic increases, the platform scales out. When traffic drops, it scales back in. Teams pay for actual compute consumption proportional to real usage, not for the tier ceiling required to handle the peak.</p><p>The scaling configuration on LocalOps is set once based on the application&#8217;s resource requirements and traffic patterns. From that point, scaling decisions are made by the platform in response to real signals, without human intervention, without manual dyno configuration, and without the over-provisioning that Heroku&#8217;s model structurally requires.</p><p>For teams evaluating alternatives to Heroku, specifically because of scaling problems, the difference between manual vertical scaling and event-driven horizontal autoscaling is not marginal. It is the difference between an infrastructure model designed for predictable linear workloads and one designed for the variable, bursty traffic patterns that real SaaS applications experience.</p><p><a href="https://localops.co/features/auto-scaling?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how autoscaling works on LocalOps &#8594;</a></p><h2><strong>The Pattern Across All Four Limitations</strong></h2><p>These five limitations share a common structure. Each one is invisible at a small scale, where Heroku&#8217;s simplicity provides genuine value, and the constraints are either absent or manageable. Each one becomes a strategic constraint at the growth stage, Series A and beyond, when enterprise deals arrive, when architecture needs to evolve, when compliance frameworks become sales requirements, and when infrastructure cost compounds past the point of easy justification.</p><p>The teams that navigate this transition well are the ones that discover these limitations before they surface as crises. The CTO who identifies Heroku&#8217;s compliance ceiling six months before the first enterprise deal closes has time to plan a migration under calm conditions. The CTO who discovers it during a live security review does not.</p><h2><strong>How LocalOps + AWS Addresses All Five Limitations</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform built specifically for teams replacing Heroku.</p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles with least-privilege policies, encrypted secrets via AWS Secrets Manager, CloudTrail audit logging, and a complete Prometheus + Loki + Grafana observability stack, automatically. No Terraform. No Helm charts. No manual configuration. Production-ready in under 30 minutes.</p><p>From this point onwards, the developer experience is identical to Heroku. Push to your configured branch. LocalOps builds, containerizes, deploys, runs health checks, and handles rollback automatically. Preview environments spin up on every pull request. Horizontal autoscaling runs by default based on real traffic signals. Stateful workloads run as first-class service types with persistent storage.</p><p>The infrastructure runs in your AWS account. VPC isolation, private networking, IAM-based access control, audit logging, compliance-ready defaults, all present from the first deployment. If you stop using LocalOps, the infrastructure keeps running. Nothing needs to be rebuilt.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221;</em> <strong>&#8211; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</strong></p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, all of which LocalOps has saved for us.&#8221;</em> <strong>&#8211; Gaurav Verma, CTO and Co-founder, SuprSend</strong></p></blockquote><p><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get started for free, first environment on AWS in under 30 minutes &#8594;</a></p><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>How do teams get VPC isolation and private networking when moving off Heroku?</strong></p></li></ol><p>Moving to an AWS-native Internal Developer Platform provisions a dedicated VPC for every environment automatically. Private subnets separate application, database, and cache tiers. Security groups control traffic between services at the network layer. Services communicate over private IP addresses, never over the public internet. LocalOps provisions this VPC architecture automatically from the first deployment, following AWS Well-Architected standards. There is no manual VPC configuration required and no separate security project to complete before going to production.</p><ol start="2"><li><p><strong>What are the specific compliance risks of running HIPAA or SOC 2 workloads on Heroku?</strong></p></li></ol><p>HIPAA requires demonstrable control over infrastructure handling protected health information, access controls, audit logging, and transmission security, all implemented and auditable by the team. SOC 2 Type II requires consistent control over infrastructure over time. On Heroku, the infrastructure implementing these controls belongs to Heroku; the team cannot independently configure, audit, or demonstrate control over it. Moving to AWS via LocalOps puts the compliance surface in the team&#8217;s own AWS account, which holds HIPAA BAA, SOC 2 Type II, GDPR adequacy, and PCI DSS certifications. The compliance architecture is in place from the first deployment as a default.</p><ol start="3"><li><p><strong>How do teams implement least-privilege access and audit logging after leaving Heroku?</strong></p></li></ol><p>AWS IAM provides role-based access control at every layer of the infrastructure stack. LocalOps provisions IAM roles following least-privilege principles automatically; every service gets a role scoped to exactly the AWS resources it needs. AWS CloudTrail logs every API call to every AWS service automatically, providing a comprehensive audit trail for SOC 2 audits and enterprise security reviews. Both are present by default in every environment LocalOps provisions, not as separate configuration projects.</p><ol start="4"><li><p><strong>Why is Heroku unsuitable for stateful workloads?</strong></p></li></ol><p>Heroku&#8217;s dyno filesystem is ephemeral; any data written locally is lost when the dyno restarts. There is no persistent storage that survives dyno restarts. Database connection pools, WebSocket connections, and long-running stateful processes all behave unpredictably when the underlying process can restart at any time without the team&#8217;s control. Kubernetes running on AWS solves this through persistent volumes that survive pod restarts, StatefulSets that provide stable network identities, and Amazon EFS for shared filesystem access. LocalOps supports stateful workloads as a first-class service type.</p><ol start="5"><li><p><strong>How does event-driven autoscaling differ from Heroku&#8217;s dyno scaling model?</strong></p></li></ol><p>Heroku scaling is manual; humans decide when to add dynos or upgrade tiers, and teams pay for whatever capacity level is configured continuously. Kubernetes horizontal pod autoscaling responds to real workload signals, CPU, memory, and request queue depth, automatically and in seconds. When traffic increases, the platform scales out. When it drops, it scales back in. Teams pay for actual consumption rather than the tier ceiling required to handle peak load. For applications with variable traffic, the cost and reliability difference is significant.</p><ol start="6"><li><p><strong>Is LocalOps the best Heroku alternative for teams with compliance requirements?</strong></p></li></ol><p>For teams with SOC 2, HIPAA, GDPR, or enterprise compliance requirements, the defining characteristic of any Heroku alternative is whether infrastructure runs in the team&#8217;s own cloud account. Managed PaaS alternatives like Render and Railway run on the vendor&#8217;s shared cloud; the compliance ceiling is vendor-defined, the same structural problem as Heroku. LocalOps provisions infrastructure into the team&#8217;s own AWS account with compliance-ready defaults, private subnets, least-privilege IAM, encrypted secrets, and CloudTrail audit logging. The compliance surface is AWS, which holds the relevant certifications, not a vendor&#8217;s representations about what they support.</p><ol start="7"><li><p><strong>What does Rails hosting, a Heroku alternative, look like for compliance-sensitive Rails applications?</strong></p></li></ol><p>Rails applications have specific infrastructure requirements, Sidekiq workers, Postgres with connection pooling, Action Cable with Redis, Active Storage with object storage, and scheduled tasks. LocalOps handles all of these as first-class service types running inside a dedicated VPC. Web processes and Sidekiq workers scale independently. RDS provides Postgres with VPC isolation. ElastiCache provides Redis for Action Cable and job queuing. All services communicate over private networking. For Rails teams with compliance requirements, this is the Rails hosting Heroku alternative that satisfies enterprise security reviews and infrastructure ownership, with the developer experience intact.</p><h2><strong>Key Takeaways</strong></h2><p>The infrastructure limitations Heroku hides from small teams are the same limitations that become strategic constraints at the growth stage. VPC isolation and private networking become enterprise deal requirements. HIPAA and SOC 2 compliance become sales blockers. Least-privilege access and audit logging become audit requirements. Stateful workload support becomes an architectural necessity. Event-driven autoscaling becomes a cost and reliability requirement.</p><p>None of these surfaces is a crisis at a small scale. All of them surface before Series B for any B2B SaaS team with enterprise ambitions.</p><p>The best Heroku alternatives in 2026 are those that solve all five limitations simultaneously, not by adding compliance features on top of a managed PaaS, but by running infrastructure in the team&#8217;s own AWS account with compliance-ready defaults from the first deployment.</p><p>For engineering leaders evaluating alternatives to Heroku, the frame that produces the best decisions is the three-year question: what infrastructure limitations will constrain the business at the next stage? The answer to that question consistently points toward infrastructure ownership on AWS, with a platform layer that preserves the developer experience Heroku provided without the constraints it imposed.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call &#8594;</a></strong> Our engineers review your current Heroku setup and walk through the AWS migration for your specific stack.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started for Free &#8594;</a></strong> First production environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Heroku Migration Guide &#8594;</a></strong> Full technical walkthrough, database migration, environment setup, DNS cutover.</p>]]></content:encoded></item><item><title><![CDATA[Developer Self-Serve on AWS: How to Replace Heroku Without Creating an Ops Bottleneck]]></title><description><![CDATA[The missing layer in Heroku &#8594; AWS migrations: how to keep developers shipping without creating an ops dependency.]]></description><link>https://blog.localops.co/p/replace-heroku-without-creating-ops-bottleneck</link><guid isPermaLink="false">https://blog.localops.co/p/replace-heroku-without-creating-ops-bottleneck</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Wed, 15 Apr 2026 04:59:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hTUY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.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_!hTUY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hTUY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png 424w, https://substackcdn.com/image/fetch/$s_!hTUY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png 848w, https://substackcdn.com/image/fetch/$s_!hTUY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png 1272w, https://substackcdn.com/image/fetch/$s_!hTUY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hTUY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png" width="2400" height="1531" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1531,&quot;width&quot;:2400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5086064,&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://blog.localops.co/i/194261518?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52d97d58-85f9-4618-b6d4-1b36c237dfe1_2400x1808.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_!hTUY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png 424w, https://substackcdn.com/image/fetch/$s_!hTUY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png 848w, https://substackcdn.com/image/fetch/$s_!hTUY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.png 1272w, https://substackcdn.com/image/fetch/$s_!hTUY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8186ed8e-c8e0-40cc-8154-27a6855f8956_2400x1531.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>The most common way a Heroku to AWS migration fails is not a database problem or a DNS problem. It is an organizational one.</p><p>The infrastructure moves to AWS successfully. The technical configuration is correct. The compliance architecture is sound. And then developers who used to deploy themselves every 20 minutes on Heroku are filing tickets with the platform team and waiting 48 hours. Shipping velocity drops. Engineers are frustrated. The migration gets blamed, even though the infrastructure is fine.</p><p>This failure has a name in the engineering community: trading a PaaS dependency for a platform team dependency. The infrastructure problem is solved. The developer autonomy problem is recreated in a different form, with a different bottleneck, and the same cost.</p><p>Every team evaluating AWS as a Heroku alternative needs to answer one question before committing to an approach: <em>Will any developer on the team be able to deploy their service, access their logs, and check their application health on day one, without asking anyone for help?</em></p><p>If the answer is no, the migration has not succeeded, regardless of what the infrastructure looks like underneath.</p><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> How to preserve git-push deployments on AWS, what production-grade CI/CD looks like on a Heroku alternative, how to replicate Heroku Review Apps on Kubernetes, what genuine developer self-service requires, and whether small teams can run production SaaS on AWS without a dedicated platform function</p><p><strong>The core principle:</strong> Developer autonomy is not a feature to add after the migration. It is a requirement that the migration must preserve from day one.</p><p><strong>The answer:</strong> An AWS-native Internal Developer Platform that handles infrastructure complexity invisibly, so developers keep the workflows they already have, and the business gets the infrastructure it owns</p><p><strong>Want to see what developer self-serve looks like on LocalOps?</strong><a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Schedule a walkthrough &#8594;</a></p><h2><strong>Why Teams Lose Developer Experience When They Move to AWS</strong></h2><p>Heroku&#8217;s developer experience was not an accident. It was a deliberate product decision: make deployment so simple that any developer on the team can do it without infrastructure knowledge. The result was a platform that product engineers loved precisely because it got out of the way.</p><p>When teams move to raw AWS, they get everything Heroku could not provide: VPC isolation, horizontal autoscaling, compliance-ready infrastructure, and direct pricing. What they do not get automatically is the abstraction layer that made Heroku&#8217;s developer experience possible.</p><p>Deploying to EKS requires configuring the cluster, the VPC, the load balancers, the IAM roles, the security groups, and the CI/CD pipeline. Writing Kubernetes manifests. Managing Helm charts. Configuring health checks and rollback logic. For a platform engineer, this is reasonable work. For a product engineer building features, it is an unreasonable prerequisite to deploy code.</p><p>The gap between &#8220;AWS infrastructure is provisioned&#8221; and &#8220;any developer can deploy independently&#8221; is typically a three to six-month platform engineering project, before accounting for preview environments, self-serve environment management, or integrated observability. Most teams do not plan for this. Most migrations stall here.</p><p>The solution is not to simplify AWS. AWS is appropriately complex for what it does. The solution is an Internal Developer Platform, a layer that sits on top of AWS infrastructure and handles every infrastructure operation invisibly, so the developer-facing workflow stays identical to what the team had on Heroku.</p><h2><strong>Preserving Git-Push Deployments on AWS</strong></h2><p>The git-push deployment workflow is the single most important thing to preserve in a Heroku migration. It is not just a convenience; it is the mechanism that enables developer autonomy. When any developer can push code and see it deployed without infrastructure knowledge, the platform team stops being a bottleneck.</p><p>Preserving this on AWS requires an abstraction layer that translates a git push event into the Kubernetes operations required to deploy the new version, automatically, without the developer ever touching Kubernetes directly.</p><p>With LocalOps, the workflow is identical to Heroku. A developer pushes code to a configured branch. LocalOps detects the push, builds a container image automatically, pushes it to Amazon ECR, updates the Kubernetes deployment on EKS, runs health checks against the new version, and handles rollback automatically if the health checks fail. Within minutes, the new version is live. The developer sees deployment status in the LocalOps interface. No kubectl. No Helm. No Terraform. No platform team notification required.</p><p>Heroku buildpack replacement happens transparently. If the team has a Dockerfile, LocalOps uses it directly. If not, LocalOps detects the language and framework automatically and generates a container configuration. Rails, Node.js, Python, Go, and .NET are all supported out of the box. The build trigger is a git push, identical to what the team did on Heroku.</p><p>What the platform must provide to make this genuinely equivalent to Heroku: pre-configured CI/CD that triggers on every push without external pipeline configuration, deployment status visibility without AWS console or kubectl access, and rollback capability that any developer can trigger without platform team involvement. Without all three, the git-push experience is incomplete even if the underlying deployment mechanism works correctly.</p><p><a href="https://docs.localops.co/environment/services/deploy?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles continuous deployments &#8594;</a></p><h2><strong>What Production-Grade CI/CD Looks Like on a Heroku Alternative</strong></h2><p>Heroku&#8217;s CI/CD model is simple by design: push to a branch, Heroku builds the application using buildpacks and deploys it. There is no pipeline to configure. No YAML to write. No external service to connect. The entire build-deploy-verify cycle is handled by the platform automatically.</p><p>This simplicity does not scale with modern Git-based development practices in two specific ways.</p><p>First, Heroku&#8217;s pipeline model does not support preview environments natively without the Heroku CI add-on, and even with it, the implementation is limited compared to what Kubernetes-native platforms can provide. As teams grow and code review becomes more rigorous, the inability to spin up a full environment per pull request slows down QA and reduces deployment confidence.</p><p>Second, Heroku&#8217;s build system is opinionated about buildpacks and has limited support for multi-stage Docker builds, custom build tooling, and complex dependency graphs. Teams that outgrow Heroku&#8217;s buildpack ecosystem find themselves working around the platform rather than with it.</p><p>A production-grade CI/CD pipeline on a Heroku alternative has four characteristics that Heroku&#8217;s model lacks.</p><p>It builds from containers, not buildpacks. Container images are portable, reproducible, and not tied to any platform&#8217;s runtime assumptions. The same image that passes CI is the exact image that runs in production, no translation, no divergence.</p><p>It triggers on every push and every pull request automatically. No manual pipeline configuration. No YAML files to maintain. The platform detects the push, builds the image, and either deploys to a configured environment or spins up a preview environment for the pull request.</p><p>It includes health checks and automatic rollback as defaults. A deployment that fails health checks rolls back to the previous version automatically without human intervention. This is the behavior developers relied on with Heroku and expect to retain.</p><p>It provides deployment visibility without infrastructure access. Developers see build status, deployment progress, health check results, and recent deployment history in one interface, without navigating the AWS console or running kubectl commands.</p><p>LocalOps provides all four as the default configuration. CI/CD is wired in from the first deployment. There is no external pipeline to configure and no YAML to maintain.</p><h2><strong>Replicating Heroku Review Apps on AWS</strong></h2><p>Heroku Review Apps, ephemeral, per-pull-request environments with a live URL, are one of the most operationally valuable features teams lose when they move away from Heroku. Their absence slows QA, makes code review less confident, and reduces shipping velocity in ways that are hard to attribute directly but consistently felt by engineering teams.</p><p>Replicating this on AWS requires spinning up a complete, isolated environment automatically when a pull request is opened, with its own URL, its own database, its own configuration, and tearing it down automatically when the PR is closed, and resources are released. Technically possible on Kubernetes. Configuring it from scratch is a meaningful platform engineering project that most teams underestimate.</p><p>LocalOps handles this automatically. Every pull request triggers a complete, isolated preview environment with its own URL running the full application stack. No additional configuration. No platform team involvement. No approval workflow.</p><p>Each preview environment gets its own isolated namespace in the EKS cluster. Environment variables and secrets are inherited from the base configuration. The environment URL is posted automatically to the pull request as a comment. When the PR is closed, the environment tears down, and all AWS resources are released. Preview environments on LocalOps do not share a database with production or staging; each is fully isolated, with a dedicated test database or a seeded copy of production data. A broken preview environment has zero blast radius on other environments.</p><p>For CTOs evaluating Heroku alternatives, preview environments are one of the clearest signals of a platform&#8217;s production maturity. A platform that requires manual configuration or third-party tooling to provide per-PR environments has not matched what Heroku provided. A platform that provides them automatically as a default is meaningfully ahead.</p><p><a href="https://docs.localops.co/use-cases/ephemeral?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how preview environments work on LocalOps &#8594;</a></p><h2><strong>What Genuine Developer Self-Service Actually Requires</strong></h2><p>Developer self-service is not just about deployment. It is the full scope of infrastructure interactions a developer needs throughout the development cycle, without filing a ticket, without waiting for approval, without infrastructure knowledge.</p><p>On Heroku, this was implicit in the platform design. Every capability a developer needed, deployment, environment creation, log access, metrics viewing, and secret management, was available through the Heroku CLI or dashboard with no infrastructure knowledge required. The platform team did not need to be involved for routine developer operations.</p><p>On a raw AWS migration without a platform layer, all of this requires explicit design. Without it, the platform team becomes a bottleneck for every infrastructure interaction, not just deployments. Environment creation requires Terraform or manual AWS console work. Log access requires CloudWatch navigation or Kibana queries. Metrics require Prometheus query knowledge. Secret updates require AWS Secrets Manager access that may not be appropriate to grant broadly.</p><p>Genuine self-service on a Heroku alternative requires three things to be true simultaneously. First, deployment without tickets: any developer pushes code and sees it deployed, no approval workflow, no waiting. Second, environment management without ops involvement: developers create environments, configure variables, and manage secrets through a self-service interface without understanding VPCs, IAM roles, or Kubernetes namespaces. Third, log and metric access without AWS console knowledge: developers access their application&#8217;s logs and metrics through a unified interface without navigating CloudWatch or writing Prometheus queries.</p><p>The mechanism that makes self-service safe for compliance-sensitive teams is encoding security controls into the platform rather than into an approval process. With LocalOps, every environment is provisioned from hardened infrastructure templates following AWS Well-Architected standards. Private subnets, least-privilege IAM policies, encrypted secrets via AWS Secrets Manager, and security group configurations are applied automatically. Developers cannot provision insecure infrastructure because the insecure options are not available in the self-service interface.</p><p>Platform teams set the guardrails once. Developers work within them without knowing they exist. Security is enforced at the infrastructure level, not through a ticket queue. This is the model that eliminates the ops bottleneck without eliminating security controls.</p><p><a href="https://localops.co/features/secure-by-default?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles security by default &#8594;</a></p><h2><strong>Can a Team of Five to Ten Engineers Run Production SaaS on AWS Without a Dedicated Platform Function?</strong></h2><p>This is the question most directly relevant to early-stage and growth-stage teams, and the honest answer depends entirely on how they access AWS.</p><p>Raw AWS without a platform layer requires someone to own infrastructure configuration, security hardening, CI/CD pipeline setup, observability configuration, Kubernetes cluster management, and ongoing maintenance. For a team of five to ten engineers, this typically means one engineer spending 30&#8211;50% of their time on infrastructure rather than product. At the growth stage, there is a high cost to pay in engineering capacity.</p><p>An AWS-native Internal Developer Platform changes the calculation entirely.</p><p>LocalOps handles VPC provisioning, EKS cluster management, IAM configuration, security hardening, observability setup, CI/CD wiring, and autoscaling configuration automatically. A team of five to ten engineers can run production-grade AWS infrastructure, with full compliance architecture, built-in observability, and developer self-service, without any engineer owning those responsibilities full-time.</p><p>The threshold where dedicated platform engineering expertise becomes necessary is when requirements exceed what the platform handles automatically. For most teams with five to fifteen engineers, that threshold is well above where they currently operate. The platform handles the infrastructure. The team handles the product.</p><h2><strong>How LocalOps Fits In</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform built specifically for teams replacing Heroku.</p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and a complete Prometheus + Loki + Grafana observability stack automatically. No Terraform. No Helm charts. No manual configuration. First environment ready in under 30 minutes.</p><p>From there, the developer experience is identical to Heroku. Push to your configured branch. LocalOps builds, containerizes, deploys, runs health checks, and handles rollback automatically. Preview environments spin up on every pull request. Logs and metrics are available from day one in pre-built Grafana dashboards. Autoscaling runs by default.</p><p>The infrastructure runs in your AWS account. If you stop using LocalOps, it keeps running. Nothing needs to be rebuilt. Developer autonomy is preserved from day one. The ops bottleneck does not get created.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221;</em><strong> &#8211; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</strong></p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, , all of which LocalOps has saved for us.&#8221;</em> <strong>&#8211; Gaurav Verma, CTO and Co-founder, SuprSend</strong></p></blockquote><p><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get started for free, first environment live in under 30 minutes &#8594;</a></p><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>How do teams preserve Git push deployments after migrating to AWS without learning Kubernetes?</strong></p></li></ol><p>The answer is an Internal Developer Platform that sits between developers and AWS infrastructure, translating a git push into all the Kubernetes operations required to deploy the new version, invisibly. LocalOps detects the push, builds the container image automatically, pushes to Amazon ECR, updates the EKS deployment, runs health checks, and handles rollback if anything fails. Developers see the deployment in progress, and the new version is live within minutes. No Kubernetes knowledge required. No Helm charts. No Terraform. No platform team notification. The workflow is identical to Heroku. The infrastructure underneath is AWS running in the team&#8217;s own account.</p><ol start="2"><li><p><strong>What does a production-grade CI/CD pipeline look like on a Heroku alternative?</strong></p></li></ol><p>A production-grade pipeline on a Heroku alternative builds from container images rather than buildpacks, triggers automatically on every push and every pull request without manual pipeline configuration, includes health checks and automatic rollback as defaults, and provides deployment visibility without AWS console or kubectl access. LocalOps provides all four as the default configuration. There is no YAML to write and no external CI/CD service to connect. The entire build-deploy-verify cycle is handled by the platform automatically, the same behavior Heroku provided, running on infrastructure the team owns.</p><ol start="3"><li><p><strong>How do teams replicate Heroku Review Apps on Kubernetes-based platforms?</strong></p></li></ol><p>Replicating Heroku Review Apps on Kubernetes requires spinning up a completely isolated environment automatically when a pull request is opened, with its own URL, own database, and own configuration, and tearing it down when the PR closes. LocalOps handles this automatically on every pull request with no additional configuration required. Each preview environment gets its own isolated EKS namespace, inherits environment variables from the base configuration, and posts its URL automatically to the pull request. When the PR closes, the environment tears down, and AWS resources are released. No platform team involvement at any step.</p><ol start="4"><li><p><strong>What does genuine developer self-service require on a Heroku alternative?</strong></p></li></ol><p>Three things must be true simultaneously: deployment without tickets,, any developer pushes code and sees it deployed with no approval workflow; environment management without ops involvement,, developers create environments and manage secrets through a self-service interface without AWS or Kubernetes knowledge; and log and metric access without AWS console navigation,  logs and metrics available in a unified interface from the first deployment. The mechanism that makes this safe for compliance-sensitive teams is encoding security controls into the platform rather than into an approval process, so guardrails are enforced at the infrastructure level without creating a ticket queue.</p><ol start="5"><li><p><strong>Can a five to ten-person team run production SaaS on AWS without a dedicated SRE or platform function?</strong></p></li></ol><p>Yes, with the right platform layer. Raw AWS without a platform layer requires someone to own infrastructure configuration, Kubernetes management, security hardening, observability setup, and ongoing maintenance. On a five to ten-person team, that typically means one engineer spending 30&#8211;50% of their time on infrastructure rather than product. LocalOps handles all of this automatically. The team runs production-grade AWS infrastructure with full compliance architecture, built-in observability, and developer self-service without any engineer owning infrastructure full-time. The threshold where dedicated platform expertise becomes necessary is well above where most five to fifteen-person teams currently operate.</p><ol start="6"><li><p><strong>Is AWS a good Heroku alternative for teams without DevOps expertise?</strong></p></li></ol><p>AWS is the right infrastructure foundation; the challenge is accessing AWS without requiring product engineers to become infrastructure engineers. An AWS-native IDP makes this practical. LocalOps handles VPC provisioning, EKS cluster management, IAM configuration, security hardening, CI/CD wiring, observability configuration, and autoscaling, automatically, from the first deployment. Teams of five to ten engineers run production-grade AWS infrastructure without a dedicated DevOps hire. Developers interact with git and a deployment interface. The AWS complexity is abstracted entirely, but the team&#8217;s AWS account is always fully accessible.</p><ol start="7"><li><p><strong>What makes LocalOps different from other AWS Heroku alternative platforms?</strong></p></li></ol><p>The infrastructure runs in the team&#8217;s own AWS account, not LocalOps&#8217;s. This means the compliance surface is the team&#8217;s AWS account, there is no vendor lock-in to unwind, and the infrastructure continues running independently if the team ever stops using LocalOps. Most AWS Heroku alternative platforms that provide developer-friendly workflows do so by running infrastructure in their own shared cloud, the same structural model as Heroku. LocalOps provides a Heroku-equivalent developer experience on infrastructure the team owns and controls entirely.</p><h2><strong>Key Takeaways</strong></h2><p>Replacing Heroku without creating an ops bottleneck requires treating developer autonomy as a first-class requirement, not as a feature to add after the migration is complete.</p><p>Git-push deployments, preview environments on every pull request, self-serve environment management, and unified log and metric access are all achievable on AWS. None of them requires developers to learn Kubernetes, Helm, or Terraform. They require a platform designed to absorb that infrastructure complexity invisibly, so developers keep the workflows they already have, and the business gets the infrastructure it owns.</p><p>For CTOs evaluating the best Heroku alternatives in 2026, the AWS Heroku alternative that preserves developer autonomy from day one is not the one with the most infrastructure features. It is the one where any developer on the team can deploy, access logs, and check application health without asking anyone for help, running on infrastructure the team owns, at direct AWS pricing, with no new vendor lock-in to unwind.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call &#8594;</a></strong> Our engineers review your Heroku setup and walk through what developer self-serve looks like for your specific stack.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started for Free &#8594;</a></strong> First environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Migration Guide &#8594;</a></strong> Full technical walkthrough, database migration, environment setup, DNS cutover.</p>]]></content:encoded></item><item><title><![CDATA[Self-Hosted Heroku Alternatives in 2026: Build vs. Buy for Platform Engineering Teams]]></title><description><![CDATA[Why infrastructure ownership isn&#8217;t the hard part, operating it at scale is (and what that really costs your team)]]></description><link>https://blog.localops.co/p/self-hosted-heroku-alternatives-build-vs-buy</link><guid isPermaLink="false">https://blog.localops.co/p/self-hosted-heroku-alternatives-build-vs-buy</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Mon, 13 Apr 2026 08:52:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!fyiq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.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_!fyiq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fyiq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png 424w, https://substackcdn.com/image/fetch/$s_!fyiq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png 848w, https://substackcdn.com/image/fetch/$s_!fyiq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png 1272w, https://substackcdn.com/image/fetch/$s_!fyiq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fyiq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png" width="1806" height="1384" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1384,&quot;width&quot;:1806,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5131656,&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://blog.localops.co/i/194047963?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c867fd1-a698-4e16-81c3-e4c8e9786d5a_1808x2400.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_!fyiq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png 424w, https://substackcdn.com/image/fetch/$s_!fyiq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png 848w, https://substackcdn.com/image/fetch/$s_!fyiq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.png 1272w, https://substackcdn.com/image/fetch/$s_!fyiq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a40cf94-8638-4625-a277-16ac36230f03_1806x1384.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>A self-hosted Heroku alternative is any deployment platform that runs on infrastructure the team owns and controls, typically in their own AWS account, rather than on a shared third-party cloud.</p><p>This model solves the three most important structural problems with Heroku simultaneously: cost compounding from platform margin, compliance ceiling from shared infrastructure, and vendor lock-in from infrastructure that disappears when you leave. This is why the self-hosted category consistently dominates engineering community discussions when CTOs evaluate what comes after Heroku.</p><p>What it does not solve automatically is the operational burden of running the platform itself. That burden, and the true cost of building versus buying a self-hosted deployment platform, is what this guide covers directly.</p><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> The most production-ready self-hosted Heroku alternatives in 2026, real operational limitations, compliance architecture, true build vs. buy cost, and how to avoid replicating vendor lock-in</p><p><strong>Who it is for:</strong> CTOs and founders evaluating whether to build a self-hosted platform or buy a managed one</p><p><strong>The core tension:</strong> Self-hosting gives you infrastructure ownership, compliance capability, and no platform margin. It transfers the full operational burden of platform maintenance to your team. For most Series A&#8211;C product-focused teams, that burden is higher than it appears before migration.</p><p><strong>Want infrastructure ownership without building the platform yourself?</strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Speak with the LocalOps team &#8594;</a></p><h2><strong>The Most Production-Ready Self-Hosted Options in 2026</strong></h2><p>The self-hosted landscape has three meaningful options for teams wanting to run on their own AWS account. Each has a distinct maturity profile and production ceiling.</p><p><strong>Coolify</strong> is the most actively developed and provides the most Heroku-like interface, a web-based deployment dashboard, Docker-based hosting, database provisioning, SSL management, and environment variable handling. It is the most accessible entry point in this category. Its core limitation for production SaaS is autoscaling. Coolify does not natively support horizontal autoscaling based on real traffic signals; scaling is primarily manual or scheduled. Observability is not included. Proper multi-environment isolation requires manual configuration beyond what the default setup provides.</p><p><strong>Dokku </strong>is the original self-hosted Heroku alternative. It delivers the most genuine git-push experience of any open-source option, push to a branch, application deploys, no Kubernetes required. The limitation is architectural: Dokku is a single-server platform. Horizontal scaling across multiple hosts requires significant additional work, and the single-server model creates a reliability risk for applications with SLA commitments. For teams running a small number of services with modest and predictable traffic, Dokku is a reasonable path. For production SaaS at the growth stage, the architecture is too constrained.</p><p><strong>CapRover </strong>uses Docker Swarm to provide multi-node horizontal scaling, a meaningful step beyond Dokku. It supports a web dashboard, one-click app templates, and custom domain management. The limitation worth understanding before committing: Docker Swarm has been largely superseded by Kubernetes in the production engineering community. Teams choosing CapRover are building on a stack with declining ecosystem investment, and production patterns like canary deployments, preview environments, and application-metrics-driven autoscaling all require significant additional work.</p><p>Across all three, achieving proper multi-environment isolation, separate VPCs, environment-specific IAM policies, isolated databases, and network segmentation between dev, staging, and production requires manual configuration that none of these platforms provides automatically. This gap is the most common source of post-migration compliance and reliability incidents.</p><p><a href="https://docs.localops.co/environment/inside?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles multi-environment isolation automatically &#8594;</a></p><h2><strong>The Real Operational Limitations</strong></h2><p>The decision to self-host a deployment platform transfers a specific set of operational responsibilities from the platform vendor to the team. Understanding what those responsibilities actually cost is the core of the build vs. buy calculation.</p><p>Security patching and platform maintenance are ongoing and non-negotiable. CVEs in Docker, Kubernetes, the underlying OS, and the platform software require evaluation, testing, and deployment on a regular cadence. Observability setup is a multi-day project per environment that none of the platforms above includes out of the box. Prometheus for metrics, Loki for logs, Grafana for dashboards, and alerting rules all require separate configuration and ongoing maintenance as services are added. Platform on-call means that when the deployment platform has an incident, the engineering team owns the response. There is no vendor support. Scaling configuration on Kubernetes requires ongoing tuning as traffic patterns evolve; it is not a one-time setup.</p><p>The signal that a scaling startup should choose a managed AWS-native IDP over a self-hosted alternative is consistent: when engineering hours required to maintain the platform layer exceed the cost of a platform fee, and when those hours would otherwise be spent on product. For product-focused teams at Series A and beyond without a dedicated platform engineer, this threshold is crossed almost immediately. Platform maintenance consistently represents 4&#8211;8 engineering hours per week. At $100&#8211;150 per fully-loaded engineering hour for a senior engineer, that is $400&#8211;$1,200 per week in hidden maintenance costs, before any incident response.</p><h2><strong>Compliance: Self-Hosted vs. Managed PaaS</strong></h2><p>This is one of the most significant and most misunderstood dimensions of the self-hosted decision.</p><p>When your deployment platform runs on your own AWS account, your compliance surface is your own infrastructure. SOC 2 Type II, HIPAA, and GDPR assessments are conducted against your VPC configuration, your IAM policies, and your data handling practices, all of which you control. This is a structural difference from any managed PaaS alternative. On Heroku, Render, or Railway, the infrastructure is the vendor&#8217;s. Your compliance posture is bound by what the vendor certifies. When an enterprise security questionnaire asks about VPC configuration, private networking, and IAM audit logging, the honest answer on a managed PaaS is that the team does not control those things.</p><p>The compliance advantage of self-hosting is real. Realizing it requires correct implementation. A self-hosted platform running on EC2 instances without proper VPC isolation, without least-privilege IAM policies, without encrypted secrets management, and without infrastructure audit logging does not satisfy SOC 2 or HIPAA requirements, regardless of the fact that it runs in the team&#8217;s own account. Infrastructure ownership is necessary for compliance. It is not sufficient without the correct security configuration on top.</p><p>LocalOps applies all of the required compliance controls automatically in every environment, private subnets, least-privilege IAM policies, encrypted secrets via AWS Secrets Manager, security group configurations, and CloudTrail logging, following<a href="https://aws.amazon.com/architecture/well-architected"> AWS Well-Architected standards</a> as defaults, not as options. The compliance architecture is in place from the first deployment without additional configuration.</p><p><a href="https://localops.co/features/secure-by-default?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles compliance by default &#8594;</a></p><h2><strong>The True Build vs. Buy Cost</strong></h2><p>Most infrastructure reviews get this calculation wrong because they include only the infrastructure cost and exclude the engineering cost.</p><p>The initial build cost of a production-grade Internal Developer Platform on Kubernetes, one where any product engineer can deploy independently, with git-push workflows, preview environments, integrated observability, autoscaling, and secrets management, is consistently reported at three to six months of senior platform engineering time. At a fully-loaded cost of $200,000 per year, three months of a senior platform engineer&#8217;s time represents approximately $50,000 before the platform has shipped a single product feature. For a ten-person team, this is also three to six months during which one senior engineer is building platform infrastructure rather than product.</p><p>Ongoing maintenance adds $20,000&#8211;$40,000 per year in engineering time, permanently. Platform on-call creates incident response burden and context-switching overhead that is difficult to measure but genuinely costly. And if the developer experience migration is incomplete, if developers who used to deploy in 20 minutes on Heroku are now waiting hours for platform team involvement, the productivity cost compounds across the entire engineering team.</p><p>A managed AWS-native IDP like LocalOps charges a platform fee. The underlying infrastructure runs at AWS list pricing with no markup. Observability is included. The build cost, maintenance cost, on-call burden, and developer experience regression cost are all absorbed by the platform. For most Series A&#8211;C teams, the fully-loaded cost of building and maintaining a self-hosted Kubernetes platform significantly exceeds the cost of a managed IDP, before accounting for the opportunity cost of engineering hours redirected from product to platform.</p><p>The self-hosted build path makes economic sense for teams with two or more platform engineers whose full-time job is internal infrastructure. For product-focused teams without this capacity, the math consistently favors managed.</p><p><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Walk through the cost comparison with a LocalOps engineer &#8594;</a></p><h2><strong>How to Avoid Replicating Heroku&#8217;s Vendor Lock-in</strong></h2><p>This is the strategic question most infrastructure evaluations underweight, and the one that determines whether the migration is made once or twice.</p><p>Heroku&#8217;s lock-in has a specific mechanism: infrastructure lives in Heroku&#8217;s systems, disappears when you leave, and accumulates dependencies with every year you stay. Managed PaaS alternatives replicate this mechanism with a different vendor name. The risk when choosing any alternative is recreating this structure in a new form.</p><p>Four infrastructure design decisions future-proof the platform choice. Infrastructure must run in your own cloud account, not the vendor&#8217;s. This is the binary decision that determines compliance ceiling, data residency, and exit optionality. The platform must use standard, portable technology, Kubernetes, not proprietary runtimes. This means infrastructure is manageable directly if you ever need to change the platform layer. The exit path must be verified explicitly before committing. Ask every vendor what happens if you stop using their platform tomorrow, and require a specific answer. And compliance requirements should be evaluated against 18-month projections, not just today&#8217;s requirements, because enterprise deals surface new requirements faster than most teams anticipate.</p><p>LocalOps is built around all four principles. Every resource is provisioned into the team&#8217;s own AWS account on standard Kubernetes. Infrastructure runs independently if the team stops using LocalOps. The compliance architecture supports SOC 2, HIPAA, and GDPR from day one as a default. The exit path is always open.</p><h2><strong>How LocalOps Fits In</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform built for teams replacing Heroku, and for teams evaluating whether to build a self-hosted platform or buy a managed one.</p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and a complete Prometheus + Loki + Grafana observability stack automatically. No Terraform. No Helm charts. No manual configuration. Production-ready in under 30 minutes.</p><p>Developers push to a configured branch. LocalOps builds, containerizes, deploys, health checks, and handles rollbacks automatically. Preview environments spin up on every pull request. Autoscaling runs by default. The infrastructure runs in your AWS account. If you stop using LocalOps, it keeps running. Everything that makes self-hosting strategically valuable, infrastructure ownership, compliance capability, no platform margin, and no vendor lock-in, is present. The operational burden of building and maintaining the platform is handled by LocalOps rather than your team.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221;</em> <strong>&#8211; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</strong></p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, all of which LocalOps has saved for us.&#8221;</em> <strong>&#8211; Gaurav Verma, CTO and Co-founder, SuprSend</strong></p></blockquote><p><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get started for free, first environment on AWS in under 30 minutes &#8594;</a></p><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>What are the most production-ready self-hosted Heroku alternatives in 2026?</strong></p></li></ol><p>Coolify, Dokku, and CapRover are the three most actively maintained options. Coolify provides the most Heroku-like interface but lacks production-grade autoscaling and integrated observability. Dokku is the most git-push-native but is architecturally limited to single-server deployments. CapRover provides multi-node scaling through Docker Swarm but builds on a stack largely superseded by Kubernetes. All three require significant additional configuration to achieve proper multi-environment isolation, production-grade observability, and compliance-ready infrastructure in an AWS account.</p><ol start="2"><li><p><strong>When should a scaling startup choose a managed IDP over a self-hosted alternative?</strong></p></li></ol><p>When the engineering hours required to maintain the platform layer exceed the cost of a platform fee, and when those hours would otherwise be spent on product. For product-focused teams at Series A and beyond without a dedicated platform engineer, this threshold is crossed almost immediately. Ongoing platform maintenance consistently represents 4&#8211;8 engineering hours per week. The managed IDP path makes sense for the majority of product-focused engineering teams. The self-hosted build path makes sense for teams with two or more platform engineers whose full-time job is internal infrastructure.</p><ol start="3"><li><p><strong>How do self-hosted alternatives compare to managed PaaS on SOC 2 and HIPAA compliance?</strong></p></li></ol><p>Self-hosted alternatives running on the team&#8217;s own AWS account have a structurally superior compliance architecture compared to managed PaaS platforms. The compliance surface is the team&#8217;s own AWS account, which holds SOC 2, HIPAA, GDPR, and additional certifications. However, the compliance advantage is only realized with correct implementation: proper VPC configuration, least-privilege IAM policies, encrypted secrets management, and audit logging. Infrastructure ownership is necessary for compliance. It is not sufficient without a correct security configuration on top.</p><ol start="4"><li><p><strong>What is the true build vs. buy cost of a self-hosted Kubernetes platform?</strong></p></li></ol><p>The full cost includes: initial build cost of three to six months of senior platform engineering time (approximately $50,000&#8211;$100,000), ongoing maintenance of 4&#8211;8 hours per week permanently ($20,000&#8211;$40,000 per year), on-call burden for platform incidents, and developer experience regression cost if git-push workflows are not fully replicated. For most Series A&#8211;C product-focused teams, the fully-loaded cost of building and maintaining a self-hosted Kubernetes deployment platform significantly exceeds the cost of a managed AWS-native IDP.</p><ol start="5"><li><p><strong>How do engineering leaders choose a Heroku alternative that avoids vendor lock-in?</strong></p></li></ol><p>Four decisions future-proof the choice: infrastructure must run in your own cloud account, the platform must use standard Kubernetes, not proprietary runtimes, the exit path must be verified explicitly before committing, and compliance requirements should be evaluated against 18-month projections. LocalOps satisfies all four: infrastructure in your own AWS account, standard Kubernetes, infrastructure that runs independently if you stop using the platform, and AWS compliance surface with no vendor-defined ceiling.</p><ol start="6"><li><p><strong>What is the difference between a Heroku self-hosted alternative and LocalOps?</strong></p></li></ol><p>A Heroku self-hosted alternative like Coolify or Dokku gives full infrastructure control with no licensing cost. Your team owns the complete operational burden, provisioning, patching, observability, scaling, and platform on-call. LocalOps provides the same infrastructure ownership; everything runs in your own AWS account, with the platform layer managed rather than built. The infrastructure is self-hosted. The platform is managed. For teams without dedicated platform engineering capacity, this distinction determines whether infrastructure ownership is operationally viable or not.</p><h2><strong>Key Takeaways</strong></h2><p>The self-hosted category in 2026 offers genuine strategic value, infrastructure ownership, AWS-based compliance architecture, no platform margin, and no vendor lock-in. These advantages are real and are why the category deserves serious evaluation.</p><p>The build vs. buy decision is not about whether to own your infrastructure. Infrastructure ownership in your own AWS account is the right architectural model for B2B SaaS teams with enterprise ambitions. The decision is about whether to build and maintain the platform layer on top of that infrastructure yourself or to use a managed platform that handles that layer while keeping the infrastructure in your account.</p><p>For most product-focused engineering teams at Series A and beyond, the answer is the same one the engineering community has been converging on throughout 2026: buy the platform layer, own the infrastructure.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call &#8594;</a></strong> Our engineers review your current setup and walk through what infrastructure ownership looks like for your specific stack.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started for Free &#8594;</a></strong> First environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Heroku Migration Guide &#8594;</a></strong> Full technical walkthrough, database migration, environment setup, DNS cutover.</p>]]></content:encoded></item><item><title><![CDATA[🎉 New release: SAML 2.0 support - Sign in using your org's Identity provider]]></title><description><![CDATA[LocalOps becomes enterprise ready with SAML 2.0 support]]></description><link>https://blog.localops.co/p/new-release-saml20-support-sign-in</link><guid isPermaLink="false">https://blog.localops.co/p/new-release-saml20-support-sign-in</guid><dc:creator><![CDATA[LocalOps Inc]]></dc:creator><pubDate>Mon, 13 Apr 2026 08:21:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DiXG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.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_!DiXG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DiXG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png 424w, https://substackcdn.com/image/fetch/$s_!DiXG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png 848w, https://substackcdn.com/image/fetch/$s_!DiXG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png 1272w, https://substackcdn.com/image/fetch/$s_!DiXG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DiXG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png" width="1456" height="1137" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1137,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2397500,&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://blog.localops.co/i/194043725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.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_!DiXG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png 424w, https://substackcdn.com/image/fetch/$s_!DiXG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png 848w, https://substackcdn.com/image/fetch/$s_!DiXG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.png 1272w, https://substackcdn.com/image/fetch/$s_!DiXG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d91ddd-9a96-43db-b6bf-dc78515b6275_2742x2141.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>To make it easier for teams to on-board &amp; off board their users, we just released SAML2.0 support. </p><p>If you are the org owner or admin (<a href="https://blog.localops.co/p/new-release-switch-organizationsteams">you can belong to multiple orgs, btw</a>), you can now visit Account security settings to add a new SSO provider. With just a few clicks, you can enforce all users to sign in via your current Identity provider.</p><p>Any SAML 2.0 compliant identity provider is supported.</p><ol><li><p>Okta</p></li><li><p>Microsoft Entra ID</p></li><li><p>Google Workspace SSO</p></li><li><p>OneLogin</p></li><li><p>Auth0</p></li></ol><p><a href="mailto:anand@localops.co">Talk to us</a>, if you are using other identity providers. </p><p>Get started with LocalOps for free at <a href="https://console.localops.co/signup">https://console.localops.co/signup</a>. </p><p>Or <a href="https://go.localops.co/tour">get a quick demo</a> to see how LocalOps can solve DevOps bottlenecks and streamline AWS deployments in your org.</p>]]></content:encoded></item><item><title><![CDATA[Heroku Alternatives the Engineering Community Actually Recommends in 2026]]></title><description><![CDATA[Heroku Alternatives Backed by Real Migrations: Lessons from Engineering Teams in 2026]]></description><link>https://blog.localops.co/p/heroku-alternatives</link><guid isPermaLink="false">https://blog.localops.co/p/heroku-alternatives</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Fri, 10 Apr 2026 06:40:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!QJY-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.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_!QJY-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QJY-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png 424w, https://substackcdn.com/image/fetch/$s_!QJY-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png 848w, https://substackcdn.com/image/fetch/$s_!QJY-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png 1272w, https://substackcdn.com/image/fetch/$s_!QJY-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QJY-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png" width="1456" height="816" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:816,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4282653,&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://blog.localops.co/i/193586542?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.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_!QJY-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png 424w, https://substackcdn.com/image/fetch/$s_!QJY-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png 848w, https://substackcdn.com/image/fetch/$s_!QJY-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.png 1272w, https://substackcdn.com/image/fetch/$s_!QJY-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdfb6a0-af5a-4377-b5c8-210a1aea29f3_2400x1345.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>The most useful signal when evaluating Heroku alternatives is not vendor marketing or feature comparison pages. It is the pattern of decisions made by engineering leaders who have already undergone the migration and are willing to share what worked, what did not, and what they wish they had known before starting.</p><p>Across Reddit threads on r/devops, r/rails, r/node, and r/selfhosted, and Hacker News discussions on platform engineering and infrastructure decisions, consistent patterns have emerged in 2026 that did not exist with the same clarity two years ago. The community has been through enough Heroku migrations now, successful ones, failed ones, and ones that required doing twice, to have developed a genuine consensus on what works at production scale.</p><p>This guide synthesizes those patterns, maps them to the structural differences between platform categories, and gives engineering leaders a framework for choosing a Heroku alternative that does not replicate the vendor lock-in problem they are trying to solve.</p><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> What the engineering community actually recommends as Heroku alternatives in 2026, how the landscape has shifted, how top alternatives compare on TCO, and how to choose a platform that avoids recreating Heroku&#8217;s lock-in</p><p><strong>Who it is for:</strong> CTOs and engineering leaders evaluating Heroku alternatives who want a community-validated signal alongside structural analysis</p><p><strong>The community consensus:</strong> Managed PaaS alternatives are a transitional step, not a destination. Infrastructure ownership on AWS, with a platform layer that preserves developer experience, is what the community consistently validates for production SaaS at scale.</p><p><strong>Want to see what LocalOps looks like for your specific stack?</strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Schedule a walkthrough</a></p><h2><strong>How the Heroku Alternatives Landscape Has Shifted in 2026</strong></h2><p>The Heroku alternatives landscape in 2026 looks meaningfully different from what it was two years ago, and the shift is not primarily about new platforms entering the market.</p><p>The shift is in how engineering leaders are framing the decision.</p><p>In 2023 and 2024, the dominant question in the community was: <em>What is the easiest migration from Heroku?</em> Teams were evaluating alternatives primarily on migration friction, how quickly they could get off Heroku, and how similar the new experience would feel.</p><p>In 2026, the dominant question has changed: <em>what infrastructure foundation does our business need for the next three years?</em> Teams are evaluating alternatives on strategic fit, compliance capability, cost structure at scale, exit optionality, and whether the platform they choose will be the last migration they make or the first of two.</p><p>That shift in framing produces significantly different answers. The easiest migration is often not the right strategic choice. A team that moves from Heroku to Render solves the immediate cost and developer experience problem. If they are selling to enterprise customers, they will face the same compliance conversation 18 months later, with more accumulated dependencies and less time to address it under better conditions.</p><p><strong>Where compliance-sensitive teams are landing:</strong></p><p>Enterprise-grade, compliance-sensitive SaaS teams have converged on AWS-native infrastructure with a platform layer on top. The reasons are consistent across community discussions:</p><p>SOC 2 and HIPAA requirements demand infrastructure running in the team&#8217;s own cloud account. Enterprise security questionnaires require VPC configuration, private networking, and IAM audit trails that managed PaaS platforms cannot provide. Cost efficiency at scale requires direct AWS pricing, not a PaaS margin that compounds with every service added. Architectural flexibility requires Kubernetes-grade infrastructure, not dyno-based compute.</p><p>The best Heroku alternatives for this profile in 2026 are platforms that run on AWS infrastructure the team owns, with enough abstraction that developers do not need to interact with that infrastructure directly.</p><h2><strong>What the Engineering Community Is Actually Recommending</strong></h2><p>The community signal on Heroku alternatives is worth examining directly, because it captures the failure modes that vendor comparisons do not surface.</p><h3><strong>Pattern 1: The Managed PaaS Stepping Stone</strong></h3><p>The most frequently discussed migration pattern in the community is one that involves two migrations, not one.</p><p>Team moves from Heroku to Render or Railway to reduce friction and cost. The migration goes smoothly. Developer experience is preserved. Costs reduce modestly. The platform feels like a clear upgrade from Heroku for the first 12&#8211;18 months.</p><p>Then something changes. An enterprise prospect sends a security questionnaire. Or a compliance audit surfaces infrastructure requirements that the platform cannot meet. Or the cost structure at 15+ services starts looking familiar, platform margins compounding across services the same way Heroku&#8217;s did.</p><p>The team migrates again. This time to infrastructure they own.</p><p>The community commentary on this pattern is consistent and pointed: <em>the second migration is more expensive than going directly to infrastructure ownership would have been.</em> More accumulated dependencies to untangle. More technical debt from the intermediate platform. More urgency because the enterprise deals are now in an active pipeline rather than theoretical future scenarios.</p><p>The observation that surfaces in nearly every thread where this pattern is discussed: <em>the teams that went to infrastructure ownership directly made the migration once.</em></p><h3><strong>Pattern 2: The Raw AWS Complexity Trap</strong></h3><p>The second common pattern discussed is the team that moves directly to raw AWS and discovers that getting from &#8220;AWS is provisioned&#8221; to &#8220;any developer can deploy independently&#8221; is a multi-month platform engineering project.</p><p>The infrastructure is technically sound. The compliance posture is correct. The cost structure is right. But product engineers who used to deploy every 20 minutes on Heroku now file tickets with a platform team and wait 48 hours. Shipping velocity drops. The migration is blamed, even though the infrastructure itself is fine.</p><p>The community diagnosis is consistent: the technical migration succeeded. The developer experience migration failed. The team built the infrastructure layer without building the platform layer, which makes the infrastructure accessible to product engineers.</p><p>The resolution discussed in these threads is almost always the same: adopt a platform layer on top of the AWS infrastructure. In many cases, this is specifically what brings teams to AWS-native Internal Developer Platforms; they have the AWS foundation already, and they need the developer experience layer on top.</p><h3><strong>Pattern 3: The Rails Hosting Question</strong></h3><p>Rails teams are among the most active in these discussions, and their requirements surface a specific evaluation dimension that generic platform comparisons miss.</p><p>The community consensus on Rails hosting Heroku alternative options is clear and specific: any platform being evaluated for Rails production hosting needs to handle Sidekiq workers, Postgres with connection pooling, Active Storage with object storage, Action Cable with Redis, and scheduled tasks, as first-class service types, not as workarounds or add-on integrations.</p><p>Platforms that handle these as edge cases consistently receive community recommendations against for production Rails applications. Platforms that treat them as native deployment patterns, web processes and workers scaling independently, Redis inside the VPC, cron jobs as a first-class service type, consistently receive positive recommendations.</p><h3><strong>Pattern 4: The Infrastructure Ownership Conclusion</strong></h3><p>The most significant shift in community sentiment between 2024 and 2026 is the emergence of a clear conclusion on infrastructure ownership.</p><p>In 2024, the community was still debating whether infrastructure ownership was worth the operational complexity. In 2026, that debate has largely been settled for B2B SaaS teams with an enterprise go-to-market motion.</p><p>The observation that captures the current community position most precisely:</p><p><em>&#8220;The teams that moved to infrastructure they own early are the ones having the smoothest conversations with enterprise prospects. The teams still on managed platforms are the ones explaining to their board why a $200K deal is stuck in security review.&#8221;</em></p><p>This is not a technical observation. It is a business one. And it reflects how the community conversation has matured from infrastructure optimization to strategic positioning.</p><p><a href="https://localops.co/migrate-heroku-to-aws?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read how engineering teams navigate this transition</a></p><h2><strong>How Top Heroku Alternatives Compare on Total Cost of Ownership</strong></h2><p>For teams running 20+ production services, the cost structure differences between Heroku alternative categories are significant and compounding. Surface-level pricing comparisons miss the structural dynamics that determine actual TCO at scale.</p><p><strong>Managed PaaS alternatives: Render, Railway, Fly.io</strong></p><p>These platforms reduce cost versus Heroku, but they do not eliminate the platform margin. Every compute resource, managed database, cache instance, and monitoring capability still carries a vendor margin layered on top of the underlying infrastructure cost.</p><p>At 20+ services, this margin compounds. Each new service adds compute margin, database margin, Redis margin, and monitoring cost simultaneously. The efficiency ceiling is lower than direct AWS because the platform margin persists regardless of scale. And observability typically requires additional add-ons with separate billing, recreating one of the most frustrating cost dynamics of Heroku at a slightly lower price point.</p><p><strong>Open-source self-hosted alternatives: Coolify, Dokku, CapRover.</strong></p><p>These platforms eliminate the platform margin. Infrastructure runs at direct cloud pricing with no vendor markup. For teams with dedicated platform engineering capacity, the compute and managed service costs are as low as they can be.</p><p>The TCO calculation changes when engineering time is included. Provisioning, security patching, observability setup, autoscaling configuration, and on-call response for platform issues all fall to the team. For most product-focused engineering teams, the engineering hours required to operate a self-hosted platform in production represent a higher total cost than a managed platform fee, even accounting for the elimination of the platform margin.</p><p><strong>AWS-native Internal Developer Platforms: LocalOps</strong></p><p>The cost structure is fundamentally different from both categories above. LocalOps charges a flat platform fee. The underlying infrastructure runs at AWS list pricing with no markup. Observability, Prometheus, Loki, and Grafana are included at no additional cost regardless of service count.</p><p>At 20+ services, the difference compounds in the IDP&#8217;s favour. Every additional service adds only AWS infrastructure cost. No observability cost increment. No platform margin on database or cache. The gap between managed PaaS total cost and AWS-native IDP total cost widens with every service added.</p><p>For an accurate TCO comparison based on your current Heroku invoice and service count,<a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> the LocalOps team will model it directly</a>.</p><h2><strong>Structural Differences Between First-Generation Alternatives and AWS-Native IDPs</strong></h2><p>This is the distinction that most Heroku alternative evaluations underweight, because the surface-level experience of managed PaaS platforms and AWS-native IDPs can look similar to developers, while the underlying architecture is fundamentally different.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/itDJS/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61f5269d-d6d6-4a6c-887f-21181905d9d9_1220x1080.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f3b447c-abf2-4fd5-8a27-0144f2766b07_1220x1080.png&quot;,&quot;height&quot;:540,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/itDJS/1/" width="730" height="540" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>The structural difference is not about developer experience on day one. Both categories can provide a git-push deployment workflow. The structural difference is about what happens at month 18 when enterprise deals arrive, compliance requirements sharpen, and the cost structure at scale comes under scrutiny.</p><p>First-generation alternatives, Render, Railway, and Fly.io, improve on Heroku&#8217;s developer experience and pricing. The fundamental model is the same: your infrastructure runs on someone else&#8217;s cloud. Your compliance posture is bound by what the vendor chooses to support. Your exit path requires rebuilding infrastructure from scratch. You are trading one managed dependency for another.</p><p>AWS-native Internal Developer Platforms change the model entirely. Infrastructure runs in your cloud account. Developer experience is preserved, and git push deploys without Kubernetes knowledge. Observability, CI/CD, autoscaling, and secrets management are built in. And if you stop using the platform, your infrastructure keeps running. Nothing needs to be rebuilt.</p><p>This structural difference is what the community discovered through the stepped migration pattern described above. The teams that made it once recognized this distinction before choosing. The teams that made it twice discovered it afterwards.</p><h2><strong>How to Choose a Heroku Alternative That Avoids Replicating Vendor Lock-in</strong></h2><p>This is the question that separates a good infrastructure decision from a decision that creates the same problem in a different form.</p><p>Heroku&#8217;s vendor lock-in has a specific mechanism: your infrastructure lives in Heroku&#8217;s systems. When you leave, it disappears. You start from scratch. Every year you stay on Heroku, the dependencies accumulate, and the eventual migration becomes more expensive.</p><p>The risk when choosing a Heroku alternative is choosing a platform that replicates this mechanism with a different vendor name. The managed PaaS category does this structurally; Render, Railway, and Fly.io all use the same model. Your infrastructure lives in their systems. When you leave, you start from scratch.</p><p><strong>The infrastructure design decisions that future-proof the platform choice:</strong></p><p><strong>Decision 1: Infrastructure must run in your cloud account.</strong></p><p>This is the binary decision that determines everything downstream. If infrastructure runs in your account, your VPC, your EKS cluster, your RDS database, then the platform vendor you use to manage that infrastructure is replaceable. The infrastructure is yours. The management layer is a service you pay for, not a dependency you are locked into.</p><p>If infrastructure runs in the vendor&#8217;s systems, you are locked in structurally, regardless of how the platform markets itself.</p><p><strong>Decision 2: The platform must use standard, portable technology.</strong></p><p>Kubernetes is the standard. Helm charts are standard. Terraform is standard. Any platform that runs your workloads on standard Kubernetes in your own account gives you the option to manage that infrastructure directly if you ever need to change the platform layer.</p><p>Platforms that run on proprietary runtimes, proprietary deployment formats, or proprietary infrastructure abstractions create lock-in even if the infrastructure nominally runs in your account.</p><p><strong>Decision 3: Verify the exit path before committing.</strong></p><p>Ask every platform vendor directly: <em>if we stop using your platform tomorrow, what does our infrastructure look like, and can we continue operating it independently?</em></p><p>LocalOps answers this question specifically and directly. Every resource LocalOps provisions lives inside the team&#8217;s own AWS account. EKS clusters, RDS databases, VPCs, load balancers, all owned by the team, all running in their account, all manageable directly through the AWS console or CLI if the team ever stops using LocalOps. There is no data to export. There is no infrastructure to rebuild. The exit path is always open.</p><p>Platforms that cannot answer this question clearly, or that answer it with migration timelines, data export processes, or infrastructure rebuild requirements, are creating vendor lock-in regardless of how they describe their model.</p><p><strong>Decision 4: Evaluate compliance ceiling, not just current compliance.</strong></p><p>Managed PaaS platforms have a compliance ceiling defined by what the vendor chooses to support. That ceiling may be adequate today. It may not be adequate in 18 months when enterprise procurement processes become part of the sales cycle.</p><p>AWS-native IDPs running in the team&#8217;s own account have no compliance ceiling. The compliance surface is AWS, which holds SOC 2, HIPAA, GDPR, PCI DSS, and dozens of additional certifications. The compliance architecture grows with the business rather than constraining it.</p><p><a href="https://localops.co/features/secure-by-default?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps handles compliance by default</a></p><p><strong>How LocalOps Fits the Community&#8217;s Validated Pattern</strong></p><p>LocalOps is an AWS-native Internal Developer Platform built specifically for teams replacing Heroku.</p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and a complete observability stack, Prometheus, Loki, and Grafana, automatically. No Terraform. No Helm charts. No manual configuration. First environment ready in under 30 minutes.</p><p>From that point onwards, the developer experience is identical to Heroku. Push to your configured branch. LocalOps builds, containerizes, and deploys to AWS automatically. Preview environments spin up on every pull request. Logs and metrics available from day one. Autoscaling and auto-healing run by default.</p><p>The infrastructure runs in your AWS account. If you stop using LocalOps, it keeps running. Nothing needs to be rebuilt. This is the architectural model the community has converged on: infrastructure ownership with developer simplicity, no new vendor dependency, no compliance ceiling.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221;</em><strong> &#8211; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</strong></p><p><em>&#8220;We saved months of DevOps effort by using LocalOps,&#8221;</em> <strong>&#8211; Shobit Gupta, Ex-Uber, CTO and Co-founder, Segwise.</strong></p></blockquote><p><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get started for free, first environment live in under 30 minutes</a></p><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>How has the Heroku alternatives landscape shifted in 2026, and which platforms have emerged as most viable for enterprise-grade SaaS teams?</strong></p></li></ol><p>The most significant shift is not in the platforms available; it is in how engineering leaders are framing the decision. In 2023 and 2024, teams optimised for migration ease. In 2026, teams are optimizing for the three-year infrastructure foundation their business needs. This shift produces different answers. Managed PaaS alternatives remain viable for early-stage teams without current enterprise compliance requirements. For enterprise-grade, compliance-sensitive SaaS teams, AWS-native Internal Developer Platforms running in the team&#8217;s own account have emerged as the clear choice, because they are the only category that satisfies compliance requirements without a ceiling, eliminates platform margin at scale, and provides a genuine exit path.</p><ol start="2"><li><p><strong>What are engineering teams on Reddit and Hacker News actually recommending in 2026?</strong></p></li></ol><p>The community consensus has coalesced around three consistent positions. First: managed PaaS alternatives like Render and Railway are a transitional step, not a destination; teams that go there first often end up migrating again when compliance requirements arrive. Second: going directly to raw AWS without a platform layer creates developer experience problems that erode the infrastructure benefits. Third: AWS-native Internal Developer Platforms, infrastructure in your own account with a developer experience layer on top, is the pattern the community validates for production SaaS teams with enterprise ambitions. Rails teams specifically require platforms that handle Sidekiq, Postgres, Active Storage, and Action Cable as first-class concerns.</p><ol start="3"><li><p><strong>How do Render, Railway, Fly.io, and AWS-native IDPs compare on TCO at 20+ services?</strong></p></li></ol><p>At 20+ production services, the structural cost differences become significant. Managed PaaS alternatives maintain a platform margin on every component, compute, database, cache, and monitoring, which compounds with each new service. At scale, the observability cost alone adds meaningfully as per-service monitoring costs multiply. AWS-native IDPs like LocalOps charge a flat platform fee with AWS list pricing on all infrastructure and observability included at no additional cost. The cost gap widens with every service added because every service adds another component where the margin difference applies. For an accurate comparison based on your current stack, the LocalOps team will model it from your Heroku invoice.</p><ol start="4"><li><p><strong>What are the structural differences between first-generation Heroku alternatives and AWS-native IDPs?</strong></p></li></ol><p>The fundamental difference is infrastructure ownership. First-generation alternatives, Render, Railway, and Fly.io, run infrastructure on the vendor&#8217;s shared cloud. No VPC ownership. Compliance ceiling defined by the vendor. Exit path requires a full infrastructure rebuild. Platform margin persists regardless of scale. AWS-native IDPs run infrastructure in the team&#8217;s own AWS account. Full VPC isolation. No compliance ceiling, the surface is AWS itself. Exit path is always open, infrastructure continues running independently. Direct AWS pricing with no platform margin. The developer experience on day one can look similar. The strategic implications diverge significantly at month 18.</p><ol start="5"><li><p><strong>How do engineering leaders choose a Heroku alternative that avoids replicating vendor lock-in?</strong></p></li></ol><p>Four infrastructure design decisions future-proof the platform choice. First: infrastructure must run in your cloud account, not the vendor&#8217;s. Second: the platform must use standard, portable technology, Kubernetes, not proprietary runtimes. Third: verify the exit path explicitly before committing, ask what happens if you stop using the platform tomorrow and evaluate the answer carefully. Fourth: evaluate compliance ceiling against 18-month requirements, not just current requirements. LocalOps specifically addresses all four: infrastructure in your AWS account, standard Kubernetes, explicit exit path with infrastructure running independently, and AWS compliance surface with no vendor-defined ceiling.</p><ol start="6"><li><p><strong>Is LocalOps a viable Heroku alternative for Rails applications specifically?</strong></p></li></ol><p>Yes. Rails applications require specific infrastructure handling: Sidekiq background workers, Postgres with connection pooling, Action Cable with Redis, Active Storage with object storage, and scheduled tasks. LocalOps handles all of these as first-class service types. Web processes and Sidekiq workers are configured and scale independently. Amazon RDS provides Postgres inside your VPC with connection pooling configuration. ElastiCache provides Redis for Action Cable and job queuing. Native cron jobs replace Heroku Scheduler. The rails hosting heroku alternative path through LocalOps preserves the git-push deployment workflow while running on infrastructure the team owns.</p><ol start="7"><li><p><strong>What is the difference between a Heroku self-hosted alternative and LocalOps?</strong></p></li></ol><p>A Heroku self-hosted alternative like Coolify or Dokku gives full infrastructure ownership with no platform vendor dependency. The team owns the complete operational burden, provisioning, security patching, observability setup, scaling configuration, and on-call response for platform issues. For teams without dedicated platform engineering capacity, the operational cost of running a self-hosted platform in production consistently exceeds initial estimates. LocalOps provides the same infrastructure ownership; everything runs in your own AWS account, with the platform layer managed. The infrastructure ownership is equivalent. The operational overhead is not. LocalOps is designed for teams that want infrastructure ownership without building and maintaining the platform themselves.</p><h2><strong>Key Takeaways</strong></h2><p>The engineering community&#8217;s consensus on Heroku alternatives in 2026 is clearer than it has ever been, because enough teams have now been through the full cycle of migration, operation, and in some cases re-migration to know what works at production scale.</p><p>Managed PaaS alternatives are a transitional step, not a destination. They solve the immediate Heroku problem and recreate the structural lock-in problem. Teams with enterprise ambitions discover this ceiling within 12&#8211;18 months.</p><p>Raw AWS without a platform layer solves the infrastructure ownership problem and creates a developer experience regression that erodes the infrastructure benefits. The two problems require two solutions, infrastructure ownership and developer experience preservation, not one.</p><p>AWS-native Internal Developer Platforms are the pattern the community validates for production SaaS teams at scale. Infrastructure in your own account. Developer experience preserved. No new vendor dependency. No compliance ceiling. Cost structure that scales proportionally with usage rather than in tier jumps.</p><p>The best Heroku alternatives in 2026 are the ones that solve the immediate migration problem and the long-term infrastructure ownership problem simultaneously, so the migration is made once, under conditions the team controls, and does not need to be repeated.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call &#8594;</a></strong> Our engineers review your current Heroku setup and walk through what the migration looks like for your specific stack.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started for Free &#8594;</a></strong> First production environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Heroku Migration Guide &#8594;</a></strong> Full technical walkthrough, database migration, environment setup, DNS cutover.</p>]]></content:encoded></item><item><title><![CDATA[The Real Cost of Heroku at Scale: A Teardown for CTOs Evaluating Alternatives]]></title><description><![CDATA[Beyond the Invoice: Understanding Heroku&#8217;s True Cost for Scaling SaaS Teams]]></description><link>https://blog.localops.co/p/the-real-cost-of-heroku-at-scale</link><guid isPermaLink="false">https://blog.localops.co/p/the-real-cost-of-heroku-at-scale</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Tue, 07 Apr 2026 05:32:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_xn7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.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_!_xn7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_xn7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png 424w, https://substackcdn.com/image/fetch/$s_!_xn7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png 848w, https://substackcdn.com/image/fetch/$s_!_xn7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png 1272w, https://substackcdn.com/image/fetch/$s_!_xn7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_xn7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png" width="2400" height="1408" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1408,&quot;width&quot;:2400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6718208,&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://blog.localops.co/i/193316405?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a2f06c-3709-4140-8fba-406b71956f3b_2400x1600.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_!_xn7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png 424w, https://substackcdn.com/image/fetch/$s_!_xn7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png 848w, https://substackcdn.com/image/fetch/$s_!_xn7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.png 1272w, https://substackcdn.com/image/fetch/$s_!_xn7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca9cd71-566e-4ef8-9138-08e85acfdf46_2400x1408.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>The real cost of Heroku is not what appears on the invoice.</p><p>The invoice is the visible portion: dyno tiers, database add-ons, Redis instances, and monitoring tools. It is real, it compounds, and it grows faster than  engineering leaders expect. But for  Series A and beyond SaaS teams, the invoice cost is the smallest component of what Heroku actually costs the business.</p><p>The higher costs are the ones that do not appear on any statement: the engineering hours spent working around platform limitations instead of building products, the architectural decisions shaped by what Heroku supports rather than what the system needs, and the enterprise deals that stall or never close because the infrastructure cannot satisfy the security questionnaire.</p><p>This guide is a complete cost teardown. It is written for CTOs who are evaluating whether the infrastructure decision in front of them is an operational one or a strategic one.</p><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> The complete cost of Heroku at scale, invoice cost, add-on compounding, engineering opportunity cost, observability stack costs, and the true total cost calculation versus migrating to AWS</p><p><strong>Who it is for:</strong> CTOs and engineering leaders evaluating whether the financial case for migrating from Heroku justifies the migration investment</p><p><strong>The conclusion:</strong> The invoice cost is only one of three cost components. For  B2B SaaS teams at Series A and beyond, the compliance cost and engineering opportunity cost together exceed the infrastructure invoice, and neither appears in standard infrastructure reviews.</p><p><strong>Want to model what your Heroku setup costs on LocalOps + AWS?</strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> Speak with the LocalOps team</a></p><h2><strong>When Heroku&#8217;s Pricing Becomes Financially Indefensible</strong></h2><p>Heroku&#8217;s pricing model does not become a problem at a specific team size or traffic level. It becomes a problem at a specific combination of service count, add-on depth, and business ambition, and that combination arrives faster than  teams expect.</p><p>The inflection point for  B2B SaaS teams arrives somewhere between five and fifteen engineers. Not because the team is large. Because product complexity at that stage drives service count past the point where add-on costs become a significant and compounding line item.</p><p><strong>What the inflection looks like in practice:</strong></p><p>A team running a single production application on Heroku has a manageable bill. One dyno tier. One Heroku Postgres instance. One Redis instance. Maybe Papertrail for logs. The total is meaningful but explainable.</p><p>A team running five production services on Heroku has a fundamentally different cost structure. Each service has its own dyno configuration. Each service typically requires its own database tier. Heroku Postgres pricing is per-instance, not shared across services. Each service adds to the Redis connection count, pushing toward higher Redis tiers. Log volume across five services pushes Papertrail into higher pricing tiers. APM costs multiply across services.</p><p>The relationship between service count and cost is not linear on Heroku. It is multiplicative. Every new service does not add one cost layer. It adds five: compute, database, cache, logging, and monitoring, each carrying a platform margin.</p><p><strong>What the comparison looks like when migrating to AWS:</strong></p><p>The cost difference between Heroku and AWS via an Internal Developer Platform comes from two structural sources. First: the platform margin disappears <em>entirely</em>. Compute, database, cache, and job queue resources run at AWS list pricing with no markup. Second: observability is included. LocalOps includes Prometheus, Loki, and Grafana pre-configured in every environment at no additional cost, eliminating the Papertrail, New Relic, and APM add-on line items entirely.</p><p>The direction of this difference is structural. It does not change with scale; AWS pricing without a platform margin is 3-4x lower than PaaS pricing with one. The size of the difference depends on stack composition. For a model based on your current Heroku invoice,<a href="https://go.localops.co/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> the LocalOps team will calculate it directly</a>.</p><h2><strong>Why Heroku Add-On Costs Grow Faster Than Revenue</strong></h2><p>This is the cost dynamic that surprises engineering leaders when they first examine it systematically. Heroku&#8217;s add-on costs do not scale with revenue. They scale with product complexity, and product complexity grows faster than revenue at  SaaS companies in the growth stage.</p><p><strong>The Heroku Postgres compounding problem.</strong></p><p>Heroku Postgres pricing is structured around tiers defined by row limits, connection limits, and storage. As applications grow, databases move through these tiers, but not in proportion to actual usage growth. A database that grows from 5 million to 7 million rows may jump a full pricing tier even though the actual resource consumption increase is modest. More significantly, in a multi-service architecture, each service typically requires its own Heroku Postgres instance. The database cost compounds per service, not per application.</p><p><strong>The Heroku Redis compounding problem.</strong></p><p>Heroku Redis pricing is structured around connection limits and memory. As more services connect to Redis, for session management, job queuing, caching, and pub/sub, the connection count drives tier upgrades. Redis tier upgrades on Heroku are significant price jumps. And like Postgres, a multi-service architecture typically requires multiple Redis instances, each on its own billing tier.</p><p><strong>The monitoring add-on compounding problem.</strong></p><p>Papertrail pricing scales with log volume. As service count grows, log volume grows, typically faster than traffic growth, because more services mean more internal log output independent of external request volume. New Relic and Scout APM pricing scales with host count or service count. Adding a new service does not just add compute cost. It adds monitoring cost across every observability add-on in the stack.</p><p><strong>The AWS-native alternative cost structure:</strong></p><p>On AWS via LocalOps, the cost structure is fundamentally different. Amazon RDS pricing is based on instance type and storage, not on row counts or arbitrary tier boundaries. A database with 7 million rows costs the same as a database with 5 million rows if the instance type handles both. Amazon ElastiCache pricing is based on node type and replication configuration, not on connection count tiers that force upgrades as services scale. And observability, logs, metrics, and dashboards are included in LocalOps at no additional cost, regardless of service count or log volume.</p><p>The structural difference: Heroku add-on costs are designed around tier boundaries that create forced upgrades as applications grow. AWS-native services are priced on actual resource consumption with no artificial tier boundaries driving cost jumps.</p><p><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how the full Heroku to AWS stack mapping works</a></p><h2><strong>The True Total Cost of Heroku: What CTOs Miss in the Analysis</strong></h2><p>The Heroku cost analysis that surfaces in infrastructure reviews covers only the invoice. For a CTO preparing a board-level infrastructure recommendation, the invoice is the wrong starting point.</p><p>The true total cost of Heroku has three components.</p><h3><strong>Component 1: The Invoice Cost</strong></h3><p>The visible portion. Dyno tiers, database add-ons, Redis instances, monitoring tools, scheduler add-ons, and log management. This is the number that appears on the credit card statement and in the finance team&#8217;s questions.</p><p>It is real, and it compounds, but for  Series A and beyond teams, it is not the largest cost component.</p><h3><strong>Component 2: The Engineering Opportunity Cost</strong></h3><p>The hours engineering teams spend working around Heroku&#8217;s limitations rather than building a product. This cost does not appear on any invoice. It accumulates in recognizable patterns that every engineering leader at a scaling SaaS company has observed.</p><p>A senior architect scopes a feature differently because the technically correct implementation requires a storage pattern that Heroku handles poorly. A backend engineer spends three days building a workaround for a networking limitation that VPC-native infrastructure would handle natively. A team defers a microservices decomposition they know is right for the product because the operational complexity on Heroku is prohibitive without underlying networking primitives.</p><p>None of these decisions appears as infrastructure costs. All of them are real costs, paid in engineering time, in technical debt, and in product decisions made to serve the platform rather than the customer.</p><p>For a Series B SaaS company with fifteen engineers at an average fully-loaded cost of $200,000 per year, every engineering hour is worth approximately $100. If Heroku&#8217;s limitations consume two hours per engineer per week in workarounds, delayed decisions, and architectural compromises, the annual opportunity cost exceeds $150,000. This cost does not appear anywhere in infrastructure reviews. It is often the largest cost component.</p><h3><strong>Component 3: The Compliance Revenue Cost</strong></h3><p>For B2B SaaS teams with an enterprise go-to-market motion, this is frequently the significant cost component and the least visible until an enterprise deal surfaces.</p><p>Enterprise procurement processes require infrastructure controls that Heroku cannot provide: VPC isolation, private networking between services, IAM-based access control with audit logging, dedicated infrastructure and data residency in a specified region. When the security questionnaire arrives, and the honest answer to every infrastructure question is &#8220;we don&#8217;t control that,&#8221; the deal quickly starts going south.</p><p>The revenue impact of this infrastructure gap is real and calculable. A single $150,000 ARR enterprise deal delayed by one quarter because of infrastructure compliance questions costs $37,500 in revenue timing. A single deal that never closes because the infrastructure cannot satisfy the security review costs the full contract value. For a company with multiple enterprise deals in the pipeline, the compliance cost of staying on Heroku can dwarf every other cost component combined.</p><h3><strong>The Total Cost Calculation</strong></h3><p>When CTOs present the infrastructure transition to their board or CEO, the analysis that generates alignment is the one that includes all three components.</p><p><strong>Invoice savings:</strong> structural, predictable, and begin immediately on migration. The platform margin disappears. Observability add-on costs disappear.</p><p><strong>Engineering opportunity cost recovery:</strong> directionally clear, grows with team size. Senior engineering hours redirected from platform workarounds to product development.</p><p><strong>Compliance revenue unlock:</strong> the component that makes the migration financially obvious for any B2B SaaS team with enterprise ambitions. Infrastructure that answers the security questionnaire cleanly is infrastructure that does not block deals.</p><p>Together, these three components reframe the infrastructure migration from an operational cost to a strategic investment with a compounding return.</p><h2><strong>Why Heroku&#8217;s Tier-Based Pricing Fails SaaS Companies</strong></h2><p>Heroku&#8217;s pricing model was designed for simplicity at a small scale. It is structurally misaligned with how SaaS businesses actually grow and operate at scale.</p><p><strong>The tier-jump problem.</strong></p><p>Heroku pricing scales in tiers, not proportionally with usage. When resource requirements grow past a tier boundary, the cost jumps to the next tier regardless of whether actual usage justifies the full tier ceiling. Teams pay for the tier ceiling, not for actual consumption.</p><p>For finance teams preparing infrastructure forecasts, this makes cost modeling unreliable. Infrastructure spend jumps at irregular intervals unrelated to business growth metrics. A 20% increase in traffic does not produce a 20% increase in infrastructure cost; it might produce a 0% increase or a 40% jump, depending on where the team sits relative to tier boundaries.</p><p><strong>The seasonal traffic problem.</strong></p><p>Many SaaS applications have non-linear traffic patterns. B2B applications peak during business hours and drop to near-zero overnight and on weekends. Consumer applications spike around product launches and marketing campaigns. Event-driven workloads process jobs in bursts that may be 10x the average load.</p><p>Heroku&#8217;s response to all of these patterns is identical: provision for peak capacity and pay for it continuously. Go to the performance tier, pay us more to save more. Teams either over-provision, paying for idle capacity at all times, or under-provision and accept performance degradation during spikes.</p><p>AWS horizontal autoscaling on EKS responds to this directly. Workloads scale out when traffic increases and back in when it drops, automatically, without human intervention. Teams pay for actual compute consumption proportional to real usage, not for the tier ceiling required to handle the peak.</p><p><strong>The predictability gap.</strong></p><p>For a CTO preparing a 12-month infrastructure budget, Heroku&#8217;s tier-based model creates a forecasting problem. The budget for next year is not last year&#8217;s Heroku invoice scaled by growth. It is last year&#8217;s invoice scaled by growth, plus the tier-jump events triggered by crossing the service count and traffic thresholds the product roadmap implies.</p><p>AWS-native infrastructure priced by actual consumption solves this forecasting problem directly. Infrastructure spend grows in proportion to actual usage. Budget modeling is straightforward. Surprises are eliminated.</p><p><a href="https://localops.co/features/auto-scaling?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how autoscaling works by default on LocalOps &#8594;</a></p><p><strong>The Real Cost of the Heroku Observability Stack</strong></p><p>This is the cost teams underestimate, until they look at the Heroku invoice line by line and add up what monitoring actually costs.</p><p>A typical production Heroku stack assembles observability from multiple paid add-ons:</p><p><strong>Papertrail</strong> for log management. Pricing scales by log volume, which grows with service count and traffic regardless of optimization. At production scale with multiple services, Papertrail costs accumulate quickly as log volume grows past free tier limits.</p><p><strong>New Relic or Scout</strong> for application performance monitoring. APM pricing on Heroku add-ons scales with host count or agent count. Every new service added to the production stack adds another APM agent, another billing line item that compounds with each new service deployment.</p><p><strong>Additional tools</strong> for error tracking, uptime monitoring, and alerting, each with their own pricing tier, their own billing cycle, and their own failure modes.</p><p><strong>The operational cost beyond the financial one:</strong></p><p>The financial cost of the Heroku observability stack is significant. The operational cost is often larger.</p><p>When an incident occurs at 2 am, a Heroku team correlates information across multiple dashboards from multiple vendors with different data models and different refresh rates. Logs in Papertrail. Metrics in New Relic. The relationship between a spike in error rates and a specific deployment requires context-switching between tools. Each tool switch adds minutes to incident response time. For SaaS applications with customer-facing SLAs, those minutes matter.</p><p>The tools are often configured independently with no unified alerting model. An alert threshold set in New Relic does not automatically correlate with a log pattern in Papertrail. Building that correlation requires manual work, or accepting that incidents will be identified more slowly than they would be on a platform with integrated observability.</p><p><strong>What integrated observability looks like:</strong></p><p>LocalOps includes Prometheus, Loki, and Grafana pre-configured in every environment at no additional cost.</p><p>Prometheus collects metrics automatically from every service, CPU, memory, request rate, error rate, and custom application metrics. No agent installation. No per-service configuration.</p><p>Loki aggregates logs from all services through standard output. No log drain configuration. No Papertrail account. No log volume pricing tiers.</p><p>Grafana provides unified dashboards with pre-built views for infrastructure metrics and application logs in a single interface. When something breaks at 2 am, logs and metrics are in the same place, with the same timestamps, correlated automatically.</p><p>The observability tools that are monthly line items on a Heroku invoice, adding up to hundreds of dollars per month for a typical production stack, are included in LocalOps as infrastructure. There is no add-on to configure. There is no additional cost. There is no vendor to manage.</p><p><a href="https://localops.co/features/builtin-monitoring?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how built-in monitoring works on LocalOps</a></p><h2><strong>How LocalOps Addresses the Cost Problem Structurally</strong></h2><p>LocalOps is an AWS-native Internal Developer Platform built specifically for teams replacing Heroku.</p><p>Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and a complete observability stack, Prometheus, Loki, and Grafana, automatically. No Terraform. No Helm charts. No manual configuration. First environment ready in under 30 minutes.</p><p>From that point, the developer experience is identical to Heroku. Push to your configured branch. LocalOps builds, containerizes, and deploys to AWS automatically. Logs and metrics are available from day one. Autoscaling and auto-healing run by default.</p><p>The cost structure is fundamentally different from Heroku. LocalOps charges a flat platform fee. The underlying infrastructure runs at AWS list pricing with no markup. Observability is included. The tier-jump cost model is replaced by proportional pricing that scales with actual usage.</p><p>The infrastructure runs in your AWS account. If you stop using LocalOps, it keeps running. Nothing needs to be rebuilt.</p><blockquote><p><em>&#8220;Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221; <strong>&#8211;</strong></em> <strong> Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</strong></p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort, all of which LocalOps has saved for us.&#8221;</em> <strong>&#8211; Gaurav Verma, CTO and Co-founder, SuprSend</strong></p></blockquote><p><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get started for free, first environment on AWS in under 30 minutes &#8594;</a></p><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>At what point does Heroku&#8217;s pricing become financially indefensible?</strong></p></li></ol><p>The inflection point varies by stack composition but consistently arrives when service count grows past five and add-on costs begin compounding across multiple services simultaneously. The signal is not the absolute invoice amount; it is when the invoice becomes difficult to attribute cleanly across services, difficult to forecast accurately, and impossible to optimize without changing the underlying platform. For  B2B SaaS teams, this happens between five and fifteen engineers, driven by product complexity rather than team size directly.</p><ol start="2"><li><p><strong>Why do Heroku add-on costs grow faster than revenue as SaaS teams scale?</strong></p></li></ol><p>Heroku add-on costs scale with product complexity rather than with revenue. Adding a new service to a Heroku production stack does not add one cost layer; it adds compute, database, Redis, logging, and monitoring costs simultaneously, each carrying a platform margin. Database tier pricing is driven by row counts and connection limits that force upgrades independently of revenue growth. Log volume and APM agent counts scale with service count rather than with business metrics. The result is a cost structure where infrastructure spend grows faster than revenue at precisely the growth stage where unit economics matter.</p><ol start="3"><li><p><strong>How should a CTO calculate the true total cost of Heroku?</strong></p></li></ol><p>The full calculation has three components. Invoice cost: dyno tiers, database add-ons, Redis, monitoring tools, scheduler, totalled across all production services. Engineering opportunity cost: hours spent on platform workarounds, architectural compromises made to serve Heroku&#8217;s limitations, and deferred technical decisions that accumulate as debt. Compliance revenue cost: Deals are delayed or lost because the infrastructure cannot satisfy enterprise security questionnaires. For  Series A and beyond B2B SaaS teams with enterprise ambitions, the compliance revenue component is the largest and least visible, and the one that makes the migration decision strategically obvious when it surfaces.</p><ol start="4"><li><p><strong>Why is Heroku&#8217;s tier-based pricing misaligned for seasonal or variable traffic?</strong></p></li></ol><p>Heroku requires teams to provision for peak capacity and pay for it continuously; there is no automatic scale-down when traffic drops. For B2B applications with sharp usage peaks during business hours, consumer applications with campaign-driven spikes, or any application with variable traffic patterns, the choice is between over-provisioning at continuous cost or under-provisioning and accepting performance degradation. AWS horizontal autoscaling on EKS scales out when the load increases and back in when it drops automatically. Teams pay for actual compute consumption, not for the tier ceiling required to handle the peak.</p><ol start="5"><li><p><strong>What does the Heroku observability stack actually cost at production scale?</strong></p></li></ol><p>A typical production Heroku stack assembles observability from Papertrail for log management, New Relic or Scout for APM, and potentially additional tools for error tracking and uptime monitoring. Each add-on has its own pricing tier that scales with usage, log volume for Papertrail, host or service count for APM tools. The combined cost compounds with the service count. Beyond the financial cost, the operational cost of correlating logs and metrics across multiple disconnected tools adds meaningful time to incident response. LocalOps includes Prometheus, Loki, and Grafana pre-configured in every environment at no additional cost, replacing the entire assembled observability stack with integrated tooling that provides better correlated visibility at zero marginal cost.</p><ol start="6"><li><p><strong>What is the difference between a Heroku self-hosted alternative and an AWS-native IDP in terms of cost?</strong></p></li></ol><p>A Heroku self-hosted alternative like Coolify or Dokku eliminates platform margin on infrastructure but requires the team to own the full operational burden, provisioning, security patching, observability setup, and on-call response for the platform itself. The infrastructure cost is lower. The engineering cost of running the platform is high and ongoing. An AWS-native IDP like LocalOps provides the same infrastructure cost efficiency, direct AWS pricing, and no platform margin, with the platform layer managed. For teams without dedicated platform engineering capacity, the total cost of a self-hosted alternative consistently exceeds the total cost of a managed IDP once engineering hours for platform maintenance are included.</p><ol start="7"><li><p><strong>How do Heroku&#8217;s open source alternatives compare on observability cost?</strong></p></li></ol><p>Heroku open source alternatives eliminate the platform margin on compute and managed services. They do not eliminate the observability cost problem; they shift it. Rather than paying for Papertrail and New Relic, teams running open-source alternatives take on the engineering cost of setting up, configuring, and maintaining their own observability stack. Prometheus, Loki, and Grafana are available as open-source tools, but setting them up correctly, integrating them with application infrastructure, and maintaining them over time requires engineering investment. LocalOps includes this observability stack pre-configured as part of the platform; the setup work is done, the maintenance is handled, and the cost is zero beyond the platform fee.</p><h2><strong>Key Takeaways</strong></h2><p>The real cost of Heroku at scale has three components, and  infrastructure reviews only examine one of them.</p><p>The invoice cost is real, and compounds with every service added. The engineering opportunity cost is rarely measured but consistently significant for teams running more than five services. The compliance revenue cost is the largest component for any B2B SaaS team with enterprise ambitions, and the one that makes the migration decision strategically obvious rather than operationally optional.</p><p>The observability cost is a specific case study in how Heroku&#8217;s add-on model creates financial and operational overhead that integrated platforms eliminate. Hundreds of dollars per month in add-on fees, plus the operational cost of correlating incidents across disconnected tools, are replaced by a pre-configured observability stack at no additional cost.</p><p>For CTOs preparing the business case for infrastructure migration, the frame that generates board-level alignment is not &#8220;we should save money on infrastructure.&#8221; It is &#8220;we are currently paying a tax on every enterprise deal we close, and the migration eliminates that tax while also reducing infrastructure costs and recovering engineering capacity.&#8221;</p><p>That is the real cost of Heroku at scale. And that is the case for moving.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call &#8594;</a></strong> Our engineers model your current Heroku costs against LocalOps + AWS and walk through the migration for your specific stack.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started for Free &#8594;</a></strong> First production environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Heroku Migration Guide &#8594;</a></strong> Full technical walkthrough, database migration, environment setup, DNS cutover.</p>]]></content:encoded></item><item><title><![CDATA[Kubernetes vs Internal Developer Platform: Do You Need Both for AWS Deployments?]]></title><description><![CDATA[A practical breakdown for engineering teams choosing between raw Kubernetes and an IDP on AWS]]></description><link>https://blog.localops.co/p/kubernetes-vs-internal-developer-platform-aws</link><guid isPermaLink="false">https://blog.localops.co/p/kubernetes-vs-internal-developer-platform-aws</guid><dc:creator><![CDATA[Madhushree Sivakumar]]></dc:creator><pubDate>Fri, 03 Apr 2026 12:27:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Tr-6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.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_!Tr-6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tr-6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png 424w, https://substackcdn.com/image/fetch/$s_!Tr-6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png 848w, https://substackcdn.com/image/fetch/$s_!Tr-6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!Tr-6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tr-6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.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;:5024677,&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://blog.localops.co/i/193060504?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.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_!Tr-6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png 424w, https://substackcdn.com/image/fetch/$s_!Tr-6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png 848w, https://substackcdn.com/image/fetch/$s_!Tr-6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!Tr-6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f3414e-fb3b-4c5b-ac8b-cb70c1681c90_2400x1600.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>The majority of AWS teams running containers have landed on Kubernetes. According to the 2025 CNCF Annual Cloud Native Survey, 82% of container users now run Kubernetes in production, a number<a href="https://aws.amazon.com/blogs/containers/aws-at-kubecon-eu-2026-open-source-leadership-meets-production-innovation/"> AWS continues to see grow</a> across EKS deployments. It is the default choice for containerised workloads and EKS makes it accessible enough that most teams land there eventually.</p><p>But at some point the same teams start looking at internal developer platforms. And the question that comes up is a reasonable one: if Kubernetes already handles deployments, container orchestration, scaling, and health checks, what does an IDP actually add? Are these two separate tools solving two different problems, or is one replacing the other?</p><p>The answer is not obvious. On AWS, the boundaries blur quickly. EKS integrates deeply with IAM, networking, and other managed services, which makes Kubernetes feel like it should be enough. But in practice, teams still run into gaps around how developers interact with that infrastructure.</p><p>This post breaks down where each one starts, where it ends, and whether you actually need both running together on AWS.</p><h2>TL;DR</h2><ul><li><p>Amazon EKS runs your containers. An internal developer platform defines how engineers actually deploy and operate them.</p></li><li><p>A well-designed IDP on AWS does not just connect to a cluster. It standardises how infrastructure like VPCs, EKS, CI/CD, and observability are provisioned and used.</p></li><li><p>Developers push code. The platform handles everything underneath.</p></li><li><p>You still need Kubernetes. The real question is whether every engineer should be dealing with it directly on every deploy.</p></li><li><p>The shift toward IDPs is generally the right call, but only if the platform is designed with escape hatches. When something breaks at the Kubernetes level, engineers with zero cluster knowledge cannot debug it.</p></li><li><p>Most teams do not make this shift intentionally. They make it when the alternative stops working.</p></li></ul><h2>What Kubernetes Handles on AWS and Where It Stops</h2><p>Kubernetes is a container orchestration system. It schedules containers across a pool of compute, manages service-to-service networking, restarts failed workloads, and scales pod replicas based on load. On AWS, EKS is the managed Kubernetes service. AWS handles the control plane &#8212; the API server and etcd &#8212; so you do not operate those components yourself.</p><p>What stays with your team in a standard EKS setup: VPC design, subnets, NAT gateways, and security group rules. IAM setup, including role bindings and service account mapping. Choosing and managing node groups. Installing and configuring cluster add-ons like CoreDNS, VPC CNI, and the AWS Load Balancer Controller. Planning and executing Kubernetes version upgrades.</p><p>EKS Auto Mode extends AWS management further into the data plane and handles more of the node lifecycle automatically. But even with Auto Mode, platform design, developer workflows, environment management, and delivery standardisation remain your responsibility.</p><p>This is where the internal developer platform question starts. Kubernetes handles the runtime. It does not handle how your developers interact with that runtime. It does not create environments, wire CI/CD pipelines, or give a backend engineer a self-service path to deploy a new service without understanding the cluster underneath.</p><p>That layer has to come from somewhere. On AWS, that is what an IDP is for.</p><h2>Kubernetes vs IDP: What Each One Actually Does on AWS</h2><p>Most teams assume Kubernetes and an IDP overlap significantly. They do overlap in deployment automation, but they operate at different abstraction levels and solve different problems.</p><p>Kubernetes is the orchestration and runtime layer. It schedules containers, maintains workload state, handles service discovery, and scales pods. An internal developer platform is the developer experience and automation layer above it. It shapes how engineers create environments, deploy services, access observability, and interact with shared infrastructure &#8212; without needing to touch the cluster directly.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/So8V9/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fad25816-906d-4387-b466-1d158a3a2fed_1220x816.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/93077a61-1952-480f-b477-050a4f4c879a_1220x816.png&quot;,&quot;height&quot;:406,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/So8V9/1/" width="730" height="406" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>The confusion usually comes from the fact that both touch deployments. </p><blockquote><p>But Kubernetes manages how containers run. An IDP manages how developers deploy. </p></blockquote><p>On AWS, a platform like LocalOps does not sit beside EKS &#8212; it provisions EKS, manages surrounding AWS resources, and abstracts cluster complexity away from engineers who should not need to think about it on every deploy.</p><p>Kubernetes runs the workloads. The IDP simplifies how developers consume the platform. You need both.</p><h2>How an IDP Handles What Kubernetes Does Not on AWS</h2><p>Kubernetes does not provision environments. It does not wire CI/CD pipelines. It does not give a backend engineer a self-service path to deploy a new service without touching cluster config. Those are not gaps in Kubernetes &#8212; it was never designed to do those things. But someone on your team ends up doing them anyway, usually the person who set up the cluster.</p><p>An IDP takes that work off the individual and puts it at the platform level. When a developer pushes to a branch, the platform handles VPC provisioning, EKS cluster setup, EC2 node configuration, CI/CD pipeline wiring, auto-scaling, SSL, and deployment. The developer writes a service config file. The infrastructure side is handled by the platform.</p><p>No Dockerfile. No Terraform. No Helm required from the developer&#8217;s side.</p><p>The trade-off is real though. Full abstraction means engineers lose visibility into what is running underneath. When a pod enters CrashLoopBackOff or a service fails a health check, an engineer who has never touched kubectl cannot diagnose it. A well-built IDP handles this by exposing controlled access to the cluster when needed. Engineers should not need Kubernetes knowledge for routine deploys, but they should be able to get to it when something goes wrong.</p><h2>What an IDP Actually Sets Up in Your AWS Account</h2><p>When you create a new environment, a production-grade IDP provisions the following inside your AWS account:</p><ul><li><p>Dedicated VPC with private and public subnets, NAT gateway, and internet gateway</p></li><li><p>Managed EKS cluster with EC2 compute nodes</p></li><li><p>Elastic Load Balancer for inbound HTTP/HTTPS traffic</p></li><li><p>Prometheus, Loki, and Grafana for metrics, log aggregation, and dashboards</p></li><li><p>Managed AWS services on demand: RDS, S3, SQS, Elasticache</p></li><li><p>CI/CD pipeline triggered on branch push</p></li><li><p>Auto-renewing SSL certificates, encrypted secrets storage, and role-based access control</p></li></ul><p>Everything runs inside your AWS account. The vendor does not hold your data or access your infrastructure directly.</p><p>Each environment is isolated at the VPC level. For BYOC deployments where enterprise customers bring their own AWS account, the entire stack gets provisioned inside the customer&#8217;s account. Each customer gets their own cluster, their own VPC, their own compute. That is the architecture enterprise compliance frameworks typically require.</p><p>SuprSend, a notification infrastructure company, used LocalOps to handle this entire setup for their BYOC (Bring your own cloud) distribution. Before that, every enterprise customer deal required spinning up dedicated infrastructure manually. </p><p>LocalOps is provisioning the per-customer AWS environments in 30mins without changing how their engineering team works &#8212; same git-push workflow, same branch-based deploys, just running inside each customer&#8217;s own AWS account. They are able to close enterprise deals faster without adding DevOps headcount. For the full picture, read the case study from their CTO:<a href="https://localops.co/case-study/suprsend-unlocks-enterprise-revenue-byoc"> How SuprSend Unlocks Enterprise Revenue with BYOC</a></p><p>Without an IDP, someone on your team is doing all of this manually, per environment, every time a new one is needed.</p><h2>Backstage, Port and an IDP: Which One Works for AWS Teams</h2><p>Only 28% of organisations have a dedicated DevOps / platform engineering team responsible for internal platforms, according to the Q1 2026 CNCF Technology Landscape Radar report.<a href="https://www.prnewswire.com/news-releases/cncf-and-slashdata-report-finds-platform-engineering-tools-maturing-as-organizations-prepare-for-ai-driven-infrastructure-302722721.html"> PR Newswire</a> That number matters when evaluating IDP options because most DevOps tools assume you have that team already.</p><p>Before comparing tools, one distinction worth clarifying: an internal developer portal vs platform is not just a naming difference. A portal surfaces information about existing infrastructure. A platform provisions and manages cloud resources. This matters because Backstage, the most widely used open source internal developer platform, is actually a portal. It gives you a service catalog and a UI layer but does not provision infrastructure or manage deployments out of the box.</p><p>Teams searching for a Backstage internal developer platform often discover this gap after they have already invested months in setup. Backstage needs integrations and plugins to act as a full platform. You build those yourself. Right call if you have the platform engineering capacity/team to sustain it internally.</p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/94C8j/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06fad217-4625-4ea7-a96a-0a055caa1de4_1220x1092.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b01320d0-0395-42bc-93e3-4257ff736b46_1220x1092.png&quot;,&quot;height&quot;:548,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/94C8j/1/" width="730" height="548" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>Port works well as a catalog and visibility layer on top of existing infrastructure. A cloud native IDP fits teams that need production-grade AWS environments running without the upfront platform investment.  Not sure which fits your stack?<a href="https://cal.com/anand-localops/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog"> Book a demo with us</a> and our engineer will walk you through it.</p><h2>Do You Still Need a DevOps Engineer If You Have an IDP on AWS?</h2><p>Short answer: yes. But the actual role changes significantly.</p><p>According to CNCF survey data, organisations typically allocate one platform engineer per 17 to 50 developers &#8212; roughly 2 to 6% of total engineering headcount.<a href="https://byteiota.com/platform-engineering-2026-80-adoption-devops-dead/"> byteiota</a> That ratio only works if the platform is handling routine infrastructure work. Without an IDP, that one person becomes the bottleneck for every deployment question, every new environment, and every EKS config change on the team.</p><p>With an IDP, that same engineer sets the platform up once. Developers provision environments, deploy services, and access observability without filing a ticket. The DevOps or platform engineer shifts to work that actually requires their expertise: cost architecture, security posture, compliance requirements, and reliability engineering.</p><p>High-maturity platform teams report 40 to 50% reductions in cognitive load for developers.<a href="https://dev.to/meena_nukala/platform-engineering-in-2026-the-numbers-behind-the-boom-and-why-its-transforming-devops-381l"> DEV Community</a> That is not just a developer experience metric. It directly affects how fast product teams ship and how much of your engineering budget goes toward infrastructure overhead versus product work.</p><p>What an IDP still cannot replace on AWS:</p><ul><li><p>Reserved Instance and Savings Plan strategy</p></li><li><p>Custom VPC architectures for specific compliance frameworks</p></li><li><p>Multi-account setups with complex permission boundaries</p></li><li><p>Incident response when something breaks at the infrastructure level</p></li></ul><p>The abstraction trade-off is real. When a pod enters CrashLoopBackOff or a node group fails to scale, someone needs to know what they are looking at. An IDP reduces how often engineers hit those situations. It does not eliminate them. Teams should maintain baseline Kubernetes literacy even if developers do not use it daily.</p><p>Teams that delay building this layer tend to accumulate technical debt quietly. Helm chart configurations drift across services, cluster knowledge stays siloed with one or two people, and onboarding new engineers to the deployment process takes longer than it should.</p><h2>What to Look for Before Choosing an IDP for AWS</h2><p>Not all IDPs that claim AWS support are built the same way. Before committing, these are the questions worth asking:</p><p><strong>Does it provision EKS or just connect to one you already have?</strong> Connecting to an existing cluster means you still own the setup, configuration, and upgrade cycle. Provisioning means the platform handles the full lifecycle.</p><p><strong>Does it require developers to write Helm charts?</strong> Helm support for engineers who need it is fine. Requiring it from everyone means you have moved the complexity rather than removed it.</p><p><strong>Is observability included or a separate integration?</strong> Prometheus, Loki, and Grafana should come with the platform. Wiring observability after the fact is a project in itself.</p><p><strong>Does it provision managed AWS services from the same interface?</strong> RDS, S3, SQS, Elasticache &#8212; if these require a separate Terraform repo, you have two systems to maintain instead of one.</p><p><strong>Does your data stay in your AWS account?</strong> The vendor should not have direct access to your application data or infrastructure. Everything should run inside your own account.</p><p><strong>Can you eject if you need to?</strong> Vendor lock-in is a real consideration. If you stop using the platform, you should be able to take the infrastructure and run it independently.</p><p><strong>Does it fit your deployment model?</strong> SaaS, single-tenant, BYOC, and self-hosted have different infrastructure requirements. The platform should support your model without requiring custom tooling for each.</p><p>To see how LocalOps specifically handles these on AWS, the<a href="https://docs.localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog"> LocalOps developer documentation</a> covers environment provisioning, EKS setup, observability, BYOC, and the eject path in full detail.</p><h2>FAQs</h2><p><strong>1. What is the best internal developer platform for AWS teams?</strong></p><p>The best internal developer platform for AWS depends on your team size and whether you have a dedicated platform engineering team. Backstage is the most widely adopted open source internal developer platform, but it requires significant setup and maintenance investment, typically 6 to 12 months before developers are using it consistently. For teams that need AWS environments running quickly without dedicated DevOps overhead, a cloud native IDP like LocalOps provisions EKS, observability, and CI/CD inside your AWS account out of the box. Not sure what fits your stack?<a href="https://cal.com/anand-localops/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog"> You can talk to our engineers</a> to help figure it out.</p><p><strong>2. What should an AWS internal developer platform actually do?</strong></p><p>An AWS internal developer platform should provision and manage EKS clusters, handle VPC and subnet configuration, wire CI/CD pipelines, set up observability, and manage access control, all inside your own AWS account. It should give developers a self-service path to deploy services without touching Kubernetes directly. If it only connects to an existing cluster rather than provisioning one, you still own most of the infrastructure complexity yourself.</p><p><strong>3. What does internal developer platform architecture look like on AWS?</strong></p><p>A production-grade internal developer platform architecture on AWS includes a dedicated VPC with private and public subnets, a managed EKS cluster, EC2 compute nodes, an Elastic Load Balancer, Prometheus and Grafana for observability, managed AWS services like RDS and S3, and a CI/CD pipeline wired to branch pushes. Each environment runs in isolation at the VPC level. For BYOC deployments, that entire architecture gets replicated inside the customer&#8217;s AWS account.</p><p><strong>4. Should you build an internal developer platform or buy one for AWS?</strong></p><p>Building gives you full control but requires significant engineering investment. SuprSend estimated that building their BYOC infrastructure setup in-house would have taken 10 to 12 engineer months. Buying a platform like LocalOps reduces that to under 30 minutes for a production-ready environment. Build makes sense if you have a dedicated platform team and specific requirements that off-the-shelf platforms cannot meet. Buying makes sense if your engineering team&#8217;s time is better spent on product work rather than platform infrastructure.</p><p><strong>5. How does platform engineering relate to an internal developer platform?</strong></p><p>Platform engineering and internal developer platform adoption are growing in parallel, but they are not the same thing. Platform engineering is the practice of building and owning developer infrastructure as a product. An internal developer platform is what that practice produces, the actual system engineers use to deploy, provision environments, and access infrastructure. You can run an IDP without a formal platform engineering team. Many smaller teams buy a pre-built IDP specifically to avoid needing one.</p><h2>So Do You Need Both Kubernetes and an IDP on AWS?</h2><p>Yes. But that is not really the right question.</p><p>Kubernetes and an internal developer platform are not competing for the same job. EKS handles container orchestration. An IDP handles how your engineers interact with that orchestration layer without needing to understand it on every deployment. Removing either one creates a gap the other cannot fill.</p><p>The more useful question is what happens when you have Kubernetes but no IDP above it. Environment setup stays manual. Deployment workflows differ across services. New engineers spend days getting cluster access before they contribute anything. The one person who understands the EKS setup becomes the path of least resistance for every infrastructure question on the team.</p><p>An IDP does not make Kubernetes disappear. It makes Kubernetes someone else&#8217;s problem &#8212; specifically, the platform layer&#8217;s problem &#8212; so your product engineers can stay focused on the product.</p><p>Developers are increasingly accessing Kubernetes indirectly through internal developer platforms rather than directly, according to a March 2026 CNCF report covering 12,500 developers across 100 countries.<a href="https://www.cncf.io/announcements/2026/03/24/cncf-and-slashdata-report-finds-cloud-native-community-reaches-nearly-20-million-developers/"> Cloud Native Computing Foundation</a> That shift is not happening because Kubernetes is being replaced. It is happening because teams have realised that exposing cluster complexity to every engineer is a choice, not a requirement.</p><p>On AWS, you have the tooling to make that choice cleanly. The question is whether you build the layer above EKS yourself or use a platform that already has it.</p><p>If you&#8217;re figuring out how this would fit into your setup, the LocalOps team can help you work through it:</p><p><strong><a href="https://cal.com/anand-localops/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Book a Demo</a> &#8594;</strong> Walk through how environments, deployments, and AWS infrastructure are handled in practice for your setup.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Get started for free</a> &#8594;</strong> Connect an AWS account and stand up an environment to see how it fits into your existing workflow.</p><p><strong><a href="https://docs.localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Explore the Docs</a> &#8594;</strong> A detailed breakdown of how LocalOps works end-to-end, including architecture, environment setup, security defaults, and where engineering decisions still sit.</p><h2>Related Articles</h2><ol><li><p><a href="https://blog.localops.co/p/what-is-an-internal-developer-platform-idp">What Is an Internal Developer Platform? Definition, Core Components and Real-World Use Cases</a></p></li><li><p><a href="https://blog.localops.co/p/internal-developer-platform-build-vs-buy-cost-comparison">How Much Does It Cost to Build an Internal Developer Platform In-House vs Buying One?</a></p></li><li><p><a href="https://blog.localops.co/p/standardize-dev-staging-prod-internal-developer-platform?">How to Standardize Dev, Staging and Production Environments with an Internal Developer Platform</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Why Your Team Is Outgrowing Heroku - And the Architecture That Comes Next]]></title><description><![CDATA[The cost, scaling, and compliance inflection points that push teams beyond Heroku, and how AWS-native platforms replace it without losing developer experience.]]></description><link>https://blog.localops.co/p/why-your-team-is-outgrowing-heroku</link><guid isPermaLink="false">https://blog.localops.co/p/why-your-team-is-outgrowing-heroku</guid><dc:creator><![CDATA[Nidhi Pandey]]></dc:creator><pubDate>Tue, 31 Mar 2026 06:30:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!johs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.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_!johs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!johs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png 424w, https://substackcdn.com/image/fetch/$s_!johs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png 848w, https://substackcdn.com/image/fetch/$s_!johs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png 1272w, https://substackcdn.com/image/fetch/$s_!johs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!johs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png" width="2400" height="1583" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1583,&quot;width&quot;:2400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7957189,&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://blog.localops.co/i/192598190?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349fd1a1-4702-458b-9e8e-3c4b6ca6169f_2400x1808.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_!johs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png 424w, https://substackcdn.com/image/fetch/$s_!johs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png 848w, https://substackcdn.com/image/fetch/$s_!johs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.png 1272w, https://substackcdn.com/image/fetch/$s_!johs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f38c67-1a77-48c1-a797-8353066275e1_2400x1583.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>Outgrowing Heroku is not a sudden event. It is a pattern that develops over 12 to 18 months and becomes undeniable at a specific inflection point, usually when a cost review, a failed enterprise deal, or a production incident forces the conversation that has been quietly building.</p><p>Most engineering leaders recognize the pattern in retrospect. The Heroku bill was manageable at $500 per month. Then it was $2,000. Then it was $5,000 and growing, fragmented across dyno tiers, database add-ons, monitoring tools, and Redis instances, each scaling independently with no unified optimization lever. The CFO started asking questions that the CTO could not answer cleanly.</p><p>Or the pattern shows up in architecture. The product that started as a monolith now has background workers, event-driven components, and services that need to communicate privately. Heroku handles these patterns poorly. Workarounds accumulate. Senior engineers start spending time on platform constraints rather than product features.</p><p>Or it shows up in a deal. An enterprise prospect sends a security questionnaire. The infrastructure questions, VPC configuration, private networking, and IAM audit logging reveal that the team does not control the infrastructure on which their product runs.</p><p>These are not isolated problems. They are the predictable sequence of constraints that surface as SaaS products mature past what Heroku was designed to support. This guide covers each one, what causes it, and what the architecture that comes next actually looks like.</p><h2><strong>TL;DR</strong></h2><p><strong>What this covers:</strong> The specific points at which Heroku&#8217;s pricing, scaling model, reliability, and architecture become constraints, and what the migration path to a modern alternative looks like</p><p><strong>Who it is for:</strong> CTOs and engineering leaders who recognize the Heroku constraints described above and are evaluating what comes next</p><p><strong>The architecture that replaces Heroku:</strong> AWS-native infrastructure with an Internal Developer Platform layer,  infrastructure you own, developer experience you keep, at direct AWS pricing with no platform margin</p><p><strong>Want to see exactly what a Heroku to AWS migration looks like?</strong> We have covered it in detail -<a href="https://localops.co/migrate-heroku-to-aws?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> localops.co/migrate-heroku-to-aws</a></p><h2><strong>The Pricing Inflection Point: When Heroku Becomes Financially Indefensible</strong></h2><p>Heroku&#8217;s pricing model is not inherently expensive at a small scale. The inflection point arrives at a specific combination of team size, service count, and traffic volume,  and it arrives faster than most teams expect.</p><p>The structural problem is not the per-dyno cost in isolation. It is the compounding of the platform margin across every component of the stack simultaneously.</p><p>A team running five production services on Heroku is typically paying for: Standard-2X dynos at $50 per dyno per month, Heroku Postgres tiers per service, Heroku Redis tiers for caching and job queues, Papertrail or equivalent for log management, New Relic or Scout for APM, and Heroku Scheduler for background jobs. Each component carries a platform margin. Each component scales independently. And each new service added to the product adds another compounding layer of platform cost.</p><p>The inflection point for most B2B SaaS teams arrives when the Heroku invoice stops being explainable as a simple infrastructure cost and starts requiring a detailed breakdown to justify. This typically happens between five and fifteen engineers,  not because the team is large, but because product complexity at that team size drives service count past the point where add-on costs become significant.</p><p><strong>What the comparison looks like when migrating to AWS:</strong></p><p>The cost difference between Heroku and AWS via an Internal Developer Platform comes from two structural sources. First: the platform margin disappears. Compute, database, cache, and job queue resources run at AWS list pricing with no markup. Second: observability is included. LocalOps includes Prometheus, Loki, and Grafana pre-configured in every environment at no additional cost,  eliminating the Papertrail, New Relic, and APM add-on line items entirely.</p><p>The size of the cost reduction depends on stack composition and scale. The direction is structural and does not change with scale. AWS infrastructure pricing without a platform margin is lower than PaaS pricing with one. For a model based on your current Heroku invoice,<a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> speak with the LocalOps team</a>.</p><p><a href="https://docs.localops.co/migrate-to-aws/from-heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See what your Heroku setup costs on LocalOps + AWS</a></p><h2><strong>The True Total Cost of Heroku: What CTOs Miss in the Analysis</strong></h2><p>The Heroku cost analysis that surfaces in most infrastructure reviews covers only the invoice. The invoice is the smallest component of the true total cost.</p><p><strong>Component 1: The invoice cost.</strong></p><p>The visible portion. Dyno tiers, database add-ons, Redis instances, monitoring tools, scheduler add-ons, and log management. This is the number that appears on the credit card statement and in the finance team&#8217;s questions. It is real, and it compounds,  but it is not the largest cost component for most Series A and beyond teams.</p><p><strong>Component 2: The engineering opportunity cost.</strong></p><p>The hours engineering teams spend working around Heroku&#8217;s limitations rather than building a product. This cost does not appear on any invoice. It accumulates in recognizable patterns.</p><p>A senior architect scopes a feature differently because the technically correct implementation requires a storage pattern that Heroku handles poorly. A backend engineer spends three days building a workaround for a networking limitation that VPC-native infrastructure would handle natively. A team defers a microservices decomposition they know is right for the product because the operational complexity on Heroku is prohibitive without the underlying networking primitives.</p><p>None of these decisions appears as infrastructure costs. All of them are real costs,  paid in engineering time, in technical debt, and in product decisions made to serve the platform rather than the customer.</p><p><strong>Component 3: The compliance revenue cost.</strong></p><p>For B2B SaaS teams with an enterprise go-to-market motion, this is frequently the largest cost component and the least visible until an enterprise deal surfaces.</p><p>Enterprise procurement processes require infrastructure controls that Heroku cannot provide: VPC isolation, private networking between services, IAM-based access control with audit logging, and data residency in a specified region. When the security questionnaire arrives, and the honest answer to every infrastructure question is &#8220;we don&#8217;t control that,&#8221; the deal goes into extended security review. Some deals never return from it.</p><p>The revenue impact of infrastructure compliance gaps is difficult to quantify precisely before it surfaces,  and difficult to ignore once it does. For teams building toward enterprise, it is the cost component that makes the Heroku migration decision strategic rather than operational.</p><p><strong>The total cost calculation:</strong></p><p>When CTOs present the infrastructure transition to their board or CEO, the analysis that generates alignment is the one that includes all three components,  not just the infrastructure invoice. Invoice savings are structural and begin immediately. Engineering opportunity cost recovery is directional and grows with team size. Compliance revenue unlock is the component that makes the migration financially obvious for any B2B SaaS team with enterprise ambitions.</p><p><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Walk through the cost comparison with a LocalOps engineer.</a></p><h2><strong>The Vertical Scaling Problem: Why Heroku&#8217;s Dyno Model Breaks at Scale</strong></h2><p>Heroku&#8217;s scaling model is vertical. When an application needs more capacity, the answer is always the same: upgrade to a larger dyno tier or add more dynos. The unit of scale is the dyno. The mechanism is manual.</p><p>This model works for linear, predictable workloads where traffic grows steadily, and scaling decisions can be made deliberately. It does not work for the traffic patterns that characterize most SaaS applications at the growth stage.</p><p><strong>Why vertical scaling fails for high-concurrency APIs:</strong></p><p>High-concurrency APIs do not have linear traffic. They experience request bursts driven by user behavior, webhook deliveries, batch processing jobs, and external events. A payment processor webhook that triggers processing for 10,000 accounts simultaneously. A B2B application that sees 80% of its daily traffic between 9 am and 12 pm in a single timezone. A consumer application that spikes 5x normal volume during a marketing campaign.</p><p>Heroku&#8217;s response to all of these patterns is identical: manually add more dynos before the spike, pay for them whether or not the traffic materializes, and manually remove them afterwards. There is no event-driven scaling that responds to real traffic signals. There is no automatic scale-down when traffic drops. The choice is between continuously over-provisioning, paying for idle capacity, or under-provisioning and accepting degraded performance during spikes.</p><p><strong>How Kubernetes-based alternatives handle burst traffic differently:</strong></p><p>Kubernetes horizontal pod autoscaling responds to real workload signals, CPU utilization, memory pressure, request queue depth, and custom application metrics, automatically and in seconds. When a traffic spike arrives, the platform scales out to handle it. When traffic drops, it scales back in. Teams pay for actual compute consumption rather than for the tier ceiling required to handle the peak.</p><p>For high-concurrency APIs, the operational difference is significant. Kubernetes can scale a service from two instances to twenty in under two minutes in response to a traffic spike, then scale back to two when the spike passes. Heroku requires a manual decision and a manual dyno configuration, and it accepts the cost of overprovisioning during the waiting period.</p><p>LocalOps runs workloads on EKS with horizontal pod autoscaling configured by default. No manual scaling decisions. No dyno tier upgrades. Services scale based on actual traffic signals and scale back automatically when the load drops.</p><p><a href="https://localops.co/features/auto-scaling?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how autoscaling works on LocalOps.</a></p><h2><strong>What Happens to Reliability When a SaaS Product Outgrows Heroku</strong></h2><p>Reliability degradation on Heroku follows a predictable sequence as applications grow past what the Standard dyno tier was designed to support.</p><p><strong>The cold start problem.</strong></p><p>Standard dynos on Heroku sleep after 30 minutes of inactivity and require a cold start when traffic arrives. For production applications, this means the first request after a quiet period experiences significantly elevated response time. For applications with consistent traffic, this is manageable. For applications with variable traffic patterns, common in B2B SaaS,  cold starts create periodic reliability events that are visible to customers and difficult to eliminate without upgrading to Performance dynos at significantly higher cost.</p><p><strong>The resource ceiling problem.</strong></p><p>Standard-2X dynos provide 1GB of memory. For applications with growing data processing requirements, ML inference, or complex query patterns, this ceiling creates memory pressure that manifests as intermittent performance degradation and occasional dyno restarts. The upgrade path to Performance dynos is a significant cost jump with no intermediate steps.</p><p><strong>The shared infrastructure problem.</strong></p><p>Heroku&#8217;s dynos run on shared infrastructure. Noisy neighbor effects, where other tenants on the same physical infrastructure consume resources that affect application performance, are documented and acknowledged by Heroku but are not preventable by teams running on the platform. For SaaS applications with customer-facing SLAs, this is an infrastructure risk that cannot be mitigated without leaving the platform.</p><p><strong>The safest migration path:</strong></p><p>The migration path that minimizes customer-facing reliability risk runs both environments in parallel before any DNS cutover. The new environment, LocalOps provisioning AWS infrastructure in the team&#8217;s own account, receives all the verification traffic while Heroku remains the production environment. Database migration runs with AWS DMS replication to keep both databases synchronized. DNS cutover happens only after the new environment has handled real traffic patterns for a sufficient observation period.</p><p>This approach means there is no forced downtime window. Heroku stays live throughout. The cutover is a DNS switch, not a service migration under pressure. LocalOps&#8217;s<a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026"> white-glove migration service</a> handles this process end-to-end for teams that prefer not to manage it themselves.</p><p>Read the zero-downtime migration playbook.</p><h2><strong>Why Heroku Is Architecturally Incompatible With Modern SaaS</strong></h2><p>The deepest reason engineering teams outgrow Heroku is not cost and not compliance. It is architecture. Heroku was designed around a specific application model, a single web application with stateless processes and external services for persistence, and that model constrains the architectural patterns that production SaaS applications require as they mature.</p><p><strong>Microservices.</strong></p><p>Heroku&#8217;s model is built around individual applications. Each application is a separate Heroku app with its own dyno configuration, add-ons, environment variables, and deployment pipeline. As a product decomposes into microservices, managing the relationships between these Heroku apps, routing, service discovery, shared configuration, and deployment coordination becomes increasingly complex without the underlying networking primitives that VPC-native infrastructure provides.</p><p>Private communication between Heroku applications requires going over the public internet. There is no service mesh. There is no private DNS. Services communicate through public endpoints that must be secured at the application layer rather than the network layer. For microservices architectures where internal services should never be publicly accessible, this is a fundamental mismatch.</p><p><strong>Event-driven systems.</strong></p><p>Event-driven architectures depend on reliable message delivery, consumer group management, and dead-letter queue handling. Heroku&#8217;s add-on marketplace offers CloudAMQP for RabbitMQ and various Kafka-as-a-service options, but these run outside the Heroku networking model, require external service accounts, and add cost and operational complexity that compounds with every event-driven component added.</p><p>AWS-native services, SQS, SNS, EventBridge, and MSK, run inside the team&#8217;s VPC with native IAM integration, no external service accounts, and direct pricing with no platform margin. The operational model for event-driven systems on AWS is fundamentally cleaner than assembling it from Heroku add-ons.</p><p><strong>Sidecar patterns.</strong></p><p>Modern application deployment patterns increasingly rely on sidecars, containers running alongside the main application container to handle concerns like logging, metrics collection, service mesh proxying, and secret rotation. Heroku&#8217;s application model does not support multi-container deployments. The sidecar pattern does not exist on Heroku.</p><p>On Kubernetes, which LocalOps runs on EK, sidecars are a first-class pattern. Logging agents, metrics collectors, Envoy proxies for service mesh, and secret management sidecars all run alongside application containers within the same pod. This is the deployment model that modern SaaS architectures assume.</p><p><strong>What platforms support these architectures natively on AWS:</strong></p><p>AWS-native Internal Developer Platforms running on Kubernetes support all three patterns natively. Private networking between services through VPC. Event-driven architectures through native AWS services with IAM integration. Sidecar containers through Kubernetes pod specifications. LocalOps provides this infrastructure foundation, provisioned automatically, configured to AWS Well-Architected standards, running in the team&#8217;s own AWS account.</p><p><a href="https://docs.localops.co/environment/services/micro-services?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">See how LocalOps supports micro services on AWS and modern architectures.</a></p><h2><strong>The Architecture That Comes Next</strong></h2><p>The architecture that replaces Heroku for scaling SaaS teams has five consistent characteristics.</p><p><strong>Infrastructure in the team&#8217;s own cloud account.</strong> VPC isolation. Private networking between services. IAM-based access control with audit logging. Data residency in a specified region. The compliance foundation that enterprise deals require.</p><p><strong>Developer experience that does not regress.</strong> Git-push deployments. Self-serve environment management. Preview environments on every pull request. Developers deploy without tickets, without infrastructure knowledge, without platform team involvement. The autonomy that made Heroku valuable survives the migration.</p><p><strong>Observability is built into the platform.</strong> Prometheus for metrics. Loki for log aggregation. Grafana for unified dashboards and alerting. Available from the first deployment at no additional cost. Not assembled from add-ons after the fact.</p><p><strong>Horizontal autoscaling by default.</strong> Workloads scale based on real traffic signals automatically. No manual dyno configuration. No over-provisioning for anticipated peaks. Cost proportional to actual usage.</p><p><strong>No new vendor lock-in.</strong> Standard Kubernetes in the team&#8217;s own AWS account. Infrastructure that continues running independently of any platform vendor. An exit path that is always open.</p><p>LocalOps provisions all five as the default configuration. Connect your AWS account. Connect your GitHub repository. LocalOps provisions a dedicated VPC, EKS cluster, load balancers, IAM roles, and the full Prometheus + Loki + Grafana observability stack, automatically. No Terraform. No Helm charts. No manual configuration. First environment ready in under 30 minutes.</p><blockquote><p><em>&#8216;&#8217; Their thoughtfully designed product and tooling entirely eliminated the typical implementation headaches. Partnering with LocalOps has been one of our best technical decisions.&#8221;</em> <strong>&#8211; Prashanth YV, Ex-Razorpay, CTO and Co-founder, Zivy</strong></p><p><em>&#8220;Even if we had diverted all our engineering resources to doing this in-house, it would have easily taken 10&#8211;12 man months of effort , all of which LocalOps has saved for us.&#8221;</em> <strong>&#8211;  Gaurav Verma, CTO and Co-founder, SuprSend</strong></p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get started for free - first environment live in under 30 minutes.</a></strong></p></blockquote><h2><strong>Frequently Asked Questions</strong></h2><ol><li><p><strong>At what point does Heroku&#8217;s pricing become financially indefensible?</strong></p></li></ol><p>The inflection point varies by stack composition but consistently arrives when service count grows past five and add-on costs begin compounding across multiple services simultaneously. The signal is not the absolute invoice amount; it is when the invoice becomes difficult to attribute cleanly across services and difficult to optimize without changing the underlying platform. For most B2B SaaS teams, this happens between five and fifteen engineers, not because of team size directly, but because product complexity at that stage drives the service count and add-on accumulation that makes the cost structure opaque.</p><ol start="2"><li><p><strong>How should a CTO calculate the true total cost of staying on Heroku?</strong></p></li></ol><p>The full calculation has three components. Invoice cost: dyno tiers, database add-ons, Redis, monitoring tools, and scheduler, totalled across all production services. Engineering opportunity cost: hours spent on platform workarounds, architectural compromises made to serve Heroku&#8217;s limitations, and deferred technical decisions that accumulate as debt. Compliance revenue cost: Deals are delayed or lost because the infrastructure cannot satisfy enterprise security questionnaires. For most Series A and beyond B2B SaaS teams with enterprise ambitions, the compliance revenue component is the highest and least visible cost, and the one that makes the migration decision strategically obvious when it surfaces.</p><ol start="3"><li><p><strong>Why does Heroku&#8217;s dyno scaling fail for high-concurrency production workloads?</strong></p></li></ol><p>Heroku scales vertically in fixed tiers and requires manual intervention to adjust capacity. There is no event-driven autoscaling that responds to CPU, memory, or request queue signals automatically. For high-concurrency APIs that experience traffic bursts, common in B2B SaaS with peak business-hours usage patterns, the choice is between over-provisioning continuously or accepting degraded performance during spikes. Kubernetes horizontal pod autoscaling on EKS responds to real traffic signals in seconds, scales to handle burst load, and scales back automatically when traffic drops. Teams pay for actual compute consumption rather than for the tier ceiling required to handle the peak.</p><ol start="4"><li><p><strong>What is the safest migration path when a production application has outgrown Heroku?</strong></p></li></ol><p>The safest path runs both environments in parallel before any DNS cutover. Provision the new AWS environment with LocalOps and verify the full application stack, web services, background workers, scheduled jobs, and third-party integrations against the new environment before moving any production traffic. Use AWS DMS to replicate database changes from Heroku Postgres to RDS in near-real time during the transition period. Lower DNS TTL 48 hours before the planned cutover. Switch DNS only after the new environment has handled real traffic patterns for a sufficient observation period, with Heroku remaining live throughout. For teams that prefer not to manage this themselves, LocalOps&#8217;s white-glove migration handles the process end-to-end.</p><ol start="5"><li><p><strong>Why is Heroku incompatible with microservices and event-driven architectures?</strong></p></li></ol><p>Heroku&#8217;s application model assumes a single web application with stateless processes. Private communication between separate Heroku applications requires traversing the public internet; there is no VPC, no service mesh, and no private DNS. Event-driven architectures assembled from Heroku add-ons run outside the Heroku networking model, require external service accounts, and add operational complexity with every component added. Sidecar container patterns, logging agents, metrics collectors, and service mesh proxies are not supported because Heroku does not support multi-container deployments. On Kubernetes running inside a VPC, all three patterns are first-class: private inter-service networking, native AWS event services with IAM integration, and pod-level sidecar support.</p><ol start="6"><li><p><strong>What does the architecture look like after migrating from Heroku to AWS?</strong></p></li></ol><p>The post-migration architecture runs on EKS inside a dedicated VPC with private subnets, least-privilege IAM policies, and encrypted secrets via AWS Secrets Manager, all provisioned automatically by LocalOps. Developers push to a configured branch, and the application deploys. Services communicate over private networking. Prometheus collects metrics automatically. Loki aggregates logs from all services. Grafana provides unified dashboards from day one. Horizontal autoscaling responds to real traffic signals without manual intervention. The developer experience is identical to Heroku. The infrastructure underneath is the team&#8217;s own AWS account, with no platform margin, no compliance ceiling, and no vendor lock-in to unwind.</p><h2><strong>Key Takeaways</strong></h2><p>Engineering teams outgrow Heroku in a predictable sequence. Cost predictability breaks down as service count grows and add-on costs compound. Infrastructure control becomes a compliance requirement when enterprise deals arrive. Vertical scaling fails for variable traffic workloads. Reliability degrades as applications push against Standard dyno limits. And modern architectural patterns, microservices, event-driven systems, and sidecars hit fundamental platform incompatibilities.</p><p>The architecture that comes next is not more complex to operate. It is different in model, infrastructure the team owns, running on AWS, with a platform layer that preserves the developer experience Heroku provided. For engineering teams at Series A and beyond, this is the foundation that supports the next stage of growth rather than constraining it.</p><p>The teams that navigate this transition well are the ones who recognize the sequence before any single constraint becomes a crisis, and move from a position of clarity rather than under pressure.</p><p><strong><a href="https://go.localops.co/heroku?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Schedule a Migration Call &#8594;</a></strong> Our engineers review your current Heroku setup and walk through what the transition looks like for your specific stack.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Get Started for Free &#8594;</a></strong> First environment on AWS in under 30 minutes. No credit card required.</p><p><strong><a href="https://localops.co/vs/heroku-alternative?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=heroku_alternatives_2026">Read the Migration Guide &#8594;</a></strong> Full walkthrough, database migration, environment setup, DNS cutover.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.localops.co/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"></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[🎉 New release: Switch organizations/teams & New CLI update]]></title><description><![CDATA[Handling multiple engineering teams and environments, just got easier in your Internal developer platform.]]></description><link>https://blog.localops.co/p/new-release-switch-organizationsteams</link><guid isPermaLink="false">https://blog.localops.co/p/new-release-switch-organizationsteams</guid><dc:creator><![CDATA[Anand]]></dc:creator><pubDate>Tue, 31 Mar 2026 06:21:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!TKvM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We released quite a few enhancements today.</p><p>If you run multiple products and multiple engineering teams handling their own qa, uat and production environments, you will love this update.</p><h3>Switch between multiple organizations/teams:</h3><p>Users can now belong to multiple organizations using their same login / email address. And they can easily switch between the organizations from the top left menu like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TKvM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TKvM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png 424w, https://substackcdn.com/image/fetch/$s_!TKvM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png 848w, https://substackcdn.com/image/fetch/$s_!TKvM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png 1272w, https://substackcdn.com/image/fetch/$s_!TKvM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TKvM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png" width="1412" height="985" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:985,&quot;width&quot;:1412,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:548426,&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://blog.localops.co/i/192689175?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.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_!TKvM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png 424w, https://substackcdn.com/image/fetch/$s_!TKvM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png 848w, https://substackcdn.com/image/fetch/$s_!TKvM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.png 1272w, https://substackcdn.com/image/fetch/$s_!TKvM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f2e296-9bd5-4d53-9db3-df5a448ffee1_1412x985.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>Each organization can have unique environments like this:</p><ul><li><p>Github org</p></li><li><p>ECR Registries</p></li><li><p>Environments</p><ul><li><p>qa</p></li><li><p>uat</p></li><li><p>production</p></li></ul></li><li><p>Deployments</p></li></ul><h3>Enhanced CLI Login:</h3><p>LocalOps CLI now use the existing web login sessions to authenticate. </p><p>To login, just type this in your terminal:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">$ ops login</code></pre></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ylUn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ylUn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png 424w, https://substackcdn.com/image/fetch/$s_!ylUn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png 848w, https://substackcdn.com/image/fetch/$s_!ylUn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png 1272w, https://substackcdn.com/image/fetch/$s_!ylUn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ylUn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png" width="1456" height="1322" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1322,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1032206,&quot;alt&quot;:&quot;&quot;,&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://blog.localops.co/i/192689175?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ylUn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png 424w, https://substackcdn.com/image/fetch/$s_!ylUn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png 848w, https://substackcdn.com/image/fetch/$s_!ylUn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.png 1272w, https://substackcdn.com/image/fetch/$s_!ylUn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d0e0ca-cc6b-4cc6-93c2-af66c1eddc62_1864x1692.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>And you will get a link to click and open the browser. If you&#8217;re already logged in to LocalOps console (console.localops.co), we will show up the authorization form that CLI is requesting to use your current login. Once you authorize, boom! You can access LocalOps services via CLI.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pjex!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pjex!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png 424w, https://substackcdn.com/image/fetch/$s_!pjex!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png 848w, https://substackcdn.com/image/fetch/$s_!pjex!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png 1272w, https://substackcdn.com/image/fetch/$s_!pjex!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pjex!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png" width="1160" height="1040" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1040,&quot;width&quot;:1160,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:102224,&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://blog.localops.co/i/192689175?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.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_!pjex!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png 424w, https://substackcdn.com/image/fetch/$s_!pjex!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png 848w, https://substackcdn.com/image/fetch/$s_!pjex!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.png 1272w, https://substackcdn.com/image/fetch/$s_!pjex!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133c2275-998e-4086-a022-52f0a68be04f_1160x1040.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 need to update the CLI version to v3.0.0 to get this update. Checkout <a href="https://docs.localops.co/cli/install-macos">https://docs.localops.co/cli/install-macos</a> (for MacOS) or <a href="https://docs.localops.co/cli/install-windows">https://docs.localops.co/cli/install-windows</a> (for Windows) or <a href="https://docs.localops.co/cli/install-linux">https://docs.localops.co/cli/install-linux</a> (for Linux) to learn more.</p><p>Reach out to us get a quick tour of LocalOps - <a href="https://go.localops.co/tour">https://go.localops.co/tour</a>. </p><p>Or sign up for free at <a href="https://console.localops.co/signup">https://console.localops.co/signup</a>.</p><p>Cheers.</p>]]></content:encoded></item><item><title><![CDATA[How Internal Developer Platforms Enable Control Across Multi-Cloud, Regions, and Microservices]]></title><description><![CDATA[Bring consistency to multi-cloud deployments and keep visibility, security, and control as your systems scale.]]></description><link>https://blog.localops.co/p/manage-multi-cloud-multi-region-deployments-with-idp</link><guid isPermaLink="false">https://blog.localops.co/p/manage-multi-cloud-multi-region-deployments-with-idp</guid><dc:creator><![CDATA[Madhushree Sivakumar]]></dc:creator><pubDate>Sun, 29 Mar 2026 05:30:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!LaCc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.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_!LaCc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LaCc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png 424w, https://substackcdn.com/image/fetch/$s_!LaCc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png 848w, https://substackcdn.com/image/fetch/$s_!LaCc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!LaCc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LaCc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png" width="992" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:992,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LaCc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png 424w, https://substackcdn.com/image/fetch/$s_!LaCc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png 848w, https://substackcdn.com/image/fetch/$s_!LaCc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!LaCc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb98781b-fa2c-44f6-b565-843b3ed5712b_992x1200.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>Multi-cloud and multi-region setups look simple at first. In practice, they don&#8217;t stay that way.</p><p>A team runs the same service on two cloud providers. It works in the beginning. Then small differences start to show up. Load balancers behave differently. IAM policies don&#8217;t map cleanly. Network defaults are not the same. Teams add fixes to make things work, and those fixes stay.</p><p>After a while, staging and production stop matching. Debugging depends on which cloud the service is running on.</p><p>At that point, the problem is not provisioning. It is keeping environments consistent when the underlying systems behave differently.</p><p>Traditional DevOps workflows struggle here. They assume environments behave the same. In multi-cloud setups, they don&#8217;t. Pipelines get duplicated. Infrastructure definitions drift. Ownership becomes unclear.</p><p>An internal developer platform changes how this is handled. It does not try to hide the differences between cloud providers. It adds structure to how environments are created, updated, and maintained.</p><p>That shift is what keeps environments consistent as systems grow.</p><h2>TL;DR</h2><ul><li><p>Multi-cloud breaks on four gaps: provisioning inconsistency, credential sprawl, environment drift, and lack of clear visibility into what is running in each environment</p></li><li><p>Traditional DevOps workflows slow down as systems grow. Infrastructure changes move through tickets, and simple environment updates take days</p></li><li><p>An internal developer platform standardises how environments are defined and requested. Developers work with a consistent model, while the platform handles provider-specific differences</p></li><li><p>Multi-region deployments need more than reusable templates. Data residency, region-specific credentials, and environment parity need to be enforced at creation time</p></li><li><p>Managing microservices across environments fails on dependency visibility, not deployment mechanics</p></li><li><p>Preview environments fail when treated as full clones of production. Most systems cannot support that model reliably</p></li><li><p>Security needs to be part of environment provisioning. Adding it later leads to inconsistent policies and access gaps</p></li></ul><h2>Why Multi-Cloud and Multi-Region Deployments Break Down: The Four Gaps</h2><p>Multi-cloud setups break in predictable ways. Most teams running these systems run into the same four gaps.</p><h4>Provisioning inconsistency</h4><p>The same service is not provisioned the same way across providers.</p><p>An API in an AWS internal developer platform setup might use an ALB with a 60-second idle timeout. The same service on GCP sits behind a Cloud Load Balancer with a<a href="https://cloud.google.com/load-balancing/docs/backend-service"> 30-second backend timeout default</a>. Health check intervals and thresholds differ too. These are not configuration preferences. They affect how the service handles slow clients, retries, and upstream failures.</p><p>Over time, provider-specific fixes get added to patch these differences. Environments stop matching. What works in one cloud fails silently in another.</p><h4>Credential sprawl</h4><p>IAM models do not align across cloud providers.</p><p>AWS uses IAM roles with policy documents. GCP uses service accounts with IAM bindings. Azure uses managed identities with role assignments. None of these map cleanly to each other. When teams manage them independently, permissions get widened to unblock deployments. An S3 read policy becomes s3:* because narrowing it requires time nobody has. A GCP service account gets project-level editor access because the specific resource-level permission took too long to figure out.</p><p>Without a consistent access control layer sitting above all three providers, permissions become impossible to audit at scale. You end up with a spreadsheet mapping roles to resources across three different IAM models, and it is out of date the moment someone widens a permission to unblock a deployment.</p><h4>Environment drift</h4><p>Environments diverge at the infrastructure level over time.</p><p>A database parameter group tuned for performance in us-east-1 never gets applied to eu-west-1. A Kubernetes node pool configuration updated in staging never propagates to production. A security group rule added manually in the AWS console does not exist in the Terraform state. Each change is small. Collectively they mean staging and production are running on different infrastructure even when the application code is identical.</p><p>Drift is usually discovered during failures. A latency spike in eu-west-1 looks like a code problem for two hours before someone checks the RDS parameter group and finds it was never updated after the us-east-1 tuning.</p><h4>Lack of visibility</h4><p>Teams lose track of what is actually running.</p><p>At 30 services across three clouds, answering a basic question like &#8220;what version is in production right now&#8221; requires checking the AWS console, the GCP deployment history, a Terraform state file, and maybe a Slack message from two weeks ago. None of these agree with each other because none of them are the source of truth. They are all partial records of different parts of the system.</p><p>The problem is not that the data does not exist. It is that it lives in too many places to be useful during an incident. By the time you have reconstructed the state of the system, the debugging window has already cost you an hour.</p><h2>Why Traditional DevOps Models Collapse at Multi-Cloud Scale</h2><p>Traditional DevOps works when environments are consistent. Multi-cloud breaks that assumption.</p><h4>Pipelines diverge</h4><p>Teams maintain separate CI/CD pipelines that evolve differently across providers.</p><p>An AWS pipeline pushes container images to ECR, deploys to EKS using kubectl, and runs health checks against an ALB target group. A GCP pipeline pushes to Artifact Registry, deploys to GKE using Helm, and checks against a Cloud Load Balancing backend service. Both deploy the same application. The deployment logic shares nothing. Rollback mechanisms differ. Environment variable injection differs. A new engineer moving between teams spends the first week learning the pipeline instead of shipping.</p><h4>Infrastructure definitions split</h4><p>Infrastructure as code does not prevent variation.</p><p>Terraform modules fork across providers. An AWS module defines a VPC with specific CIDR ranges, subnet layouts, and NAT gateway configuration. The GCP equivalent uses a different network model entirely because GCP VPCs are global, not regional. The fork starts as a necessary difference. Over time, unrelated changes get applied to one module and not the other. The divergence goes undocumented. Six months later nobody knows which differences are intentional and which are drift. Without a strong internal developer platform, these differences compound silently.</p><p>This is the hidden cost teams discover when they attempt to build an internal developer platform on top of existing IaC tooling. The modules exist but the consistency layer does not.</p><h4>Ownership becomes fragmented</h4><p>Responsibility spreads across teams with no technical enforcement layer.</p><p>A developer needs a new environment with a specific RDS instance class and a particular security group configuration. They file a ticket. Three days later they get an environment with a different instance class because the platform team defaulted to what they normally provision. The misconfiguration does not surface until a load test shows the environment cannot handle the expected throughput.</p><p>This is the core problem platform engineering and internal developer platforms are meant to solve: enforcing standards through the system, not through documentation.</p><p>Application teams implement standards differently in practice because nothing in the toolchain enforces alignment at provisioning time. Changes move through tickets instead of a self-service system with guardrails.</p><h4>Feedback loops slow down</h4><p>Debugging becomes environment-specific in a way that is expensive to resolve.</p><p>A deployment passes all tests in us-east-1 staging and fails in eu-west-1 production with a connection timeout. The timeout traces back to a security group rule that exists in us-east-1 but was never applied in eu-west-1 because the Terraform state for that region was last updated four months ago. Finding this requires manually comparing security group rules across two regions, two Terraform state files, and the actual AWS console output, none of which are guaranteed to match.</p><p>Without a canonical environment definition to compare against, every cross-environment debugging session starts from reconstructing what the environment is supposed to look like. That takes time and is often incomplete.</p><p>Traditional DevOps does not fail because the approach is wrong. It fails because coordination overhead grows faster than the system can handle.</p><h2>What is an Internal Developer Platform?</h2><p>An internal developer platform is an abstraction layer above cloud infrastructure. It exposes a consistent interface for provisioning environments, deploying services, and managing configuration across cloud providers. The underlying cloud-specific resources, EKS, GKE, AKS, RDS, Cloud SQL, are provisioned by the platform based on which cloud account the environment targets. Engineers interact with the platform, not directly with cloud APIs.</p><p>The platform owns four things: provisioning logic, credential management, state tracking, and environment lifecycle. These need to work as one system for the abstraction to hold.</p><p>For a deeper breakdown of how internal developer platforms are defined and where they fit in modern engineering teams, read<a href="https://blog.localops.co/p/what-is-an-internal-developer-platform-idp?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog"> What Is an Internal Developer Platform</a> blog.</p><h2>How Does an IDP Handle Environment Provisioning Across Cloud Providers?</h2><p>Cloud providers do not share infrastructure primitives. A VPC in AWS is not the same as a VPC in GCP. EKS and GKE both run Kubernetes but differ in how node pools, IAM, and networking are configured. Writing separate provisioning logic per provider is how teams end up with forked infrastructure definitions that diverge silently over time.</p><p>An internal developer platform solves this through four layers that work together.</p><h4>Environment model</h4><p>The platform defines what an environment is independent of any cloud provider. A developer requests an environment by specifying a target cloud account and a region. They do not specify cloud resources directly. The environment model describes what needs to exist: a network layer, a compute layer, an orchestration layer, an observability layer. The platform owns that definition.</p><h4>Translation layer</h4><p>The platform translates the environment model into provider-specific resources at provisioning time. The same environment definition produces the correct networking, compute, and Kubernetes resources for whichever cloud account it targets. The developer interface does not change across providers. Provider differences are handled inside the platform, not distributed across individual team workflows.</p><h4>Orchestration</h4><p>Provisioning is not just creating resources in isolation. Network, compute, and Kubernetes components have dependencies. The platform provisions them in the correct order, wires them together, and validates the environment is functional before marking it ready. Observability tooling gets installed and connected to the environment at this stage, not added separately afterward. Logs and metrics are available from the first deployment. This matters because debugging cross-environment differences requires consistent instrumentation across all environments. When observability is set up manually per environment, one environment ends up better instrumented than another.</p><h4>Lifecycle management</h4><p>Application-specific cloud resources, databases, queues, storage buckets, are defined at the service level rather than the environment level. The platform provisions them when a service is created and removes them when the service is deleted. Resource lifecycle stays coupled to service lifecycle. This prevents orphaned infrastructure accumulating across environments over time, which is one of the more common sources of unexpected cloud spend in multi-environment setups.</p><p>If you want to see what a full environment actually includes, you can explore the <a href="https://docs.localops.co/environment/inside?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">LocalOps breakdown of what&#8217;s inside an environment.</a></p><h2>How Do You Manage Multi-Region Deployments Inside an IDP?</h2><p>Running the same environment definition in two regions is straightforward. What breaks after provisioning is keeping environments equivalent across regions, enforcing where data is allowed to exist, and preventing credentials from one region being used to provision resources in another.</p><p>An internal developer platform handles multi-region through three mechanisms.</p><h4>Account-level region constraints</h4><p>Region selection does not happen at environment creation time. It happens when a cloud account is connected to the platform. The account configuration determines which regions are available for environments targeting that account. An account configured for EU data residency only surfaces EU regions. A developer creating an environment against that account cannot select a US region because the platform does not present it as an option. Data residency gets enforced at the infrastructure level, not through documentation or process that depends on developers remembering the constraint.</p><h4>Parity through a shared environment definition</h4><p>Two environments provisioned from the same definition in different regions come out structurally identical: same network layout, same cluster configuration, same observability stack. The platform guarantees this at creation time. What breaks parity is changes made outside the platform, a configuration edit applied directly in a cloud console in one region that never reaches the other. The platform has no visibility into changes that bypass it. Parity only holds for what the platform provisions and manages. Any change applied outside the platform becomes undocumented drift that will surface as a debugging problem later.</p><h4>Explicit cross-region dependencies</h4><p>A service calling a dependency in another region introduces latency and potentially crosses a compliance boundary. Within an environment, services communicate through stable internal references that the platform assigns and maintains. These references do not change when infrastructure is updated. Cross-environment or cross-region dependencies cannot use these internal references. They need to be configured explicitly in the service&#8217;s configuration. This keeps cross-region calls visible in configuration rather than embedded in application code where they are difficult to audit.</p><p>See how LocalOps <a href="https://docs.localops.co/accounts/aws?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">handles cloud account and region configuration</a></p><h2>How Do You Manage Microservices Across Multiple Environments in an IDP?</h2><p>Deploying a container to a Kubernetes namespace is not the hard part. What gets hard at scale is knowing what is actually running: which version of which service is in which environment, whether service interfaces are still compatible after a recent change, and who is responsible when something breaks.</p><p>An internal developer platform handles microservice management across environments through four mechanisms.</p><h4>Per-service configuration isolation</h4><p>Each service carries its own configuration per environment. A change to one service&#8217;s configuration does not affect any other service in the same environment. Services are deployed independently against their own repository and branch. There is no shared configuration file that multiple services read from. When shared configuration exists at the wrong level, deploying one service requires coordinating with teams that own other services. That coordination overhead is what the isolation is designed to remove.</p><h4>Stable service references</h4><p>Services in a microservice architecture depend on each other. Dependencies expressed as hardcoded hostnames or IP addresses break when infrastructure changes underneath them. The platform assigns each service a stable internal reference that maps to its hostname within the environment. That reference does not change for the lifetime of the service. Dependent services use this reference rather than direct addresses. When infrastructure is updated or a service is redeployed, the reference continues to resolve correctly without any changes in application code.</p><h4>Independent deployability</h4><p>One service can be deployed, updated, or rolled back without touching any other service&#8217;s configuration or notifying another team. Each service has its own deployment pipeline triggered by commits to its configured branch. The platform enforces this independence structurally. When cross-service coordination is happening regularly before deployments, it usually indicates shared configuration has been introduced somewhere it should not be.</p><h4>Deployment state per environment</h4><p>The platform tracks deployment state per service per environment. Which version is running, when it was last deployed, whether the deployment is healthy. At 20 or 30 services across multiple environments this state cannot be tracked manually. Without a centralized view, teams find out a service is unhealthy when a dependent service starts returning errors or when a user reports a problem. With it, the state of every service across every environment is visible in one place.</p><p>Here&#8217;s an example of <a href="https://docs.localops.co/environment/services/micro-services?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">how LocalOps handles service dependencies and aliases across environments</a></p><h2>Internal Developer Platform Architecture: Control Layers and Orchestration</h2><p>An internal developer platform is not a single tool. It is a set of layers that need to work together. When one layer is missing or disconnected from the others, the complexity it was supposed to hide leaks back to engineers.</p><h4>Developer interface layer</h4><p>This is how engineers interact with the platform: a web console, a CLI, or an API. It accepts environment and service requests and passes them to the provisioning layer. The interface should be opinionated enough to prevent misconfigured requests but not so rigid that every new environment type requires platform team involvement to support.</p><p>This layer is what most people refer to as the internal developer portal. The internal developer portal vs platform distinction matters here. A portal handles the interface: service catalog, documentation, self-service UI. What it does not do is provision environments, manage credentials, or track infrastructure state. Teams that deploy a portal without building the layers underneath get a catalog with no operational capability. The portal works in the demo. Nothing actually provisions.</p><p>The best internal developer platform is not the one with the most features in the interface layer. It is the one where the provisioning, credential, and state layers work reliably underneath.</p><h4>Provisioning layer</h4><p>This is where environment definitions get translated into cloud resources. The provisioning layer owns the environment model, the per-provider translation logic, and the dependency ordering that ensures resources get created in the correct sequence. Security baselines get applied here, at provisioning time, not as a separate step afterward. Disk encryption, network isolation, and IAM scoping are part of the provisioning definition. An environment provisioned without these and hardened later ran without them for some period of time.</p><h4>Credential layer</h4><p>The platform needs access to cloud accounts to provision resources. That access should be role-based and keyless. The platform assumes a scoped role at provisioning time rather than holding long-lived credentials. No engineer holds direct cloud credentials. Access is auditable because it flows through the platform, not through individually managed keys scattered across team members.</p><h4>State and observability layer</h4><p>The platform tracks what it has provisioned across all cloud accounts, all regions, and all environments. This is the layer that closes the visibility gap from Section 1. Which version is deployed where, what changed recently, which environments are out of sync. These questions have answers because the platform is the system of record for everything it has provisioned. Observability tooling running inside each environment feeds into this layer, giving teams logs and metrics without manual setup per environment.</p><p>These four layers need to be integrated. A portal connected to a separate provisioning tool with no shared state between them is not a platform. It is two tools that happen to be used together, and the gap between them is where coordination overhead lives.</p><p>To understand how these four layers work together as one system, you can check out the<a href="https://docs.localops.co?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog"> LocalOps docs</a> which walk through the architecture end to end.</p><h2>How Do You Measure Control in a Multi-Cloud IDP?</h2><p>Control in a multi-cloud internal developer platform is measurable. If the platform is working, specific signals stay stable across environments and providers.</p><p><strong>Provisioning time per environment.</strong> A well-built platform provisions consistently regardless of which cloud account it targets. If provisioning time varies significantly between AWS and GCP for the same environment definition, the translation layer is not stable. Inconsistency here usually means provider-specific logic is leaking into the provisioning path.</p><p><strong>Environment parity failures.</strong> Track how often a deployment passes in staging but fails in production due to an environment difference. Each occurrence is a parity failure. These get caught in postmortems. If the number is not trending toward zero, the environment definition is not enforcing consistency at provisioning time.</p><p><strong>Drift detection rate.</strong> How often does the platform detect that live infrastructure differs from its provisioned state. If the answer is never, the platform has no visibility into out-of-band changes. Changes made directly in cloud consoles are invisible to the platform and accumulate as undocumented divergence.</p><p><strong>Deployment success rate across environments.</strong> Not just whether a deployment completed, but whether the service behaved consistently across environments after deployment. Failures that are environment-specific point to configuration or infrastructure differences the platform did not catch.</p><p><strong>Time to debug cross-environment issues.</strong> This exposes visibility gaps directly. If root cause analysis requires manually checking multiple cloud consoles, the state layer is not doing its job.</p><p>Three operational signals that sit underneath these metrics:</p><p>Can a developer provision an environment without involving another team? If not, the self-service model is not working. Can the platform tell you what is running in each environment right now without manual reconstruction? If not, the state layer is incomplete. How long does it take a new engineer to deploy their first service? Weeks means the platform has not reduced the knowledge barrier. Days means it has.</p><h2>How Does an IDP Handle Security Across Cloud Environments?</h2><p>Security in multi-cloud environments fails in predictable ways. Policies exist as documentation that teams implement inconsistently. Credentials get distributed to individuals rather than managed by the platform. Environments get provisioned without a security baseline and controls get added afterward, which means they were absent for some period of time.</p><h4>Security at provisioning time, not after</h4><p>Every cloud provider has security configurations that are not enabled by default but should be on in every production environment. Disk encryption, VPC flow logs, security groups with minimal open ports, database encryption at rest. A platform that applies these at provisioning time through the environment definition makes them non-optional. A developer cannot provision an environment without them because the template does not offer that option. Security teams stop reviewing individual provisioning requests and start reviewing the template instead. One review covers every environment provisioned from it.</p><h4>Keyless credential management</h4><p>The platform connects to cloud accounts using role-based, keyless access. In AWS this is IAM role assumption. In GCP it is the workload identity federation. In Azure it is managed identity. The platform assumes the role it needs at provisioning time, scoped to that specific operation. No engineer holds a long-lived access key for any cloud account. If an engineer&#8217;s machine is compromised, no cloud credentials are exposed because none were stored there.</p><h4>Per-environment secret isolation</h4><p>Application secrets should not be shared across environments. A production database credential should not be accessible in a staging environment. The platform provisions isolated secret storage per environment and scopes access to secrets at the environment level. Services access secrets through the platform&#8217;s credential mechanism, not through hardcoded values or shared configuration files.</p><h4>Network isolation by default</h4><p>Each environment gets its own dedicated network. Private subnets host resources with no public IP. Public subnets are limited to resources that explicitly need internet access. Services communicate internally through private DNS. This is not a configuration option. It is the default network layout for every environment the platform provisions.</p><h2>FAQs</h2><p><strong>1. How does an internal developer platform handle secrets across cloud environments?</strong></p><p>Each environment gets its own isolated secret storage. A production database credential is not accessible in staging because secrets are scoped at the environment level, not shared across environments. Services access secrets through the platform&#8217;s credential mechanism at runtime. No hardcoded values, no shared configuration files. The secret storage backend varies by cloud provider, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, but the access model is consistent across all of them because the platform abstracts it.</p><p><strong>2. How do IDPs ensure consistency across regions?</strong></p><p>Consistency across regions comes from provisioning both environments from the same definition. Same network layout, same cluster configuration, same observability stack. The platform guarantees structural equivalence at creation time. What breaks consistency is changes made outside the platform directly in cloud consoles or state files that the platform cannot track. Consistency only holds for what the platform provisions and manages.</p><p><strong>3.Can IDPs handle service discovery for microservices?</strong></p><p>Yes. Each service gets a stable internal reference that maps to its hostname within the environment. That reference does not change when infrastructure is updated or a service is redeployed. Dependent services use this reference as an environment variable rather than hardcoded hostnames or IP addresses. At runtime the platform resolves it to the actual internal hostname. This means service discovery works without a separate service mesh or DNS configuration per environment.</p><p><strong>4. How do IDPs reduce manual provisioning overhead?</strong></p><p>By replacing ticket-driven infrastructure requests with self-service. A developer selects a target cloud account and region. The platform provisions the full environment: networking, compute, Kubernetes cluster, and observability tooling. No engineer on the platform team needs to be involved. The provisioning definition is maintained once by the platform team and applied consistently across every environment request. Manual work shifts from handling individual requests to maintaining the platform itself.</p><p><strong>5. How do IDPs enforce compliance in multi-region setups?</strong></p><p>Compliance constraints get enforced at the cloud account level, not at environment creation time. When a cloud account is connected to the platform, its configuration determines which regions are available for environments targeting that account. An account configured for EU data residency only surfaces EU regions. A developer cannot select a non-compliant region because the platform does not present it as an option. Security baselines, disk encryption, network isolation, and IAM scoping are part of the provisioning definition and applied to every environment automatically.</p><p><strong>6. What is the difference between a managed and open source internal developer platform?</strong></p><p>An open source platforms like the Backstage internal developer platform gives you the portal layer: service catalog, documentation, and a self-service interface. What it does not include out of the box is a provisioning engine, a credential layer, or state management. Teams that deploy Backstage without building those layers get a catalog with no operational capability.</p><p>A managed internal developer platform provides all four layers, provisioning, credentials, state, and the developer interface, as one integrated system. The tradeoff is flexibility versus time to operational capability. Open source gives you full control but requires significant engineering investment to build and maintain the provisioning layer. A managed platform reduces that investment but operates within the boundaries the vendor has defined.</p><h2>Conclusion</h2><p>Multi-cloud control is often mistaken for having infrastructure as code per provider. It is not.</p><p>Having Terraform modules for AWS, GCP, and Azure feels like a solved problem. Until someone leaves and the modules go undocumented. Until staging and production diverge and nobody can explain why. Until a new engineer needs three weeks to get their first environment running because the knowledge is in someone&#8217;s head, not in the system.</p><p>IaC is an input to a platform. It is not the platform itself.</p><p>The gap between what teams think they have and what they actually have usually comes down to the same missing pieces: no consistent environment definition above the cloud layer, no centralized credential management, no observability provisioned by default.</p><p>Each of these gaps was manageable when the system was small. At scale they compound. Debugging takes longer. Incidents are harder to reproduce. New engineers take longer to become productive. The platform team becomes a bottleneck instead of an enabler.</p><p>An internal developer platform closes these gaps by owning the provisioning layer. One environment definition that translates across cloud providers. Role-based, keyless credential access scoped to the platform. Observability provisioned inside every environment at creation time, not added afterward. The conditions for drift get removed at the source because every environment starts from the same definition, not because the platform detects and corrects drift after the fact.</p><p>That is what control actually looks like.</p><p>If your team is dealing with environment inconsistency across cloud providers, manual provisioning overhead, or visibility gaps across regions, LocalOps is designed to handle these problems at the platform layer.</p><p>If you&#8217;re figuring out how this would fit into your setup, the LocalOps team can help you work through it:</p><p><strong><a href="https://cal.com/anand-localops/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Book a Demo</a> &#8594;</strong> Walk through how environments, deployments, and AWS infrastructure are handled in practice for your setup.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Get started for free</a> &#8594;</strong> Connect an AWS account and stand up an environment to see how it fits into your existing workflow.</p><p><strong><a href="https://docs.localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Explore the Docs</a> &#8594;</strong> A detailed breakdown of how LocalOps works end-to-end, including architecture, environment setup, security defaults, and where engineering decisions still sit.</p>]]></content:encoded></item><item><title><![CDATA[How Internal Developer Platforms Help a Growing SaaS Engineering Team Scale Without Hiring More DevOps]]></title><description><![CDATA[Reduce bottlenecks, speed up releases and scale your engineering team without increasing headcount.]]></description><link>https://blog.localops.co/p/how-to-scale-saas-engineering-team-without-hiring-more-devops</link><guid isPermaLink="false">https://blog.localops.co/p/how-to-scale-saas-engineering-team-without-hiring-more-devops</guid><dc:creator><![CDATA[Madhushree Sivakumar]]></dc:creator><pubDate>Sat, 28 Mar 2026 05:30:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ApGQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.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_!ApGQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ApGQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png 424w, https://substackcdn.com/image/fetch/$s_!ApGQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png 848w, https://substackcdn.com/image/fetch/$s_!ApGQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png 1272w, https://substackcdn.com/image/fetch/$s_!ApGQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ApGQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6214855,&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://blog.localops.co/i/192283373?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.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_!ApGQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png 424w, https://substackcdn.com/image/fetch/$s_!ApGQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png 848w, https://substackcdn.com/image/fetch/$s_!ApGQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.png 1272w, https://substackcdn.com/image/fetch/$s_!ApGQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2b4e43-ed4c-4454-894e-208708027de3_2400x2400.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>As SaaS teams grow, infrastructure complexity doesn&#8217;t just increase, it compounds.</p><p>What starts as a simple setup with a few services quickly turns into multiple environments, fragmented pipelines, access controls, and constant operational overhead. Over time, even routine tasks like spinning up an environment or deploying a feature begin to depend on a small DevOps team.</p><p>That&#8217;s when the bottleneck shows up.</p><p>Most teams respond by hiring more DevOps engineers. But that approach only adds more people to manage an already complex system. It increases cost and coordination overhead without fixing the underlying issue.</p><p>The real challenge isn&#8217;t a lack of DevOps capacity, it&#8217;s a lack of standardization and self-service.</p><p>Internal Developer Platforms (IDPs) address this by turning infrastructure and deployment workflows into reusable, self-service systems, allowing teams to scale engineering output without scaling DevOps headcount.</p><h2>TL;DR</h2><ul><li><p>Most SaaS teams that hit an infrastructure bottleneck assume they need more DevOps engineers. They hire, the backlog clears briefly, then the same problems come back.</p></li><li><p>The issue is not capacity. It is that infrastructure work is still manual, inconsistent, and dependent on a small number of people who know how things are set up.</p></li><li><p>An internal developer platform removes that dependency. Developers provision environments, deploy services, and manage configuration without routing through anyone. Standards are enforced by the platform, not by whoever happens to be available.</p></li><li><p>The teams that get this right do not just deploy faster. They change how the whole infrastructure function works, from a request-driven queue to a self-service system developers can operate without waiting on anyone.</p></li></ul><h2>What Actually Breaks as Your SaaS Team Scales</h2><p>As a SaaS system scales, the failure point isn&#8217;t code velocity, it&#8217;s the lack of standardized infrastructure and repeatable workflows. The same patterns show up across teams once you move beyond a handful of services.</p><h4>Environment Drift and Configuration Inconsistency</h4><p>Teams typically maintain separate dev, staging, and production environments, but they&#8217;re rarely identical.</p><ul><li><p>Different instance types, env variables, or secrets</p></li><li><p>Manual hotfixes applied only in production</p></li><li><p>Inconsistent Terraform or incomplete IaC coverage</p></li></ul><p>This leads to:</p><ul><li><p>Bugs that cannot be reproduced outside production</p></li><li><p>Failed deployments due to missing or mismatched configs</p></li><li><p>Increased time spent debugging environment-specific issues</p></li></ul><p>Without strict environment templating, drift becomes inevitable.</p><h4>DevOps as a Request-Driven Bottleneck</h4><p>In most growing teams, infrastructure access is centralized for safety. In practice, this creates a ticket-driven workflow:</p><ul><li><p>&#8220;Create a new service&#8221;</p></li><li><p>&#8220;Provision a database&#8221;</p></li><li><p>&#8220;Update IAM permissions&#8221;</p></li><li><p>&#8220;Fix CI/CD pipeline&#8221;</p></li></ul><p>Each request requires:</p><ul><li><p>Context switching for DevOps</p></li><li><p>Manual validation and setup</p></li><li><p>Back-and-forth communication</p></li></ul><p>As request volume increases, lead time grows linearly. Deployment frequency drops, even if engineering capacity increases.</p><p>Industry reports from Atlassian and Puppet consistently show that a significant share of DevOps time is spent on maintenance and operational tasks rather than innovation.</p><h4>Fragmented CI/CD Pipelines</h4><p>Pipelines evolve organically per service or team:</p><ul><li><p>Different GitHub Actions / Jenkins configs</p></li><li><p>Inconsistent build, test, and deploy stages</p></li><li><p>No shared rollback or failure handling strategy</p></li></ul><p>This creates:</p><ul><li><p>Unpredictable deployment behavior</p></li><li><p>Difficult debugging across services</p></li><li><p>Lack of enforceable standards (security, testing, approvals)</p></li></ul><p>Without a unified pipeline abstraction, every service becomes a snowflake.</p><h4>Lack of Reusable Infrastructure Patterns</h4><p>Common components are repeatedly reimplemented:</p><ul><li><p>Service templates (API, worker, cron jobs)</p></li><li><p>Database provisioning patterns</p></li><li><p>Networking and service discovery setup</p></li></ul><p>Instead of reusable modules, teams copy-paste configs and modify them. Over time:</p><ul><li><p>Divergence increases</p></li><li><p>Bugs get duplicated</p></li><li><p>Upgrades become risky and inconsistent</p></li></ul><h4>Increasing Cognitive Load on Developers</h4><p>Developers are expected to handle:</p><ul><li><p>Kubernetes manifests or ECS task definitions</p></li><li><p>Networking (VPCs, subnets, security groups)</p></li><li><p>Secrets management and IAM roles</p></li><li><p>CI/CD configuration</p></li></ul><p>This leads to:</p><ul><li><p>Slower feature delivery</p></li><li><p>Higher onboarding time for new engineers</p></li><li><p>More production mistakes due to partial understanding</p></li></ul><p>At scale, this isn&#8217;t a skills issue, it&#8217;s a systems design issue.</p><h4>Poor Observability and Debugging Across Environments</h4><p>Monitoring and logging are often:</p><ul><li><p>Configured differently per service</p></li><li><p>Missing in non-production environments</p></li><li><p>Not tied to deployment events</p></li></ul><p>As a result:</p><ul><li><p>Failures are detected late</p></li><li><p>Root cause analysis takes longer</p></li><li><p>Teams rely on manual investigation instead of structured signals</p></li></ul><h4>The Core Pattern</h4><p>All of these issues point to the same underlying problem:</p><ul><li><p>Infrastructure is not standardized</p></li><li><p>Workflows are not repeatable</p></li><li><p>Systems depend on individuals instead of abstractions</p></li></ul><p>Until those are fixed, adding more DevOps engineers only increases the system&#8217;s coordination cost.</p><h2>Why Hiring More DevOps Doesn&#8217;t Solve It</h2><p>When infrastructure bottlenecks appear, the default response is to hire more DevOps engineers. It feels like a capacity problem. More requests, more people to handle them.</p><p>In reality, it&#8217;s a systems problem.</p><h4>Linear Scaling of an Operational Model</h4><p>As systems grow, the number of operational tasks increases rapidly:</p><ul><li><p>Provisioning infrastructure</p></li><li><p>Managing IAM roles and access</p></li><li><p>Maintaining CI/CD pipelines</p></li><li><p>Handling incidents and rollbacks</p></li></ul><p>Each new service or environment adds more surface area. But hiring increases capacity only linearly, while system complexity grows non-linearly.</p><p>This creates a persistent gap:</p><ul><li><p>Request volume keeps increasing</p></li><li><p>Backlogs grow despite hiring</p></li><li><p>Lead times for changes remain high</p></li></ul><h4>Increased Coordination Overhead</h4><p>Adding more DevOps engineers introduces more coordination layers:</p><ul><li><p>More handoffs between developers and DevOps</p></li><li><p>More communication required for each change</p></li><li><p>More dependencies across team members</p></li></ul><p>Instead of speeding up execution:</p><ul><li><p>Requests take longer to process</p></li><li><p>Context gets fragmented</p></li><li><p>Small changes require multiple touchpoints</p></li></ul><p>The system becomes slower not because of lack of effort, but because of increased coordination cost.</p><h4>Knowledge Silos and Operational Risk</h4><p>Infrastructure knowledge is often:</p><ul><li><p>Distributed across individuals</p></li><li><p>Built through experience rather than systems</p></li><li><p>Poorly documented or inconsistently applied</p></li></ul><p>As the team grows:</p><ul><li><p>Each engineer owns a subset of the system</p></li><li><p>Debugging requires multiple people</p></li><li><p>Onboarding new engineers takes longer</p></li></ul><p>This leads to:</p><ul><li><p>Slower incident resolution</p></li><li><p>Higher reliance on specific individuals</p></li><li><p>Increased operational risk</p></li></ul><h4>Inconsistent Practices at Scale</h4><p>Without a shared abstraction layer:</p><ul><li><p>Naming conventions differ</p></li><li><p>Configurations diverge</p></li><li><p>Deployment workflows vary across services</p></li></ul><p>Over time:</p><ul><li><p>Infrastructure becomes harder to reason about</p></li><li><p>Changes become riskier</p></li><li><p>Debugging becomes more expensive</p></li></ul><p>Every service starts behaving like its own system instead of part of a cohesive platform.</p><h4>DevOps Becomes a Gatekeeper Function</h4><p>In a request-driven model, DevOps becomes the checkpoint for:</p><ul><li><p>Deployments</p></li><li><p>Environment provisioning</p></li><li><p>Configuration updates</p></li></ul><p>This results in:</p><ul><li><p>Slower release cycles</p></li><li><p>Reduced developer autonomy</p></li><li><p>Bottlenecks during high-demand periods</p></li></ul><p>Even simple changes are delayed because they depend on a centralized team.</p><h4>The Structural Issue</h4><p>The core problem isn&#8217;t team size. It&#8217;s the operating model.</p><ul><li><p>Workflows are request-driven instead of self-service</p></li><li><p>Infrastructure is manually managed instead of abstracted</p></li><li><p>Systems depend on individuals instead of standardized platforms</p></li></ul><p>This pattern is widely observed across modern DevOps and platform engineering practices.</p><p>As teams scale, adding more DevOps engineers increases coordination overhead, fragments knowledge, and reinforces ticket-driven workflows instead of eliminating them. Without standardized, self-service systems, infrastructure complexity grows faster than the team managing it.</p><p>The result is predictable:</p><ul><li><p>Slower delivery</p></li><li><p>Higher operational overhead</p></li><li><p>Increasing cost without proportional gains in efficiency</p></li></ul><h2>How Internal Developer Platforms Solve This Structurally</h2><h4>What is an Internal Developer Platform?</h4><p>An Internal Developer Platform (IDP) is a centralized layer that standardizes infrastructure, deployment workflows, and operational practices, and exposes them as self-service tools that developers can use independently.</p><p>IDPs don&#8217;t just improve workflows, they replace the underlying operating model. Instead of scaling DevOps teams to handle growing complexity, they standardize infrastructure and expose it through self-service systems that developers can use directly.</p><p>This shifts the model from DevOps-driven execution to platform-enabled autonomy, where developers can provision environments, deploy services, and manage changes without relying on manual intervention.</p><p>For a deeper breakdown of how internal developer platforms are defined and where they fit in modern engineering teams, read<a href="https://blog.localops.co/p/what-is-an-internal-developer-platform-idp?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog"> What Is an Internal Developer Platform</a> blog.</p><h4>Self-Service Infrastructure via Environment-Based Provisioning</h4><p>IDPs move infrastructure from ad-hoc provisioning to standardized environment templates.</p><p>Each environment (development, staging, production) is provisioned using predefined configurations that include:</p><ul><li><p>Networking and access controls</p></li><li><p>Compute and storage resources</p></li><li><p>Container orchestration setup</p></li><li><p>Supporting services required to run applications</p></li></ul><p>These environments are created through reusable templates, not manual setup.</p><p>Developers don&#8217;t request infrastructure. They create environments.</p><p>Result:</p><ul><li><p>No ticket-based provisioning</p></li><li><p>Identical environments across stages</p></li><li><p>Elimination of configuration drift</p></li></ul><h4>Push-to-Deploy with Standardized CI/CD</h4><p>Instead of maintaining separate pipelines for each service, IDPs provide centralized and reusable CI/CD workflows.</p><p>A typical flow:</p><ul><li><p>Connect repository</p></li><li><p>Select branch</p></li><li><p>Trigger build and deployment automatically on code push</p></li></ul><p>Pipelines are preconfigured with:</p><ul><li><p>Build and test stages</p></li><li><p>Deployment logic</p></li><li><p>Rollback strategies</p></li></ul><p>This ensures:</p><ul><li><p>Consistent deployment behavior across services</p></li><li><p>Reduced failure rates</p></li><li><p>Faster release cycles</p></li></ul><p>CI/CD becomes a platform capability rather than a team-level responsibility.</p><h4>Infrastructure Abstraction Without Losing Control</h4><p>IDPs introduce an abstraction layer over infrastructure.</p><p>Developers interact with simple actions such as:</p><ul><li><p>Create service</p></li><li><p>Deploy application</p></li><li><p>Scale workloads</p></li></ul><p>Behind the scenes, the platform handles:</p><ul><li><p>Resource provisioning</p></li><li><p>Container orchestration</p></li><li><p>Networking and permissions</p></li></ul><p>This creates a clear separation:</p><ul><li><p>Developers define intent</p></li><li><p>The platform executes it using standardized configurations</p></li></ul><p>At the same time, governance is preserved through built-in controls and policies.</p><h4>Built-in Observability and Operational Tooling</h4><p>Observability is often inconsistent across services in growing systems.</p><p>IDPs embed monitoring and logging into the platform by default:</p><ul><li><p>Centralized logging</p></li><li><p>Metrics collection</p></li><li><p>Preconfigured dashboards</p></li></ul><p>This leads to:</p><ul><li><p>Faster detection of issues</p></li><li><p>Easier debugging across environments</p></li><li><p>Consistent visibility across services</p></li></ul><p>Observability becomes a default capability, not an additional setup step.</p><h4>Eliminating DevOps Work Through Standardization</h4><p>In traditional setups, DevOps teams repeatedly:</p><ul><li><p>Write infrastructure configurations</p></li><li><p>Maintain deployment pipelines</p></li><li><p>Manage service-specific setup</p></li></ul><p>IDPs convert these into reusable system-level components:</p><ul><li><p>Standard service templates</p></li><li><p>Predefined deployment workflows</p></li><li><p>Shared infrastructure patterns</p></li></ul><p>Developers no longer need to manage these details, and DevOps doesn&#8217;t need to rebuild them for every service.</p><h4>From Ticket-Driven Ops to Platform Engineering</h4><p>The most important change is operational.</p><p>Before:</p><ul><li><p>DevOps operates through request-driven workflows</p></li><li><p>Every change requires manual intervention</p></li></ul><p>After IDP:</p><ul><li><p>Developers use self-service systems</p></li><li><p>Infrastructure and deployments are automated</p></li><li><p>DevOps focuses on building and improving the platform</p></li></ul><p>This marks the shift from reactive operations to platform engineering.</p><h4>The Structural Shift</h4><p>IDPs solve the root problem by changing how systems operate:</p><ul><li><p>From manual to automated</p></li><li><p>From fragmented to standardized</p></li><li><p>From request-driven to self-service</p></li></ul><p>Instead of adding more DevOps engineers to manage growing complexity, teams build systems that absorb that complexity once and apply it consistently across all services and environments.</p><p>This is what enables engineering teams to scale output without increasing operational overhead.</p><p>To understand how this works end-to-end, including environment setup, deployment flow, and infrastructure defaults, take a look at <a href="https://docs.localops.co/howitworks?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">how LocalOps IDP works</a>.</p><h2>Before vs After Internal Developer Platforms</h2><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/aEJy2/2/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f3d473e6-67d6-49dc-a34a-72df4b6f0ece_1220x1088.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/09931166-5b10-417e-bf87-8f72f9925576_1220x1088.png&quot;,&quot;height&quot;:547,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/aEJy2/2/" width="730" height="547" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><h2>Measurable Impact</h2><p>Shifting to an internal developer platform does not just reduce manual work. It shows up in metrics that engineering leaders actually track.</p><p><strong>Deployment frequency increases.</strong> When developers can ship without waiting on infrastructure setup or DevOps approval, release cycles shorten. Teams move from batching changes into infrequent releases to shipping smaller updates continuously.</p><p><strong>Lead time for changes drops.</strong> Environment provisioning that took days becomes self-service. A change that previously sat in a queue now goes from commit to deployed in hours.</p><p><strong>DevOps ticket volume falls.</strong> Routine requests, environment setup, access configuration, secrets management, service deployment, stop generating tickets. The DevOps team handles genuinely complex work instead of a backlog of repetitive tasks.</p><p><strong>New engineers ramp up faster.</strong> Onboarding stops depending on tribal knowledge. A new developer connects a repo, picks a branch, and deploys without needing someone to walk them through the infrastructure setup.</p><p><strong>Environment-related incidents reduce.</strong> Standardized environments mean staging behaves like production. Inconsistencies that only surface in production become rare because every environment is built from the same template.</p><p><strong>Rollbacks become predictable.</strong> Consistent deployment pipelines mean when something goes wrong, the rollback path is known and tested. There is no guessing which environment has which configuration.</p><h2>What to Look for in an Internal Developer Platform</h2><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/aEJy2/2/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4532e8a2-b521-4443-b02d-7a8e12932cb6_1220x1088.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9135257-f6b1-4298-91c4-b09c060713d1_1220x1088.png&quot;,&quot;height&quot;:547,&quot;title&quot;:&quot;Created with Datawrapper&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/aEJy2/2/" width="730" height="547" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>If you want to see how these criteria map to a real implementation, you can explore it with the LocalOps team by <a href="https://cal.com/anand-localops/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">booking a demo </a>or <a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">trying it out yourself for free</a>.</p><h2>Common Mistakes Teams Make</h2><p>One of the most common mistakes is introducing an internal developer platform without clearly defining the problems it should solve. Teams adopt or build a platform, but continue operating the same way, so the underlying bottlenecks remain.</p><p>Another issue is not driving adoption across teams. Even a well-designed platform fails if developers continue using old processes. If it&#8217;s not clearly better, faster, and easier, it won&#8217;t be used.</p><p>Many teams also skip proper standardization. They introduce a platform but still allow multiple patterns for deployments, environments, and configurations. This brings back the same inconsistency the platform was meant to eliminate.</p><p>A frequent mistake is focusing only on infrastructure and ignoring developer experience. In platform engineering, the goal is not just automation, but enabling developers to move faster with less friction. Without that, even the best internal developer platform fails in practice.</p><p>As teams start scaling, many begin thinking about how to build an internal developer platform internally. This often leads to trying to solve too many problems at once or building for hypothetical future needs. Instead of reducing complexity, the effort shifts into maintaining the platform itself.</p><p>Building can make sense in specific cases, but during the scaling phase, it introduces additional overhead:</p><ul><li><p>Time spent designing and maintaining internal tooling</p></li><li><p>Slower time to value while the platform is still evolving</p></li><li><p>Ongoing effort required to keep workflows and integrations up to date</p></li></ul><p>This is why teams evaluating the best platform for internal developer experience often prioritize faster adoption and standardization over building everything from scratch.</p><p> If your team is weighing this decision,<a href="https://blog.localops.co/p/internal-developer-platform-build-vs-buy-cost-comparison?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog"> here is a detailed breakdown of what building vs adopting an internal developer platform actually costs</a>.</p><p>Some teams also don&#8217;t define clear ownership. Without a dedicated team responsible for maintaining and improving the platform, it becomes inconsistent over time.</p><p>There&#8217;s also a tendency to overcomplicate workflows by adding too many steps, approvals, or abstractions, which recreates the same friction the platform was meant to remove.</p><h2>FAQs</h2><p><strong>1. Is an open source internal developer platform or a managed IDP better for a growing SaaS company?</strong></p><p>Open source tools like the Backstage internal developer platform give you flexibility but the build and maintenance cost sits entirely with your team. Backstage covers the portal layer. You still need separate tooling for provisioning, CI/CD, secrets, and observability. Integrating and maintaining that stack requires dedicated platform engineering capacity most growing SaaS teams do not have.</p><p>The complexity is not upfront. It compounds. Every upgrade, patch, and new service type adds more platform team work. Without dedicated ownership the stack drifts, which defeats the standardization it was meant to create.</p><p>A managed IDP comes pre-integrated and maintained by the vendor. For teams between 15 and 60 engineers, that tradeoff usually makes more sense.</p><p><strong>2. What does an internal developer platform architecture include?</strong></p><p>An internal developer platform sits on top of your cloud infrastructure and abstracts it into layers developers can use directly. Those layers are infrastructure provisioning (environments, networking, compute), a deployment layer triggered by git push, service configuration (secrets, environment variables, custom domains), role-based access control across environments, and observability covering logs, metrics, and alerting.</p><p>In a well-built IDP these are not separate tools the platform team wires together. They come pre-integrated. A developer creates a service and gets all of it by default.</p><p><strong>3. How is platform engineering related to internal developer platforms?</strong></p><p>Platform engineering and internal developer platforms go hand in hand. Platform engineering is the practice. An internal developer platform is the output.</p><p>Platform engineering teams design systems that reduce infrastructure friction for developers. The IDP is what those systems look like in practice. It packages provisioning, deployments, and environment management into self-service workflows developers can use without understanding what runs underneath.</p><p><strong>4. Internal Developer Portal vs Platform: What is the difference?</strong></p><p>A portal is a catalog. It gives developers a place to find services, documentation, and tooling that already exists. The Backstage internal developer platform is the most common example.</p><p>A platform provisions and manages the infrastructure itself. The difference matters because a portal does not remove manual work. It organizes it. A platform automates it.</p><p><strong>5. Does an internal developer platform deploy on your own cloud account?</strong></p><p>Yes, for cloud accounts like AWS, internal developer platform provisions infrastructure directly inside your own account, not on shared infrastructure managed by the vendor. The VPCs, Kubernetes clusters, IAM roles, databases, and compute resources all live in your account and are billed to you by the cloud provider. This matters for a few reasons. Your data stays within your own cloud boundary. You retain full visibility and control over the underlying infrastructure. And if you ever need to move away, the infrastructure is already yours.</p><p>For growing SaaS teams this also covers enterprise customer requirements. When a customer needs a dedicated deployment in their own cloud account, the internal developer platform provisions it there using the same templates. No custom work per customer, no separate DevOps project, same process regardless of whose account it runs in.</p><h2>Take Away</h2><p>As SaaS teams grow, the real challenge is not writing more code, it&#8217;s managing the increasing complexity of infrastructure, environments, and deployments.</p><p>Relying on hiring more DevOps engineers might work temporarily, but it doesn&#8217;t solve the underlying problem. It adds coordination overhead, slows down workflows, and makes systems harder to manage over time.</p><p>The shift is not about scaling teams. It&#8217;s about scaling systems.</p><p>Internal developer platforms enable this shift by standardizing infrastructure, automating workflows, and making them accessible through self-service. Instead of depending on a few people to manage complexity, teams build systems that handle it consistently across every service and environment.</p><p>Platform engineering and internal developer platforms go hand in hand in making this possible. Together, they reduce cognitive load, improve developer experience, and allow teams to move faster without compromising reliability.</p><p>For growing teams, the goal is simple: remove friction, not add more layers to manage it.</p><p>Not sure where to start? The LocalOps team can help you figure out what fits your setup:</p><p><strong><a href="https://cal.com/anand-localops/tour?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Book a Demo</a> &#8594;</strong> Walk through how environments, deployments, and AWS infrastructure are handled in practice for your setup.</p><p><strong><a href="https://console.localops.co/signup?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Get started for free</a> &#8594;</strong> Connect an AWS account and stand up an environment to see how it fits into your existing workflow.</p><p><strong><a href="https://docs.localops.co/?utm_source=substack&amp;utm_medium=content&amp;utm_campaign=idp_blog">Explore the Docs</a> &#8594;</strong> A detailed breakdown of how LocalOps works end-to-end, including architecture, environment setup, security defaults, and where engineering decisions still sit.</p>]]></content:encoded></item></channel></rss>