Infrastructure has traditionally forced founders to spend money before they have learned whether anyone wants their product.
You provision a server, configure a database, pay for object storage, wire up a content delivery network, add monitoring, and start receiving monthly invoices while the application still has three test users. None of those individual costs may be enormous, but together they create an infrastructure tax on experimentation.
For an independent developer or a small team, Cloudflare offers a compelling alternative: build nearly the entire first version of a SaaS application on one serverless platform, begin on its free tiers, and let actual usage trigger the hosting bill.
For the right product, your domain name can be the only infrastructure cost between the initial idea and the first paying customer.
That is a powerful proposition. It is also easy to oversimplify.
Cloudflare’s free tier is not an infinitely scalable production environment. Workers are not traditional servers. KV is not a relational database. A globally distributed application is not automatically a globally consistent one. Building successfully on this platform requires understanding what each service is designed to do, where the free limits are, and what will need to change as the product gains users.
This is not a promise that every SaaS belongs on Cloudflare. It is a practical guide to deciding whether yours does, designing the first architecture, and reaching the point where paying for infrastructure is a good problem to have.
What “Fully Hosted on Cloudflare” Actually Means
Cloudflare is often described as a DNS provider, CDN, or DDoS protection service. It is all of those things, but its developer platform can also supply most of the infrastructure behind a modern web application.
A small SaaS can use Cloudflare for:
| Application need | Cloudflare service | What it is good at |
|---|---|---|
| DNS, TLS, and edge caching | Cloudflare DNS and CDN | Routing a custom domain, issuing certificates, caching content, and protecting the application edge |
| Frontend and API hosting | Workers with Static Assets | Serving HTML, CSS, JavaScript, and API routes from one deployment |
| Relational application data | D1 | Users, accounts, permissions, plans, and other structured SQL data |
| Fast key-value lookups | Workers KV | Read-heavy configuration, cached results, and small values that can tolerate eventual consistency |
| Files and uploads | R2 | Images, documents, exports, backups, and other unstructured objects |
| Coordinated or real-time state | Durable Objects | Strongly consistent state, WebSockets, collaboration, rooms, and per-tenant coordination |
| Background work | Queues, Workflows, and Cron Triggers | Deferring work, processing jobs, and running scheduled tasks |
| Bot protection | Turnstile | Protecting signup, login, and public forms without a traditional CAPTCHA |
| Logs and metrics | Workers Logs and platform analytics | Inspecting requests, failures, CPU use, and service consumption |
These products share an account, deployment model, command-line tool, and binding system. A Worker can access D1, KV, R2, Queues, and Durable Objects without exposing each service through a public database connection. That reduces both configuration and the number of credentials moving around an application.
It also keeps the operational surface area small. DNS, certificates, deployments, storage, logs, and usage are visible in one place. For a solo developer who is also acting as product manager, support team, security reviewer, and salesperson, that consolidation has real value.
Burnvelope as a Small, Real Example
Burnvelope is my one-time secret-sharing application. A user enters sensitive information, the browser encrypts it, and the recipient receives a link that can reveal the secret once. The decryption key stays in the URL fragment, which browsers do not send to the server, so the server stores ciphertext rather than the readable secret.
The application is fully hosted on Cloudflare’s free tier:
- Pages serves the frontend.
- Workers runs the API.
- KV stores the encrypted, expiring payloads.
Burnvelope was built before Cloudflare made Workers Static Assets the recommendation for new projects. Pages continues to work, but a new application can now deploy its frontend assets and API Worker together.
Burnvelope is a particularly good fit for this architecture. Its server-side work is small, requests are short, payloads are limited, and it does not need a large relational data model. It benefits from a globally distributed API without requiring a fleet of servers.
The important lesson is not that every product should copy Burnvelope’s exact service choices. It is that a real, public application can have a custom domain, frontend, API, storage, TLS, and global delivery without a recurring hosting bill. The architecture stays small because the product’s requirements stay small.
That last sentence matters. The goal is not to use every Cloudflare product. The goal is to choose the fewest primitives that correctly support the product.
A Sensible Starter Architecture
For many SaaS applications, the first architecture can be represented like this:
Browser
|
Cloudflare DNS, TLS, CDN, and Turnstile
|
Worker
|-- Static Assets: frontend application
|-- API routes: validation, authorization, business logic
|
|-- D1: users, organizations, permissions, product records
|-- KV: configuration and read-heavy cached values
|-- R2: uploads, images, documents, and generated files
|-- Queue: email jobs, webhooks, and deferred processing
`-- Durable Object: real-time or strongly coordinated state, if needed
This is intentionally a monolithic starting point. One Worker can serve the application and its API. One D1 database can hold the structured data. One R2 bucket can hold files. You do not need a collection of microservices merely because the platform makes them easy to create.
Start with a modular application, not distributed infrastructure. Split services only when independent scaling, isolation, ownership, or security requirements justify the added complexity.
Step 1: Decide Whether the Workload Fits
Cloudflare is strongest when an application is request-driven and can perform its server work in short, stateless executions. It is a natural fit for:
- dashboards and customer portals
- CRUD-style business applications
- API products
- forms and workflow tools
- content and membership products
- file-processing workflows that can be divided into queued steps
- real-time applications designed around Durable Objects
- static or client-rendered frontends with serverless API routes
It is a weaker fit for applications that assume a permanently running process, rely on operating-system access, perform heavy CPU-bound work during an HTTP request, or require a database feature set far beyond SQLite. Cloudflare has expanded its Node.js compatibility and offers containers for other workloads, but those options should be evaluated deliberately rather than assumed to behave like a traditional virtual machine.
Before writing code, list the application’s hard requirements:
- What data must be relational?
- What operations require immediate consistency?
- Will users upload files?
- Does anything need to run after an HTTP response finishes?
- Does the application need live connections or coordination among users?
- Which external services are unavoidable, such as payment processing or transactional email?
- What compliance, residency, retention, or backup requirements apply?
Those answers determine the architecture more reliably than starting from a list of available products.
Step 2: Start with One Worker and Static Assets
For a new project, Cloudflare recommends Workers Static Assets for static sites, single-page applications, and full-stack applications. The frontend build and Worker code can be deployed together, with static requests served as assets and API requests handled by the Worker.
Cloudflare’s project generator can scaffold a supported framework and its deployment configuration:
npm create cloudflare@latest -- my-saas
The generated Wrangler configuration becomes the description of the deployed application. It defines the Worker, compatibility settings, static asset directory, service bindings, environments, and required secret names.
Keep the public API narrow. A typical request should follow a predictable sequence:
- Route the request.
- Authenticate the caller.
- Validate the input.
- Authorize access to the requested tenant or record.
- Read or update the appropriate storage service.
- Return a small response.
- Send non-critical follow-up work to a queue.
That pattern aligns well with Workers and makes local testing much easier.
Step 3: Match Data to the Correct Storage Service
Cloudflare does not have one generic storage product because different data has different consistency, query, and access requirements.
Use D1 for relational product data
D1 is Cloudflare’s serverless SQL database built on SQLite. It is the natural starting point for accounts, organizations, memberships, roles, subscriptions, projects, and other records with relationships.
The free tier is large enough for a meaningful early application, but D1 meters rows read and written rather than simply counting SQL queries. An unindexed query that scans 50,000 rows consumes more of the allowance than an indexed lookup that reads a handful. Good schema design is therefore both a performance decision and a cost decision.
D1 also deserves a precise description when discussing global performance. Workers execute near users, but a D1 database still has a primary location for writes. Global read replication can place read replicas closer to users, and the Sessions API provides sequential consistency, but read replicas are asynchronous. “Runs at the edge” does not remove the need to reason about read-after-write behavior.
Use KV for read-heavy values that tolerate delay
Workers KV is a globally distributed key-value store optimized for high-volume reads. It is useful for configuration, allowlists, cached responses, feature data, and small values read much more often than they are changed.
KV is eventually consistent. A write or deletion can take 60 seconds or longer to become visible in another location. That makes KV the wrong place for balances, inventory, permission changes that must apply immediately, distributed locks, or any workflow that requires an atomic read-modify-write cycle.
Do not choose KV because its API looks simple. Choose it because the data’s consistency requirements match the service.
Use R2 for files and large objects
R2 is S3-compatible object storage for user uploads, generated reports, images, audio, backups, and other blobs. Its most attractive pricing characteristic is the absence of egress charges when data is served directly from R2, including through the Workers API.
Store file metadata, ownership, and access rules in D1. Store the file itself in R2. The Worker should authorize the request before returning or signing access to a private object.
Use Durable Objects when one authority must coordinate state
Durable Objects combine compute and strongly consistent storage around a uniquely addressable object. They are useful for collaborative sessions, chat rooms, multiplayer state, rate-limit counters, alarms, WebSockets, and workflows in which multiple requests must coordinate through one authority.
They are now available on the Workers Free plan with the SQLite storage backend. They are powerful, but they introduce a different programming and billing model. Do not add them to an ordinary CRUD application unless the application actually needs coordination or real-time state.
Step 4: Move Slow and Failure-Prone Work Off the Request
A user should not wait for an email provider, webhook destination, image pipeline, or third-party API if the action can safely happen after the primary transaction succeeds.
Use a Queue for work such as:
- sending transactional email
- delivering webhooks
- creating thumbnails or exports
- synchronizing with another service
- processing analytics events
- retrying a temporary external failure
The request can validate the operation, commit the application’s state, place a message on the queue, and respond. A consumer processes the message separately and can retry failures without asking the user to submit the action again.
Scheduled maintenance, cleanup, and reporting can begin with Cron Triggers. Longer multi-step processes may fit Workflows. Keep these jobs idempotent: processing the same message twice should not charge a customer twice, create duplicate records, or corrupt state.
Step 5: Treat Security as Application Work
Cloudflare supplies TLS, network-level DDoS protection, and useful edge controls. That does not secure the application logic automatically.
An early SaaS still needs:
- server-side authentication and authorization
- tenant isolation on every data access
- input validation
- rate limits for expensive or sensitive operations
- CSRF protection where the authentication model requires it
- secure session and cookie settings
- secrets stored through Worker secrets, not in source control or ordinary variables
- audit records for important account and permission changes
- backups and a tested recovery process
Turnstile is a valuable addition to signup, login, password reset, and public forms. Its free plan supports most production applications and does not require visitors to solve a traditional CAPTCHA. The token must still be validated on the server; rendering the client widget alone provides no protection.
Consolidation also creates a larger account-level blast radius. Protect the Cloudflare account with strong multi-factor authentication, use scoped API tokens for deployment, separate production from development, and limit which credentials can modify DNS or production data.
Step 6: Automate Deployment Early
A solo project still deserves repeatable releases.
At minimum, create separate local, preview, and production configurations. Keep schema migrations in source control. Run type checks and tests before deployment. Apply D1 migrations deliberately. Deploy with a scoped Cloudflare token, and use versioned deployments or gradual rollouts when a change carries meaningful risk.
The platform makes deployment easy, which is good. It also makes it easy to deploy a breaking database or API change quickly. Convenience is not a substitute for a release process.
How Much Can the Free Tier Actually Handle?
The answer depends on behavior, not registered users. One active user can generate more load than a thousand dormant accounts.
As of July 2026, some of the limits most relevant to a small SaaS include:
| Service | Selected free allowance |
|---|---|
| Workers | 100,000 dynamic requests per day, 10 ms CPU time per HTTP request, and 128 MB memory per isolate |
| Static Assets | Free and unlimited asset requests |
| D1 | 5 million rows read and 100,000 rows written per day, with 5 GB total storage |
| Workers KV | 100,000 key reads and 1,000 writes per day, with 1 GB stored data |
| R2 | 10 GB-month of Standard storage, 1 million Class A operations, and 10 million Class B operations per month, with free egress |
| Queues | 10,000 operations per day with 24-hour message retention |
| Durable Objects | 100,000 requests and 13,000 GB-seconds per day on the Free plan, using SQLite-backed storage |
These are selected limits, not a substitute for the current Workers pricing and product-specific documentation. Cloudflare changes its platform over time, and several services have additional limits on item size, subrequests, operations, and retention.
The practical takeaway is more important than any single number: the free tier is capable of supporting development, private testing, a public launch, and real early users for a modest application. It is not designed to support unlimited growth at zero cost.
It is also a hard ceiling in important places. Exceeding a free daily allowance can cause operations to fail rather than seamlessly creating a bill. A product should upgrade before its reliability depends on never having a traffic spike.
Upgrade Because Reliability Requires It, Not Because a Counter Exists
The Workers Paid plan currently starts with a $5 monthly account charge and includes substantially more usage before metered charges apply. That is a remarkably small infrastructure bill for a product with customers.
Do not define the upgrade moment as “when Cloudflare rejects a request.” Define operational triggers in advance:
- sustained use reaches a meaningful percentage of a daily limit
- launch traffic or customer activity can plausibly create a spike
- the product now has a paid reliability commitment
- requests need more CPU time than the free plan permits
- log retention and production support needs have grown
- a required capability is available only on a paid plan
Set usage alerts and review Workers requests, CPU time, D1 rows, KV operations, queue depth, R2 storage, and error rates regularly. Usage-based platforms remain inexpensive when developers understand what the application consumes. They become surprising when nobody looks until the invoice or outage arrives.
Once customers are paying, a $5 platform minimum is not a failure of the original plan. It is evidence that the plan worked. Infrastructure cost appeared after revenue instead of before validation.
The Real Advantages for an Indie Developer
Minimal upfront cost
The obvious advantage is financial. A developer can register a domain, build the product, deploy it publicly, and begin acquiring users without maintaining an idle server and database subscription.
That does not mean the entire business costs nothing. Payment processing, email, observability, support tools, legal work, and the developer’s time still exist. But the core hosting bill can remain at zero while the product is proving itself.
Very little infrastructure to maintain
There is no operating system to patch, server to resize, or cluster to keep alive. Cloudflare provisions capacity as requests arrive and distributes the application across its network.
For a small team, removing that work can matter more than the dollar savings. Time spent maintaining commodity infrastructure is time not spent talking to users or improving the product.
One operational control plane
DNS, certificates, caching, deployment, compute, storage, bot protection, and logs live within the same ecosystem. Service bindings reduce public connection strings and make the relationship between compute and data explicit.
A smooth cost curve for many web applications
Static traffic is inexpensive. Dynamic requests are metered in large units. R2 does not charge for egress. A well-designed application can grow considerably before infrastructure becomes a dominant expense.
Global delivery by default
Workers and static assets run across Cloudflare’s network without the developer designing a multi-region compute deployment. That is an extraordinary baseline for a one-person product.
Just remember that global compute and global data are separate concerns. The storage service and consistency model still determine what a user experiences.
The Tradeoffs You Should Accept Deliberately
The runtime is different
Workers support web-standard APIs and increasing Node.js compatibility, but they are not conventional long-lived Node servers. A library that expects local disk, native binaries, unrestricted sockets, or a permanent process may not fit.
Test important dependencies in the Worker runtime early. Do not discover a fundamental incompatibility after building the entire application around it.
The free tier can fail closed
Free limits are useful precisely because they prevent an unexpected bill, but that protection can become downtime. Capacity planning still exists; it simply looks like quota and operation planning instead of server sizing.
Product boundaries can become architecture boundaries
Cloudflare bindings are convenient and proprietary. D1, KV, and Durable Objects encourage designs that are closely tied to the platform.
That is not automatically bad. Every useful managed service creates some degree of lock-in. The right response is to isolate storage access behind application modules, keep business rules out of service adapters, use standard SQL where practical, and maintain export and backup paths for important data. R2’s S3-compatible API also gives object storage a familiar migration surface.
Do not add abstraction layers so elaborate that they slow down a product with no customers. Add enough separation that a service can be replaced without rewriting the business model.
Serverless does not eliminate operations
You still own migrations, backups, monitoring, security, abuse handling, data retention, incident response, and customer communication. The provider runs the infrastructure. You run the product.
Some SaaS needs remain external
Most products will still use outside services for payment processing, transactional email, customer identity, analytics, or support. “Fully hosted on Cloudflare” should describe the core application infrastructure, not pretend that a SaaS business has no dependencies.
Compliance may decide the architecture
Data location, deletion, auditability, regulated information, contractual requirements, and customer security reviews can all outweigh convenience or price. Confirm those constraints before committing sensitive production data to any platform.
An Interesting Shortcut: ChatGPT Sites
There is now another way to begin experimenting with this model.
ChatGPT Sites is in public beta and can create, host, refine, and share websites and lightweight applications without a separate deployment workflow. It supports persistent structured data through D1 and file storage through R2, and a local Sites project records those bindings in .openai/hosting.json.
That makes Sites particularly interesting for rapid product development. A developer can describe an internal tool or early application, iterate with ChatGPT, add persistent data, and publish a working version before manually provisioning a Cloudflare project. Custom domains are available where supported.
The infrastructure is clearly Cloudflare-shaped: D1 and R2 are Cloudflare services, and OpenAI lists Cloudflare among its web-hosting subprocessors. That can reduce the conceptual distance between a Sites prototype and a direct Cloudflare deployment.
It should not be presented as a portability guarantee.
OpenAI’s documentation says that Sites supports a defined runtime and that some frameworks, private networks, databases, background services, and hosting patterns may not be supported. During the beta, account limits can also prevent a high-usage Site from remaining public. Sites currently must not process payment-card data or enable financial transactions.
I would treat Sites as an incubation environment:
- Build the product interaction quickly.
- Test it with internal or early users.
- Refine the data model and workflow.
- Keep the source in a form that can be reviewed and tested locally.
- Move to a directly managed Cloudflare deployment when the product needs unsupported services, independent billing, stricter operations, or production guarantees.
Using D1 and R2 in both environments can reduce migration friction, but the direct deployment still deserves its own compatibility tests, configuration review, security review, load test, and data migration plan.
That is still a major advantage. Early in a product’s life, removing infrastructure setup from the iteration loop can help a developer learn faster. Just keep the boundary between a convenient beta hosting environment and production architecture clear.
A Practical Launch Checklist
Before inviting the first real customers, I would want to answer yes to all of these:
- The product’s runtime and dependencies have been tested on Workers.
- Every data type is stored in a service with the correct consistency model.
- Authentication and tenant authorization are enforced on the server.
- Production secrets are not committed to the repository.
- D1 queries use appropriate indexes and usage has been measured.
- Slow or retryable external work runs through a queue.
- Signup and other abuse-prone endpoints have rate limits or Turnstile protection.
- Development and production resources are separated.
- Database migrations and deployments are repeatable.
- Important data has a backup and recovery plan.
- Logs and alerts expose errors before users report them.
- Free-tier usage has an upgrade threshold, not just a maximum.
- External providers for email, payments, and identity have been included in the cost model.
If those answers are yes, the application is not merely a free-tier experiment. It is the beginning of an operable product.
Start Small, but Build Honestly
Cloudflare gives independent developers something that was difficult to imagine not long ago: a credible path from local code to a globally delivered SaaS product without provisioning servers or accepting a recurring infrastructure bill on day one.
That changes the economics of experimentation.
You can spend less money before validation. You can manage fewer systems. You can deploy faster. You can serve real users. In the right application, you can reach the first paying customer while the domain remains the only direct infrastructure expense.
But the free tier is not the strategy by itself.
The strategy is to build an architecture whose costs follow customer value. Use the free tier while the product is small. Measure it honestly. Upgrade before limits become outages. Pay for infrastructure gladly when customers are paying for the product.
For an indie developer or small business, that is the real promise of Cloudflare: not free hosting forever, but the ability to prove an idea before infrastructure gets a vote.
Building a product and deciding whether a Cloudflare-first architecture fits? Get in touch. I help founders and small teams make practical architecture decisions that support both a fast launch and responsible growth.