<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Suraj Upadhyay</title>
    <description>The latest articles on DEV Community by Suraj Upadhyay (@suraj_at_esence).</description>
    <link>https://dev.to/suraj_at_esence</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3758776%2F0b3096f9-4563-4738-a9e6-527519002a96.jpg</url>
      <title>DEV Community: Suraj Upadhyay</title>
      <link>https://dev.to/suraj_at_esence</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/suraj_at_esence"/>
    <language>en</language>
    <item>
      <title>PostgreSQL Multi-Tenancy: Isolation That Survives a Growing Team</title>
      <dc:creator>Suraj Upadhyay</dc:creator>
      <pubDate>Fri, 28 Aug 2026 06:47:41 +0000</pubDate>
      <link>https://dev.to/suraj_at_esence/postgresql-multi-tenancy-isolation-that-survives-a-growing-team-259i</link>
      <guid>https://dev.to/suraj_at_esence/postgresql-multi-tenancy-isolation-that-survives-a-growing-team-259i</guid>
      <description>&lt;p&gt;Startups building B2B products reach for multi-tenancy in PostgreSQL the same way on day one: one shared database, one set of tables, and a &lt;code&gt;tenant_id&lt;/code&gt; column marking who owns each row. That is the correct call, and it stays correct for a long time. However, when that column is enforced by application code rather than by the database, a single forgotten predicate stops being a bug and becomes a disclosure event, and a disclosure event is one of the very few engineering failures that lands straight on your balance sheet as stalled enterprise deals, an unplanned legal bill, and a security review you can no longer pass. By understanding what multi-tenancy actually guarantees, which isolation model fits your stage, and how Row-Level Security moves that guarantee out of your codebase, startup CTOs and &lt;a href="https://esence.io/blogs/fractional-cto-for-startups-gain" rel="noopener noreferrer"&gt;Fractional CTOs&lt;/a&gt; can make the tenant boundary hold without slowing the team down.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(If you want to skip the theory, jump straight to the connection pooler trap that switches Row-Level Security off in production, what it costs in query performance, or when it is genuinely time to leave the shared schema.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because "enforced by application code" means something very specific in practice. It means a promise that everyone will remember to filter on &lt;code&gt;tenant_id&lt;/code&gt;, and that promise is the single most expensive line of undocumented policy in your entire codebase, because it holds perfectly for about fourteen months, right up until the afternoon a tired engineer ships a reporting endpoint that joins four tables and forgets the predicate on exactly one of them, and then a customer opens a dashboard and sees somebody else's invoices.&lt;/p&gt;

&lt;p&gt;That is not a bug. A bug is something you fix on Monday. A cross-tenant data leak is a disclosure event, which means legal gets involved, your enterprise prospects get an email from their own security team, and the deal that was supposed to close your Series A quietly moves to next quarter and then to never.&lt;/p&gt;

&lt;p&gt;The uncomfortable part is that this is not a story about careless engineers. It is a story about an architecture that requires every engineer to be careful forever, which is not an architecture at all, it's a hope.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is multi-tenancy in PostgreSQL?
&lt;/h2&gt;

&lt;p&gt;Multi-tenancy in PostgreSQL is the practice of serving multiple customers, called tenants, from a single database system while guaranteeing that no tenant can read or modify another tenant's data. PostgreSQL supports this at three levels of physical separation: a shared schema where a &lt;code&gt;tenant_id&lt;/code&gt; column marks ownership of each row, a separate schema per tenant, or a separate database per tenant.&lt;/p&gt;

&lt;p&gt;The word doing all the work in that definition is &lt;strong&gt;guaranteeing&lt;/strong&gt;. Any database can store several customers' rows in one table. What distinguishes a real multi-tenant architecture is where the guarantee lives, either in application code that every engineer must remember to write, or in the database itself, where it holds whether or not anyone remembered.&lt;/p&gt;

&lt;p&gt;PostgreSQL has shipped a mechanism for the second option since version 9.5, in 2016. It is called Row-Level Security, and most of this post is about using it without stepping on the three mines buried around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three isolation models, and what each one really costs
&lt;/h2&gt;

&lt;p&gt;There are exactly three shapes here, and every vendor blog that tells you otherwise is selling something.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Shared schema + &lt;code&gt;tenant_id&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Schema per tenant&lt;/th&gt;
&lt;th&gt;Database per tenant&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Separation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Logical, by column&lt;/td&gt;
&lt;td&gt;Logical, by namespace&lt;/td&gt;
&lt;td&gt;Physical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost per tenant&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Near zero&lt;/td&gt;
&lt;td&gt;Catalog rows, real at scale&lt;/td&gt;
&lt;td&gt;An instance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Migrations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One run&lt;/td&gt;
&lt;td&gt;A loop over tenants&lt;/td&gt;
&lt;td&gt;A loop over instances&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cross-tenant analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A query&lt;/td&gt;
&lt;td&gt;A fan-out job&lt;/td&gt;
&lt;td&gt;A pipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Noisy-neighbour control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Restore one tenant&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hard&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Trivial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enforcement&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RLS, or app code&lt;/td&gt;
&lt;td&gt;Namespace + &lt;code&gt;search_path&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Connection string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Choose this when&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Default. Almost everybody.&lt;/td&gt;
&lt;td&gt;Tenant schemas genuinely diverge&lt;/td&gt;
&lt;td&gt;A named customer or a residency law demands it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most startups pick the shared schema correctly and then defend it incorrectly, which is a distinction worth sitting with, because the shared schema really is the right default for almost everybody reading this. You should not be running a schema per tenant at eleven customers, and the founder who spent a quarter building a database-per-tenant provisioning pipeline before finding product-market fit has bought a very good insurance policy on a house he has not finished building.&lt;/p&gt;

&lt;p&gt;The mistake is not picking the shared schema. The mistake is enforcing it in application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Row-Level Security actually works
&lt;/h2&gt;

&lt;p&gt;Row-Level Security is a PostgreSQL feature that attaches a boolean policy to a table, which the planner then welds onto every query touching that table, so that rows failing the policy are invisible regardless of what the query asked for. A missing &lt;code&gt;WHERE tenant_id = ...&lt;/code&gt; stops being a data leak and starts being an empty result set, which is a category of failure your QA process can actually&lt;br&gt;
catch.&lt;/p&gt;

&lt;p&gt;To read the full articles you can visit 👉 &lt;a href="https://esence.io/blogs/postgresql-multi-tenancy-for-startups" rel="noopener noreferrer"&gt;PostgreSQL Multi-Tenancy: Isolation That Survives a Growing Team&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I write about startup systems architecture at&lt;br&gt;
&lt;a href="https://esence.io/blogs" rel="noopener noreferrer"&gt;esence.io&lt;/a&gt;. If your tenant boundary is currently held together by code review, that is the kind of thing I look at for a living.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>backend</category>
      <category>software</category>
    </item>
    <item>
      <title>Why Startups should only hire a Fractional CTO instead</title>
      <dc:creator>Suraj Upadhyay</dc:creator>
      <pubDate>Wed, 08 Jul 2026 18:30:00 +0000</pubDate>
      <link>https://dev.to/suraj_at_esence/why-startups-should-only-hire-a-fractional-cto-instead-5c9f</link>
      <guid>https://dev.to/suraj_at_esence/why-startups-should-only-hire-a-fractional-cto-instead-5c9f</guid>
      <description>&lt;h2&gt;
  
  
  Tech Leadership hiring is a strategic, inevitable and deeply financial decision
&lt;/h2&gt;

&lt;p&gt;Designing an Engineering Team as a Founder is more important than your&lt;br&gt;
Engineering Team designing your system or your product. I have worked with a&lt;br&gt;
couple of startups and have seen a common pattern -&lt;/p&gt;

&lt;p&gt;A non-technical founder having an idea and a figma file hires a couple of&lt;br&gt;
engineers, builds a great product, sees some success in the market or closes an&lt;br&gt;
institutional Seed or Series A round and ends up hiring a CTO with 18 years of&lt;br&gt;
experience to lead the engineering team that has built the product.&lt;/p&gt;

&lt;p&gt;This new full-time CTO having a brilliant career graph of 18 years, being a&lt;br&gt;
principal or a staff engineer in a distinguished Company starts on his new role&lt;br&gt;
feeling utterly clueless on how startups actually work. He starts by analyzing&lt;br&gt;
the codebase and the current architecture of the product, and finds major flaws&lt;br&gt;
in how the product is actually implemented, he begins by pointing out that many&lt;br&gt;
of the best principles aren't followed and the whole codebase is tightly coupled&lt;br&gt;
and making changes is a nightmare.&lt;/p&gt;

&lt;p&gt;He immediately creates tens and hundreds of Jira tickets and dictates the&lt;br&gt;
engineering team to finish them before building any other major features. And he&lt;br&gt;
does all this by sending emails and meeting once or twice in a couple of days,&lt;br&gt;
barely joining standup calls, because that's what he is used to.&lt;/p&gt;

&lt;p&gt;The engineering team accustomed to the fast-paced nature of startups finds it a&lt;br&gt;
bit more difficult to actually write good quality code that would satisfy&lt;br&gt;
an industry veteran, but still delivers in a record time. To them, it was the&lt;br&gt;
biggest learning curve of their entire lifetime, but our veteran is still not&lt;br&gt;
satisfied and stalls your feature roadmap to force an abstract architectural&lt;br&gt;
rewrite.&lt;/p&gt;

&lt;p&gt;Time passes by, and you as a founder start seeing stagnancy in your&lt;br&gt;
organization even after burning precious runway on massive executive&lt;br&gt;
compensation packages for the engineering team, but don't know what exactly&lt;br&gt;
went in the wrong direction since all the reasoning given by our veteran seems&lt;br&gt;
fool-proof and unavoidable.&lt;/p&gt;




&lt;p&gt;If this story sounds familiar or you are going through something similar, then&lt;br&gt;
let me tell you that it happens to the best of ambitious founders but it can be&lt;br&gt;
solved through strategic hiring and re-assessing your leadership needs.&lt;/p&gt;

&lt;p&gt;Here's what experience and seasoned serial entrepreneurs do instead -&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hire a Fractional CTO!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you should hire a Fractional CTO
&lt;/h2&gt;

&lt;p&gt;There's a huge difference between hiring an engineer and hiring engineering&lt;br&gt;
leadership like a CTO, a Staff Engineer or a Software Architect.&lt;/p&gt;

&lt;p&gt;When you hire a developer, you are paying for execution output. When you hire a &lt;br&gt;
CTO, you are making a structural bet on the trajectory of your product, your &lt;br&gt;
cap table, and your company's operational burn rate. &lt;/p&gt;

&lt;p&gt;An early-stage startup does not need an 18-year corporate veteran sitting on a &lt;br&gt;
full-time salary to manage four developers. They need elite architectural taste &lt;br&gt;
delivered in high-impact, concentrated bursts. &lt;/p&gt;

&lt;p&gt;They need a &lt;strong&gt;Fractional CTO&lt;/strong&gt;. Here is exactly why:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Paradox of the "Enterprise Blueprint"
&lt;/h3&gt;

&lt;p&gt;An enterprise executive’s instinct is to minimize risk through process, &lt;br&gt;
bureaucracy, and heavy administrative compliance frameworks. In a startup,&lt;br&gt;
your greatest risk isn't a minor system drift, it's &lt;strong&gt;moving too slow and&lt;br&gt;
dying before you find product-market fit.&lt;/strong&gt; A Fractional CTO builds minimalist,&lt;br&gt;
flexible foundations that allow your team to pivot instantly without getting&lt;br&gt;
trapped under 400 unresolved Jira tickets.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Radical Runway Frugality
&lt;/h3&gt;

&lt;p&gt;Let’s talk numbers. A high-caliber, full-time CTO demands massive cash &lt;br&gt;
compensation, heavy equity grants, and expensive corporate benefits. For a &lt;br&gt;
startup, that is an incredibly heavy liability to carry on day one. A&lt;br&gt;
Fractional CTO gives you access to elite, battle-tested architectural&lt;br&gt;
governance at a fraction of the overhead cost, allowing you to preserve&lt;br&gt;
capital and deploy your cash directly into hiring raw, high-output execution&lt;br&gt;
developers instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Execution-Focused Mentorship
&lt;/h3&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;You can read the full article on my blog - &lt;a href="https://esence.io/blogs/fractional-cto-for-startups-gain" rel="noopener noreferrer"&gt;Engineering Insights at Esence.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>software</category>
      <category>webdev</category>
      <category>cto</category>
    </item>
    <item>
      <title>Scaling Codebases Without Platform Bloat</title>
      <dc:creator>Suraj Upadhyay</dc:creator>
      <pubDate>Wed, 01 Jul 2026 04:19:00 +0000</pubDate>
      <link>https://dev.to/suraj_at_esence/scaling-codebases-without-platform-bloat-1dj8</link>
      <guid>https://dev.to/suraj_at_esence/scaling-codebases-without-platform-bloat-1dj8</guid>
      <description>&lt;p&gt;Redundant compilation lags, bloated CI pipelines and version drift for internal&lt;br&gt;
modules quietly drain developer velocity. And normally, it's too late when the&lt;br&gt;
leadership gets the whiff of it. According to recent studies, the hidden tax on&lt;br&gt;
your team looks exactly like this -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Direct Time Drain&lt;/strong&gt;: Your engineers waste an average of 25 to 50 minutes&lt;br&gt;
due to compilation lags.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Redundant Build&lt;/strong&gt;: An engineer wastes his valuable time rebuilding&lt;br&gt;
something that already exists and is being used in another team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Pipeline Blocker&lt;/strong&gt;: Your Frontend Team spends an entire sprint cycle&lt;br&gt;
completely idle, waiting for the Core Platform Team to version-tag and publish&lt;br&gt;
the latest approved button changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these, as bad as they sound, are common occurrences in the majority of&lt;br&gt;
software engineering teams trying their best to ship fast and iterate faster.&lt;br&gt;
The problems that I listed are not inevitable, and can be solved if we just&lt;br&gt;
carefully design our engineering culture and the codebase that it revolves&lt;br&gt;
around from the beginning.&lt;/p&gt;

&lt;p&gt;In today's edition, let's tackle them one-by-one and continue where we left off&lt;br&gt;
last time in our adventure of building&lt;br&gt;
&lt;a href="//./ideal-startup-monorepo-local-workspace"&gt;the ideal monorepo setup&lt;/a&gt; for&lt;br&gt;
startups.&lt;/p&gt;

&lt;p&gt;Assuming that you followed my advice of having a monorepo for all your codebase&lt;br&gt;
needs for your startup, let's hit the road!&lt;/p&gt;
&lt;h2&gt;
  
  
  The Redundant Build: A guide to module re-use
&lt;/h2&gt;

&lt;p&gt;While there's no sure-shot way of knowing what an engineer thinks before&lt;br&gt;
embarking on the painstaking journey of rebuilding the wheel, we can mitigate&lt;br&gt;
the risk through some primary cautions -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Build a collection of re-usable modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Business logic must never be allowed to be repeated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Engineers should learn about the existing system for their use-case.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though I know, forcing software engineers to do something they don't approve of&lt;br&gt;
is never a good idea. But Companies and Team Leads should force these elementary&lt;br&gt;
coding principles rigorously via code-reviews and documentation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Building a Collection of Reusable modules
&lt;/h3&gt;

&lt;p&gt;Startups that successfully keep growing, also tend to constantly rebuild many&lt;br&gt;
parts of their system again and again. To give you a few examples -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UI Components&lt;/strong&gt;: The same kind of button, the same navigation bar, the same&lt;br&gt;
sidebar nav, etc. are rebuilt across different product lines to keep the look and&lt;br&gt;
feel of the brand consistent. The website may be using the same color scheme as the&lt;br&gt;
product dashboard, and hence the components get duplicated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backend Modules&lt;/strong&gt;: If you have more than one backend, chances are that you&lt;br&gt;
are duplicating the authentication, the logging, the middlewares, the utility&lt;br&gt;
modules and many others depending upon your particular use-case.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Due to this, some parts of your website might look and feel different than the&lt;br&gt;
other parts, worst-case it might feel they are built by different companies&lt;br&gt;
altogether. And it's not just about how the UI looks, if you have duplicated&lt;br&gt;
backend code, your team sometimes might end up debugging an edge-case over a&lt;br&gt;
weekend that an engineer didn't think, while rebuilding the authentication&lt;br&gt;
pipeline all over again.&lt;/p&gt;

&lt;p&gt;To best avoid the above duplication, is to use the &lt;code&gt;packages&lt;/code&gt; directory in your&lt;br&gt;
monorepo root judiciously.  That is if you followed the monorepo structure that&lt;br&gt;
I advocated in the &lt;a href="//./ideal-startup-monorepo-local-workspace"&gt;previous edition&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you are already doing that, it's better to keep the reusable modules kept&lt;br&gt;
inside the &lt;code&gt;packages&lt;/code&gt; directory - &lt;em&gt;loosely coupled&lt;/em&gt;, &lt;em&gt;highly parameterised&lt;/em&gt; and&lt;br&gt;
&lt;em&gt;customizable&lt;/em&gt; through environment variables and feature flags.&lt;/p&gt;
&lt;h3&gt;
  
  
  Consistent Business Logic
&lt;/h3&gt;

&lt;p&gt;If there's one thing that you should absolutely avoid, then it has got to be&lt;br&gt;
business logic duplication. Given enough time, codes change, bugs appear and get&lt;br&gt;
fixed, engineers might come and go, but hardcore business logic seldom changes.&lt;/p&gt;

&lt;p&gt;To give you an example, if you are building an accounting system, then your tax&lt;br&gt;
calculation logic must never be repeated. If it does get repeated across your&lt;br&gt;
backends and your frontends, then each update to the tax calculation logic,&lt;br&gt;
debugging sessions and eventual hot-fixing, would need to be made across the&lt;br&gt;
board and be forced to be compatible in each of the environments, causing&lt;br&gt;
huge business consequences&lt;/p&gt;

&lt;p&gt;I would like to recommend keeping a separate privileged module inside your&lt;br&gt;
shared-modules, for such sensitive business logic and have a &lt;code&gt;CODEOWNERS&lt;/code&gt; entry &lt;br&gt;
such that unauthorised engineers (most likely the interns) can never make any&lt;br&gt;
changes to the same.&lt;/p&gt;

&lt;p&gt;An example &lt;code&gt;CODEOWNERS&lt;/code&gt; entry might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .github/CODEOWNERS&lt;/span&gt;
&lt;span class="c"&gt;# Guarding core business logic from unauthorized modifications&lt;/span&gt;

&lt;span class="c"&gt;# Global fallback auditors&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt; @esence-io/platform-leads

&lt;span class="c"&gt;# Strict guardrails for sensitive domain algorithms&lt;/span&gt;
/packages/domains/billing/tax-calculator.ts       @esence-io/finance-architects
/packages/domains/appointments/compliance.go     @esence-io/medical-directors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Documentation for Reusable Modules
&lt;/h3&gt;

&lt;p&gt;This might be the only thing that separates an average organization from a&lt;br&gt;
great organization that has some degree of foresight. &lt;/p&gt;

&lt;p&gt;However, in an early-to-mid-stage startup, telling engineers to spend hours&lt;br&gt;
writing long-form documentation on a separate Confluence or Notion workspace is &lt;br&gt;
a fantasy. It creates out-of-date documentation platforms that nobody trusts, &lt;br&gt;
adding to your organizational bloat.&lt;/p&gt;

&lt;p&gt;The frugal, high-velocity alternative is &lt;strong&gt;Git-Adjacent Documentation&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Workspace READMEs&lt;/strong&gt;: Every package inside your &lt;code&gt;/packages/*&lt;/code&gt; directory &lt;br&gt;
must contain a minimalist &lt;code&gt;README.md&lt;/code&gt; explaining its API footprint, schema&lt;br&gt;
rules, and runtime assumptions. If an engineer alters code logic, they update&lt;br&gt;
the text in the exact same git commit string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strict Typing&lt;/strong&gt;: Let your compiler act as your documentation &lt;br&gt;
hub. By enforcing explicit input/output interface boundaries on shared&lt;br&gt;
components, your IDE automatically tells the frontend engineer exactly what&lt;br&gt;
parameters a component expects without them ever leaving their workspace&lt;br&gt;
terminal window.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better Code-Comments&lt;/strong&gt;: Come-on, no one writes good comments.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If code isn't discoverable from inside the repo editor, it doesn't exist.&lt;br&gt;
&lt;strong&gt;Keep it in git&lt;/strong&gt; and the engineers will follow.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trunk-Based Development: Unblocking the pipeline
&lt;/h2&gt;

&lt;p&gt;What if every engineer works on the latest changes produced by every other team?&lt;br&gt;
And what if every team starts taking ownership of the changes they make?&lt;/p&gt;

&lt;p&gt;To answer both the questions in a strong &lt;strong&gt;Yes&lt;/strong&gt;, your engineering team has to&lt;br&gt;
follow the paradigm of "Trunk-Based Development".&lt;/p&gt;

&lt;p&gt;Trunk-Based Development as opposed to module-versioning and importing foreign&lt;br&gt;
modules from registries, means that a monorepo contains everything it needs and&lt;br&gt;
every module it has, is on the latest version. And, cross-module dependencies&lt;br&gt;
just become a question of either importing those modules or their DLLs or&lt;br&gt;
binaries, completely bypassing the network-overhead of fetching latest modules.&lt;/p&gt;

&lt;p&gt;There are no version numbers to increment, no private registries to maintain,&lt;br&gt;
and no upstream breaking changes hidden behind a semver tag. And no wasteful&lt;br&gt;
standup meetings discussing whether a change is breaking enough to bump up the&lt;br&gt;
version entirely.&lt;/p&gt;

&lt;p&gt;Once your company starts following trunk-based development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the Core Platform UI Team changes the button style or its parameters, it's&lt;br&gt;
going to be the Core UI Team's responsibility to change it across the codebase.&lt;br&gt;
Thereby, creating implicit ownership of all the changes that break integration&lt;br&gt;
tests or that make other project's compilers scream.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The cost and complexity of infrastructure behind private module/package&lt;br&gt;
registries instantly become zero and setting up the local environment for the&lt;br&gt;
new joinee just becomes executing the build commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a shared or an inter-team module breaks, no one has to get blocked for&lt;br&gt;
getting fixes and updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All teams to some extent become software/module testers for all the other&lt;br&gt;
teams by becoming a direct consumer with a zero-lag feedback loop.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One easy way to do it for TypeScript workspaces is by simply including workspace&lt;br&gt;
dependencies like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@packages/ui"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workspace:*"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It isn't complicated, unless you start making it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilation Lags and Caching Build Artifacts: With Nx
&lt;/h2&gt;

&lt;p&gt;You pay money-tax to the government for earning, and pay time-tax to the&lt;br&gt;
compiler for coding. Startups hire accountants for reducing tax paid to the&lt;br&gt;
government, but seldom pay any attention to the tax paid to the compiler that&lt;br&gt;
slowly leaks their pockets in terms of wasted productive hours of a developer&lt;br&gt;
on a payroll.&lt;/p&gt;

&lt;h2&gt;
  
  
  You can read the full article on my blog - &lt;a href="https://esence.io/blogs/scaling-startup-monorepo-boundaries-caching" rel="noopener noreferrer"&gt;Engineering Insights at Esence.io&lt;/a&gt;
&lt;/h2&gt;

</description>
      <category>softwareengineering</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>startup</category>
    </item>
    <item>
      <title>The Zero-Drift Ideal Monorepo Setup for Startups</title>
      <dc:creator>Suraj Upadhyay</dc:creator>
      <pubDate>Sun, 14 Jun 2026 05:15:25 +0000</pubDate>
      <link>https://dev.to/suraj_at_esence/the-zero-drift-ideal-monorepo-setup-for-startups-3l2g</link>
      <guid>https://dev.to/suraj_at_esence/the-zero-drift-ideal-monorepo-setup-for-startups-3l2g</guid>
      <description>&lt;h2&gt;
  
  
  An Overhead-Free Monorepo Blueprint for High-Velocity Teams
&lt;/h2&gt;

&lt;p&gt;The first design decision for any serious tech startup is to decide how their&lt;br&gt;
codebase is structured, and building a monorepo setup often proves to be&lt;br&gt;
crucial for avoiding cross-project dependency maintenance that can stretch &lt;br&gt;
a small-to-mid sized engineering team which most startups cannot afford in&lt;br&gt;
pre-venture or revenue stages.&lt;/p&gt;
&lt;h2&gt;
  
  
  What does an "ideal" monorepo look like?
&lt;/h2&gt;

&lt;p&gt;While there are multiple ways a developer or a company can structure their&lt;br&gt;
monorepos and it's true that there isn't an ideal setup that fits all case&lt;br&gt;
scenarios, there are universal architectural truths that separate a clean&lt;br&gt;
engineering workspace from a chaotic one&lt;/p&gt;

&lt;p&gt;There are some salient features that every staff engineer or software&lt;br&gt;
architect should aim to achieve with their monorepos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reproducible environment&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Domain driven development&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Module and library re-use&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trunk-based development&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Central build cache registry&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simpler deployment pipelines&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Package security, visibility and role-based code access&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most successful monorepos satisfy most or all of the above requirements.&lt;/p&gt;

&lt;p&gt;I have worked with a couple of startups and have seen them all struggling with&lt;br&gt;
getting most of the above requirements right. &lt;br&gt; Even established companies with&lt;br&gt;
100s of engineers, sometimes have to spend hundreds of thousands of dollars,&lt;br&gt;
if not millions, on platform engineers just to manage their codebase and build&lt;br&gt;
pipelines.&lt;/p&gt;

&lt;p&gt;Now, Let's go through each one of the "ideal monorepo" requirements and create&lt;br&gt;
a best in class workspace for the engineering team.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a Reproducible Environment
&lt;/h2&gt;

&lt;p&gt;If you are a founder or someone from the tech leadership, there's a possiblity&lt;br&gt;
that you hear this phrase a couple of times in a week - "it works on my machine,&lt;br&gt;
I think something is wrong with the deployment". And most of the times, the&lt;br&gt;
deployment turns out be just fine and it's the developer's local environment&lt;br&gt;
configuration that's been acting up.&lt;/p&gt;

&lt;p&gt;Also, there's a huge possiblity that every new engineer you onboard takes at&lt;br&gt;
least 3 days to settle in and get comfortable with the codebase and all the&lt;br&gt;
tools required to setup a normal working local environment.&lt;/p&gt;

&lt;p&gt;What I have just described above is a classical design flaw from the early days&lt;br&gt;
of a codebase, whether a monorepo or a polyrepo.&lt;/p&gt;

&lt;p&gt;The medicinal anti-dote to this exact most common problem in tech companies is using&lt;br&gt;
sandboxing tools that isolate the development environment and levels down the&lt;br&gt;
playing field for all the engineers.&lt;/p&gt;

&lt;p&gt;We are going to take a look at one of these tools today, that can easify your&lt;br&gt;
life managing a tech team or running a tech company.&lt;/p&gt;
&lt;h3&gt;
  
  
  Devbox - The ideal sandbox for your dev environment
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.jetify.com/devbox" rel="noopener noreferrer"&gt;Devbox&lt;/a&gt; is an open-source, Nix-based package&lt;br&gt;
manager that creates isolated, reproducible development environments without the&lt;br&gt;
resource overhead of local Docker containers. And it is just the right tool to achieve&lt;br&gt;
environment isolation that I have personally used in many of my projects.&lt;/p&gt;

&lt;p&gt;It's not as heavy or expensive as managing docker configurations and forcing&lt;br&gt;
developers to write code in docker native IDEs.&lt;/p&gt;

&lt;p&gt;Let's start with the first steps of our desired setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install devbox&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.jetify.com/devbox | bash

&lt;span class="c"&gt;# Create directory for your codebase&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;monorepo
&lt;span class="nb"&gt;cd &lt;/span&gt;monorepo

&lt;span class="c"&gt;# Initialise the monorepo with devbox&lt;/span&gt;
devbox init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's take a step back and ponder over our requirements from this virtual&lt;br&gt;
environment. Most of the modern mid-level complexity full stack projects need&lt;br&gt;
at least these pieces of tools to work correctly:&lt;/p&gt;

&lt;p&gt;Essential Core Utilities:&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git (Version Control)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frontend Engineering Layers:&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js (V8 Application Runtimes)
&lt;/li&gt;
&lt;li&gt;Bun (High-Performance Local Testing &amp;amp; Package Management)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Systems &amp;amp; Data Processing Services:&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go (Highly Scalable Backend Web Servers)
&lt;/li&gt;
&lt;li&gt;Python (Machine Learning Infrastructure &amp;amp; Automation Pipelines)&lt;/li&gt;
&lt;li&gt;CMake/Make (Build tool for C/C++ used for high performance)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list of the above tools is strictly my own choice and you can chose to go&lt;br&gt;
with your own vibe of toolsets, that you want to be written on the stone for all&lt;br&gt;
your team mates.&lt;/p&gt;

&lt;p&gt;Let's install all of these and peg them against a version number to lock in the&lt;br&gt;
tool of choice for everyone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Discover the versions of tools with&lt;/span&gt;
devbox search git &lt;span class="nt"&gt;--show-all&lt;/span&gt; &lt;span class="c"&gt;# This gives a list of all available git versions&lt;/span&gt;

&lt;span class="c"&gt;# Now add the desired version of the tool to your local environment&lt;/span&gt;
devbox add git@latest

devbox add node@latest
devbox add bun@latest

devbox add python@latest
devbox add go@latest

&lt;span class="c"&gt;# Add any other tool(s) that your team needs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the last step is to officially enter into the virtual environment that we have&lt;br&gt;
created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enter into the devbox environment&lt;/span&gt;
monorepo &lt;span class="nv"&gt;$ &lt;/span&gt;devbox shell

&lt;span class="c"&gt;# Just when you execute the above command, your terminal prompt becomes this&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;devbox&lt;span class="o"&gt;)&lt;/span&gt; monorepo &lt;span class="nv"&gt;$ &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, whenever the new intern asks how he should pull the project and start the&lt;br&gt;
contributing you just tell him to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;your-repository-location&amp;gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;your-repository&amp;gt;

&lt;span class="c"&gt;# And...&lt;/span&gt;
devbox shell

&lt;span class="c"&gt;# 🤯, he is all setup!!&lt;/span&gt;
&lt;span class="c"&gt;# Now the only thing left is to execute the install scripts&lt;/span&gt;
&lt;span class="c"&gt;# and actually run the projects.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it just took him 2 minutes to start with the project without the weird&lt;br&gt;
environment issues and it didn't matter if he is on Macbook or Linux or&lt;br&gt;
Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go Task - A central registry for all commands in your project
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://taskfile.dev/" rel="noopener noreferrer"&gt;Go Task&lt;/a&gt; is an open source utility that can map simple&lt;br&gt;
words with complex commands, so that the junior devs never have to ping you in&lt;br&gt;
the middle of the night just to figure out the command that they wrote had a&lt;br&gt;
typo in it.&lt;/p&gt;

&lt;p&gt;You can read the full article on my blog - &lt;a href="https://esence.io/blogs/ideal-startup-monorepo-local-workspace" rel="noopener noreferrer"&gt;Engineering Insights at Esence.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>monorepo</category>
      <category>devex</category>
      <category>devbox</category>
      <category>nx</category>
    </item>
  </channel>
</rss>
