When the Cloud Is the Friction
For years, SaaS was the thing that removed friction from buying software. Pay a monthly fee, log in, use the product. No installation, no ops, no procurement department burning a quarter on your purchase order. For consumer software and SMB software this still holds. For enterprise sales of AI products the calculus often runs the other way. The SaaS-evaluation gauntlet has grown long enough that, for some segments, the cheapest path through it is to not be a SaaS. What the customer wants to buy is the absence of having to evaluate another vendor, route their data through another perimeter, fill out another security questionnaire, and find another budget line.
This post is about what that means in practice. It covers four shifts that have made cloud-hosted AI more expensive to sell into enterprise than it used to be. It covers what enterprise AI sales looks like in the field. It covers two responses worth considering, with the trade-offs of each. It covers the architectural principles that make heterogeneous deployment possible from one codebase. And it covers what people mean by “local-first” and “self-hosted” and “BYO model,” because the terms get used interchangeably and they are not the same thing.
Four terms that get used as if they were one
In customer conversations and marketing copy, “local-first,” “self-hosted,” “on-prem,” “air-gapped,” and “BYO model” tend to flow together. They are distinct, with distinct architectural costs, and the customer conversation goes better when you can name which one they want.
Local-first is a UX and sync architecture. The user’s working copy of the data lives on their device. Reads and writes happen against a local store. Sync to a server is asynchronous, conflicts are merged either by CRDTs or by a server-authoritative replay model, and the app keeps working when the network is bad or absent. The pure-CRDT version allows peer-to-peer with no central server in principle. The more common production shape is a central authoritative server with optimistic local writes and rebase-on-pull semantics, which is what Linear’s sync engine, Replicache, and Convex implement. Local-first is about where the user’s working copy lives.
CRDT libraries: Automerge, Yjs. Sync engines: Replicache, ElectricSQL, Triplit, Jazz. Background: the Ink & Switch essay that named the movement, and Linear on scaling their sync engine.
Self-hosted (customer-hosted) is a deployment topology. The application runs in the customer’s infrastructure rather than yours: their AWS account, their Kubernetes cluster, their on-prem servers. They operate it; you ship updates. Self-hosted is about whose cloud the application runs in.
Public examples: GitLab self-managed, Sentry, PostHog, the Plausible community edition, Mattermost, Bitwarden.
Air-gapped is a network topology. The system has no path to the public internet. Updates arrive on physical media or through a tightly controlled inbound channel. Defence, intelligence, some healthcare and financial workloads. Air-gapped is about what the application is allowed to talk to.
BYO model is a credential and routing choice. The customer supplies the LLM endpoint and credentials, hosted or local. Your code calls the model with their credentials. BYO model is about whose key gets billed and whose terms govern the inference.
Endpoints: AWS Bedrock, Azure OpenAI, Vertex, or a local server such as Ollama or vLLM.
These dimensions are independent but they combine usefully. Self-hosting plus BYO model gives the customer a complete data-sovereignty story: the application code and the model both run in their environment, and you do not see, store, or process their data. Self-hosting plus air-gap is the most paranoid deployment, viable only if the model also runs locally, since hosted-model APIs require internet egress (an Azure OpenAI deployment is reachable from a customer’s VPC but not from a truly air-gapped network). Local-first plus a small local model gives an offline-capable client that can do real work without a server at all. The architecture that makes one of these tractable tends to make the others tractable too, because they share the same demand: the deployment-varying concerns have to be cleanly separated from the domain.
Knowing the distinctions also matters when a customer asks for one thing while meaning another. “We want to run this on our infrastructure” sometimes means self-hosting, sometimes means BYO model, sometimes means air-gapped. “We want offline support” is local-first. “Our reps work on planes” is local-first. “Our data cannot leave our perimeter” can be satisfied by self-hosting alone, with BYO model layered on if the customer also objects to the inference being seen by a hosted model provider.
Why AI sharpens the problem
Four things changed at once.
Data gravity inverted. Cloud-era thinking assumed data flowed to compute. The cheapest move was to ship the data to wherever the compute lived. With LLM workloads, the data is often too sensitive, too large, or too regulated to ship. Compute moves to the data instead. A bank does not want to send its loan files to a third-party SaaS to be summarised by a third-party model running on a fourth party’s GPU. It wants the summariser to come to the files.
Vendor risk has become first-class. When your product depends on OpenAI or Anthropic, you sit downstream of their pricing, their availability, their deprecation cycles, their content policies, and their data-use terms. Models get deprecated on a few months’ notice and the replacement behaves differently. Prices rise. New content policies break flows that worked yesterday.
The underlying economics make this more acute, not less. The largest model providers are spending at a scale where the payback is unclear. OpenAI has reportedly told investors it expects to burn through $115 billion in cash by 2029 and is targeting roughly $600 billion in compute spend by 2030, financed in part by debt-funded data-centre buildouts. Bain has estimated that AI revenue across the industry will fall something like $800 billion short of what is needed by 2030 to pay for the projected compute, on plausible demand scenarios. Some observers have argued the AI infrastructure boom looks like the next great mispricing of capital in tech, with circular financing arrangements (chip makers investing in model providers that then buy the chips) and data-centre projects already running into construction and power-supply trouble. None of that means the providers will disappear. It does mean their prices, terms, and existence are not as stable a substrate to build on as they looked two years ago. A model the customer pins to a version, or runs themselves, is durable in a way a hosted endpoint is not.
The compliance bar moved up. Two years ago, SOC 2 Type II and a passable security questionnaire would carry most mid-market deals. Now AI vendors face a thicker stack: data-handling addenda, model-output indemnification, training-data certifications, residency commitments, sometimes formal AI risk reviews. These exist because the customer’s legal and security teams have been burned, or have watched others get burned, by LLM-related incidents. Self-hosting collapses much of this into a shorter question: does any data leave our perimeter? If the answer is no, half the questionnaire stops applying.
Procurement is the product. Customers in regulated industries buy the absence of having to evaluate you as a data processor. A SaaS sale requires landing the user, the buyer, the security team, the procurement team, the legal team, and the budget owner. A self-hosted deployment usually requires landing the user, the buyer, and the security team, because the data never leaves and the legal and procurement work shrinks accordingly. The architectural choice has a direct sales-cycle effect.
What enterprise AI sales actually looks like
What follows is from running engineering at Aether, a startup processing customer data through AI models. I was CTO, not in sales, but security questionnaires landed on my desk and pilots ran through engineering, so I saw the gauntlet from the inside.
The questionnaires arrived early and were long. Some were short, some were enormous, and the long ones asked for evidence behind every claim. SOC 2 Type II was desirable rather than strictly required, and customers wanted to know how data was logically separated between tenants, how access was controlled, how subprocessors were vetted, how breaches were reported, how data deletion was handled on request, how long backups were retained, how the model was prevented from training on their content, where the data was geographically resident, and how all of this would be re-attested annually. Filling a serious questionnaire well took days.
The harder question to answer was about positioning. Customers had typically already bought seats of Microsoft Copilot or Gemini for Workspace. They wanted to know how we related to those. The real answer was that we were not trying to displace them. We did specialised work in a domain where the horizontal assistants would not be deep enough, and the right relationship was alongside the assistant, not instead of it. Communicating that distinction was hard. The default framing the customer brought was competitive (“what does this do that Copilot does not?”) even when the actual proposition was complementary. Reframing the conversation took most of the first call and sometimes did not stick.
Then SaaS fatigue. Procurement teams had been told to consolidate vendors. The budget owner had a list of tools to retire, not add. Every new purchase needed either a clear retirement to fund it, or a clear category that no existing tool covered. “Yet another AI tool” was the death of more deals than security ever was.
Buying decisions also fractured across roles. The user wanted the product. The user’s manager wanted to look forward-thinking. The security team wanted to slow it down. The procurement team wanted a discount. The legal team wanted indemnification language they could live with. The CFO wanted ROI before signature. The CIO wanted alignment with the existing platform strategy. The purchaser was often not the user, the user was rarely the budget owner, the budget owner was not the security approver, and any of them could kill a deal in the final week. Internal pilots stretched for months without converting, sometimes because the user loved the product but could not push it through legal in time for the budget cycle to close.
This is what the cloud-as-friction inversion looks like in the field. The work of getting a SaaS purchase through has grown to the point where the deployment shape and the go-to-market motion deserve to be a deliberate strategic choice rather than a default.
Two responses we considered
We thought about two changes in approach, and would seriously pursue both next time. Neither replaces a SaaS motion; both run alongside it.
The first is what some people call a Trojan horse: instead of selling a new product the customer logs into, build a capability inside the customer’s existing AI surface. Custom tools and agents inside Copilot, Gemini for Workspace, ChatGPT Enterprise, and the equivalents. The customer’s identity, auth, SCIM provisioning, and storage are already provisioned. The customer’s procurement has already approved the host platform. The user already has the host platform open. What you ship is a tool, or a small agent, that does the specific thing you do, accessible inside the chat or workspace the user already uses. You become a capability inside their stack, not a tab in their browser. A society of specialist agents collaborating inside the customer’s existing surface is sometimes the right shape: a contract reviewer, a vendor due-diligence specialist, a technical-documentation helper, each accessible from the same place, each with bounded authority over data the customer already keeps in the host platform.
This approach sidesteps the SaaS evaluation gauntlet because the customer is not buying a new SaaS. They are installing a tool inside the SaaS they already bought. The costs are real: you give up brand presence, you constrain your UX to what the host allows, and you expose yourself to the host’s distribution and pricing changes. But for narrow specialist workloads where the customer has already standardised on a host platform, the procurement bypass is significant.
The second is moving faster on product-led growth. Aggressive self-service, public trial accounts, low-touch onboarding, and observable in-product usage. The point is not the marketing channel; the point is the learning loop. Selling through an enterprise gauntlet produces deal feedback, which is fragmentary and biased by all the people in the room with motivations other than using the product. Self-service usage produces direct feedback from the people doing the work on the workflows that matter to them, which is what you need to tune the product. The cloud-as-friction problem makes the case for PLG stronger, not weaker: if the SaaS path will require months of procurement per customer regardless, you may as well also run a parallel path that gives many users the product in a few minutes and tells you what they do with it.
PLG and the Trojan horse are not in tension. Each gives you a faster path to learning than the long enterprise sale, and they cover different segments. PLG reaches users who can self-serve. The in-stack approach reaches customers whose procurement has consolidated on a host platform. Enterprise direct sales remains the path for the largest regulated deals. The mistake worth avoiding is depending on enterprise direct as the only motion.
What architecture makes heterogeneous deployment tractable
Running the same codebase across your cloud, customer clouds, on-prem hardware, and air-gapped networks, against hosted or local models, is only tractable if the architecture is set up for it. The principles are simpler than the catalogue of tools makes them sound.
Isolate the things that change between deployments from the things that do not. Storage, message bus, blob store, secrets management, identity provider, telemetry destination, and model endpoint are the dimensions where deployment varies. The domain logic should not know which of these it is talking to. The standard discipline here is hexagonal architecture: each external dependency sits behind a port, and one or more adapters implement that port. The domain calls the port. Production has one adapter, the customer-hosted deployment has another, the in-memory test fake is a third, and the air-gapped deployment is a fourth where needed. Adding a deployment topology means adding adapters and a composition root, not threading flags through application code.
Pick a substrate that exists everywhere. The fewer infrastructure dependencies your product has, the fewer per-deployment ports you need. Postgres is the practical example, because it runs in every environment that matters: managed on every major cloud, embedded in containers on a single VM, clustered on bare metal, on a laptop. If you also use it for queues, search (via full-text indexing), vector search (via pgvector), JSON storage, scheduled jobs, and audit logs, none of those subsystems becomes a separate port that must be re-implemented per deployment. The substrate is the same everywhere.
Keep orchestration inside the substrate, not the cloud. Cloud-proprietary workflow services (AWS Lambda, Step Functions, EventBridge, Azure Functions, Pub/Sub) are deployment lock-in by design. If your durable workflows live in those, they cannot move. Workflow runtimes that store their state in your database, such as DBOS, let the same workflow code run against the same workflow tables wherever the database happens to be. The orchestration is portable because it has no infrastructure of its own.
Treat the model provider as a port. OpenAI, Anthropic, Gemini, Bedrock, Azure OpenAI, Vertex, Ollama, vLLM, and llama.cpp behind an HTTP wrapper all sit behind the same model port. BYO model is then a configuration change, not a code change. The customer points the port at their endpoint and the rest of the product does not notice. The caveat: model behaviour varies. A product tuned against Claude often misbehaves on a 70B Llama. Behavioural compatibility across models is its own work, separate from architectural portability.
Configuration over conditionals. The deployment variant is named once at startup and selects adapters from there. The application code has no if (selfHosted) branches. Adding a new deployment shape means writing new adapters and a new composition, not finding three hundred conditional branches to update.
These choices reward themselves in two stages. The first is operational simplicity for the team building the product, before any customer asks for a different deployment: fewer infrastructure dependencies, one substrate to operate well, no cloud-vendor proprietary surfaces to commit to. The second is the deployment portability itself, when a customer asks. The architecture earns its keep before the requirement appears, which is the only reasonable way to make it happen.
Local-first, sync engines, and what they actually buy
Self-hosted is about the company running the application. Local-first is about the device the user is working on. Both are independent dimensions and they interact in interesting ways for AI products.
The two production shapes
The pure form of local-first uses CRDTs (Automerge, Yjs) to merge concurrent edits with no central authority required. In principle the topology can be peer-to-peer. In practice, almost every shipping local-first product has a central server too: not as the only source of truth in the CRDT sense, but as a coordination point, a backup, an access-control gate, and a way for new devices to bootstrap. Aaron Boodman, a co-founder of Replicache, has put it as “CRDTs converge, but real-world systems need a server to enforce constraints external to the data.”
The more common production model, often described as a sync engine, is server-authoritative with optimistic local writes. The client maintains a local copy, writes happen against it instantly, mutations are pushed to the server, the server applies its own authoritative version, and the client rebases its speculative state on top of the server result. Linear is the canonical example, with Replicache and Convex offering this shape as a product. The Convex team’s piece on object sync engines is a clear write-up. The architectural shift is that the user’s working copy is the source of truth for what they are doing right now, and the server is a coordination and authoritative-merge point rather than the bottleneck on every read.
What it buys an AI product
For AI products, this matters in three places. First, prompts, responses, and the user’s working artefacts can live locally, so re-reading and re-using past work does not require a round-trip. Second, when a small local model is good enough for the operation (extraction, classification, intent recognition, light summarisation), the work can happen on the device with no API call and no data egress. Third, multi-device users (laptop, tablet, phone) get the same state without round-tripping every interaction through your server.
The costs, eyes open
The downsides are real and deserve being eyes-open about.
Eventual consistency is hard to reason about. Two devices that have been editing offline come back online with conflicting changes. CRDTs and sync engines merge automatically, but whether the user understands what was merged is a separate question, and the answers in production are still uneven. Where conflict resolution matters to the user (collaborative editing of a critical document, two people editing a price field), the merge needs UX, not just an algorithm.
Server-side queries become harder. A SaaS app can run any query it wants against the central database. A local-first app can only run queries against whatever the client has synced. Filtering and aggregation that span data not on the device require server-side support, often duplicating logic. Partial sync, where each client gets only the data it needs, is a real architectural problem in itself.
Authorisation gets harder. Permissions enforced server-side are easy. Permissions enforced on data that has already been replicated to a client are not. If a record needs to be visible to a user today and hidden tomorrow, the local-first store has to handle revocation. Most sync engines provide some support; some require you to design around it.
Schema migrations on local stores are painful. The server can migrate its schema in one operation. Clients are on whatever version they last opened the app at, which can be months. Forward-compatibility, backward-compatibility, and version-detection are all the application’s responsibility.
Storage and memory on the device fill up. Even with partial sync, long-tenured users accumulate a working set that grows. Eviction policies, lazy loading, and reload-from-server behaviour are the kind of details that look small in a demo and matter a lot at year two.
Search has to be reimplemented client-side. Postgres full-text search on the server is one thing; building a comparable index inside an IndexedDB store on a laptop is another. Vector search, where it is needed, is harder again.
The shape that usually fits
None of this rules out local-first or sync-engine architectures. It does mean adopting one is a real commitment, not a library choice. The right shape for many AI products is a server-authoritative sync engine with a thoughtful merge UX, partial sync from day one, and a willingness to keep some operations server-only when they cannot be replicated cheaply.
Local models, where they fit
Frontier-quality reasoning is not yet running on a laptop. Llama, Qwen, Mistral, and DeepSeek all ship strong open models that are good and getting better quickly, and Apple has been shipping small on-device models for routine tasks while routing harder queries to its Private Cloud Compute service. For top-tier reasoning, agentic planning, and long-context document work, the hosted frontier models remain ahead by a meaningful margin.
For many narrower tasks, local is already enough. Structured extraction from documents, classification, retrieval reranking, intent recognition, light summarisation, code completion. Continue and the Cursor local-model option both let developers point their tooling at Ollama, vLLM, or LM Studio. For high-volume use cases the cost and latency story favours local for these task types, even before privacy enters the picture.
The customer segments where local models matter today are the ones where the frontier-versus-local gap is smaller than the data-sensitivity cost of using a hosted frontier model. Defence, intelligence, regulated finance, healthcare, legal practice, and certain government work fall here. Enthusiasts and professionals running models on local GPUs are a smaller but growing segment, motivated by cost, customisation, and independence rather than secrecy. For mainstream consumer and business AI products, local-only remains a constraint, not a default.
The gap closes over time. Hardware improves. Quantisation improves. The architectural payoff is having the option to swap in a local model when the moment arrives for a given workload, without rewriting the product around it.
What self-hosted costs the vendor
Self-hosted is not free for the vendor. The trade-offs are worth being explicit about.
Pricing inverts
SaaS pricing is per-seat or metered usage. Self-hosted pricing is annual subscription or perpetual licence plus support. The economics differ: higher contract values, lower volume, longer sales cycles, cash up front, renewals each year. You are now a software company with an enterprise GTM motion rather than a SaaS company with a usage-based one. The organisation you need to build is different.
Support is heavier
The customer is running the software. When something breaks you cannot just look at your dashboard. You need diagnostic bundles (logs, configuration, version manifests), a support escalation process, and a way to ship fixes the customer can deploy. Replicated and similar platforms make the packaging and deployment story tractable (Helm charts, KOTS, embedded clusters, support bundle collection), and they are worth using rather than building. The support engineering work itself is still yours.
Telemetry is restricted
In SaaS you see everything: who used what, how, when, what failed, what was slow. In self-hosted, especially air-gapped, you see little or nothing. The product improvement loop, the reliability monitoring, and the usage analytics all degrade or disappear. Opt-in telemetry, support bundles, and customer-shared metrics help but do not replace the rich SaaS feedback loop.
Updates slow down
SaaS deploys many times a day. Self-hosted customers upgrade on their cadence, which is quarterly at best and annual for many. You support N versions in parallel for some period. Breaking changes need migration paths. Long-lived branches accumulate. The “we’ll fix it in prod tomorrow” reflex no longer applies.
Multi-tenancy is gone
Each customer runs an instance of their own. There is no shared infrastructure, no per-tenant cost amortisation, no centralised pipeline of improvements that benefits everyone at once. The same code runs in twenty environments, each with its own config and its own data, and each can drift from the others.
The tooling has caught up
The enterprise-distribution ecosystem (Replicated, Helm, embedded Kubernetes distributions, plus surfaces like Snowflake Native Apps and Databricks Partner Connect) has made this work less painful than it was a decade ago. The work is real, but the tooling exists.
Where each model fits
Self-hosted is the right answer when several conditions stack. The customer is mid-market or larger, with internal ops capable of running the software. The data is sensitive enough that “inside our perimeter” is non-negotiable. The compliance regime favours data residency, as in regulated finance, healthcare, defence, government, or legal. The customer has a security team, a procurement process, and a budget for enterprise software. And the contract value justifies the GTM machinery, which usually means six figures a year.
Self-hosted is the wrong answer for SMB, for self-serve, for usage-based volume products, and for customers who do not run software themselves. Forcing self-hosted into those segments produces churn and support cost. Forcing SaaS into the regulated-enterprise segment produces stalled deals.
BYO model is lighter weight than full self-hosting and worth offering more broadly. Many customers want SaaS-hosted application code but their own LLM credentials (their Azure OpenAI deployment, their Bedrock account). This is a configuration option, not a deployment-topology change, and it unblocks deals where the only objection was who pays for and sees the inference.
The in-stack approach (custom tools inside Copilot, Gemini for Workspace, ChatGPT Enterprise) works for narrow specialist workloads. It trades brand presence for procurement bypass. For specialist domains where the customer has already standardised on a host platform, this is the cheapest distribution channel available.
Most products end up offering a combination: SaaS for SMB and self-serve, self-hosted (Replicated-packaged) for enterprise, BYO model as a configuration across both, and selective integration into host AI platforms where the specialist workload justifies it. The architectural moves that enable any one of these enable all of them, which is part of why the up-front discipline is worth the effort.
What this means in practice
The cloud-as-friction inversion is not a complete reversal. SaaS is still the right default for most consumer and SMB products. Cloud-hosted AI is still the easiest way to get a product to market and iterate quickly. But for enterprise AI sales in 2026, “SaaS only” is a positioning that costs deals, and the decisions that let one codebase run in many deployment topologies are worth making early.
The good news is that the architectural moves are the same ones a small team should be making anyway for operational simplicity: hexagonal at the boundaries, one substrate operated well rather than ten in shaky shape, orchestration inside that substrate rather than handed off to a cloud vendor, ports for external dependencies with multiple adapters where the deployment varies, configuration over conditionals. None of this is specific to deployment portability when adopted; all of it cashes out as deployment portability when the customer asks.
The harder news is that self-hosted is a different business shape than SaaS. The pricing model is different, the support burden is different, the telemetry surface is degraded, the release cadence slows, and multi-tenancy goes away. Plan for the difference if it matters; do not bolt it on after a single deal demands it. The in-stack approach sidesteps a lot of this at the cost of dependence on the host platform. A faster PLG motion can do useful work in parallel by reaching users the enterprise gauntlet cannot. Any of those is better than the third path, which is finishing a hundred-question questionnaire every quarter to win a deal you might lose anyway because the budget owner decided to consolidate on Copilot.
Disclosure: LLMs have been used in the editing and research of this post.