Choosing between serverless hosting and containers affects more than deployment style. This guide gives you a repeatable way to compare cold starts, scaling, background work, WebSockets, storage, observability, security effort, and total operating cost before you deploy a web app to the cloud.
Overview
Serverless hosting and containers can both support production web applications, but they solve different operational problems. In a serverless model, the platform typically runs application functions or managed services in response to requests and other events. You usually pay for, configure, and monitor usage at the service level rather than managing a continuously running server.
With containers, you package the application and its runtime dependencies into a deployable image. A managed container platform may handle much of the infrastructure, but you still make more decisions about processes, instance size, concurrency, health checks, networking, and deployment behavior.
The best choice is rarely determined by traffic volume alone. A small application with persistent connections or long-running jobs may fit containers better than serverless. A busy but highly variable API may benefit from serverless elasticity. Start with the workload, then test the cost and operational assumptions.
For a broader view of platforms and development workflows, see Best App Development Platforms for Startups. For a narrower comparison of function-based architectures, review Serverless Functions vs Containers.
Decision matrix
| Concern | Serverless hosting | Containers |
|---|---|---|
| Traffic pattern | Strong fit for intermittent, bursty, or event-driven traffic. | Strong fit for steady workloads or services needing predictable capacity. |
| Cold starts | Possible when an execution environment is created or resumed; measure the user-facing path. | Usually fewer request-level cold-start concerns when instances remain available. |
| Scaling | Often handled by the platform, subject to concurrency, quota, and runtime limits. | Configured through instance counts, autoscaling rules, and resource limits. |
| Background jobs | Works well for short, discrete jobs; long or stateful work may need a queue and a separate worker. | Well suited to continuously running workers and custom job processors. |
| WebSockets | May require a specialized managed service or platform-specific design. | Often more straightforward when the container can maintain connections. |
| Persistent storage | Usually externalize state to a database, object store, or cache. | Still generally benefits from external storage, even when the container has a writable filesystem. |
| Observability | Requires request correlation across functions, queues, and managed services. | Offers familiar process-level logs and metrics, but you must monitor instances and capacity. |
| Security responsibility | Less host management, but careful identity, permissions, secrets, and event validation remain essential. | More responsibility for image security, runtime configuration, patching, network boundaries, and access control. |
| Portability | Convenient platform integrations can increase migration work. | Container images can improve portability, although networking and managed-service dependencies still matter. |
How to estimate
Build a simple monthly model using workload units rather than provider-specific prices. This keeps the comparison useful when pricing pages, limits, or product names change.
- Measure demand: estimate requests per month, average and peak requests per second, average response time, payload size, and the percentage of traffic that requires compute.
- Separate workload types: list synchronous HTTP requests, scheduled tasks, queue consumers, file processing, notifications, and WebSocket or streaming connections independently.
- Estimate compute: for serverless, use invocations multiplied by average execution duration and allocated memory or another provider-defined resource unit. For containers, estimate the number of running instances multiplied by requested CPU and memory over the hours they operate.
- Add supporting services: include database operations, cache usage, object storage, outbound data transfer, logs, monitoring, queues, secrets, build pipelines, and any dedicated networking components.
- Model three traffic cases: calculate a low-demand case, an expected case, and a peak or growth case. A design that is inexpensive in the expected case may become difficult to control during a traffic spike.
- Price operations, not only infrastructure: record the engineering time needed for image maintenance, scaling rules, incident response, tracing, performance tuning, and platform-specific workarounds.
A useful comparison formula is:
Total monthly cost = compute + data services + storage + transfer + observability + delivery tooling + operational effort.
Keep infrastructure spend and engineering effort in separate columns first. Combining them into one currency estimate can create false precision, while separating them shows where the real trade-off lies.
Inputs and assumptions
Write down the assumptions before comparing architectures. At minimum, capture these inputs:
- Traffic: monthly requests, peak concurrency, regional distribution, and expected growth.
- Execution: average and tail duration, memory or CPU needs, startup time, and maximum request duration.
- State: database size, read/write ratio, cache requirements, file size, retention period, and backup needs.
- Asynchronous work: job volume, maximum job duration, retry behavior, ordering requirements, and tolerance for duplicate processing.
- Availability: acceptable downtime, recovery objectives, deployment frequency, and rollback method.
- Connectivity: private network access, third-party APIs, WebSockets, streaming, and fixed outbound addresses if required.
- Team capacity: familiarity with containers, infrastructure automation, monitoring, and incident response.
Do not treat a container as automatically stateful or a serverless function as automatically stateless. These are implementation choices. In either model, durable business data should normally live in a database or object store designed for persistence, while temporary local state should be treated as disposable unless the platform explicitly guarantees otherwise.
Set performance limits before selecting a platform. A web app performance budget can define acceptable API latency and bundle size, while the cloud app capacity planning worksheet can organize demand and scaling assumptions.
Worked examples
Example 1: A low-traffic customer portal
Assume a portal receives occasional daytime requests, has predictable API operations, stores data in a managed database, and performs short notification jobs. The application does not maintain long-lived connections, and traffic varies substantially by day.
For this workload, serverless hosting may reduce the need to keep idle application instances running. The estimate should include function execution, database activity, logs, outbound transfer, and scheduled or queued jobs. The main technical checks are startup latency on less frequent routes, concurrency limits, database connection handling, and the behavior of retries.
A container can still be the better choice if the application uses a framework that is difficult to split into functions, requires a stable process, or needs predictable latency that is not worth optimizing around startup behavior. Compare both designs using the same database and observability assumptions rather than comparing compute lines alone.
Example 2: A continuously active collaboration service
Assume a collaboration service maintains many long-lived connections, processes events through workers, and needs custom libraries with substantial runtime dependencies. Traffic is steady during business hours, with occasional bursts.
A container-based deployment may provide a simpler operating model for the web process and workers. Estimate the baseline number of instances, resources per instance, autoscaling headroom, connection limits, queue capacity, and monitoring. Add the cost of image builds, security scanning, patching, and capacity reviews.
Serverless components could still handle selected tasks, such as image processing or scheduled notifications. A hybrid architecture is valid when the boundary is clear and the team can observe failures across both environments.
Example 3: A growing API with uncertain demand
When demand is difficult to predict, begin with a small service boundary and explicit metrics. Track request duration, concurrency, error rate, queue depth, database connections, and cost per meaningful business operation. Use load tests that reflect realistic payloads and authentication flows; the API testing checklist can help structure this work.
Choose the architecture that meets the performance budget with the fewest hidden assumptions. Avoid selecting serverless solely because it scales, or containers solely because they appear portable. Scaling without database capacity, queue controls, or rate limits can still create an outage or an unexpectedly large bill.
When to recalculate
Revisit the comparison before launch, after a meaningful release, and whenever the workload or platform changes. At minimum, recalculate when:
- Monthly requests, peak concurrency, or average execution time changes materially.
- A new background job, file-processing path, WebSocket feature, or streaming endpoint is introduced.
- Database reads, writes, connection counts, or storage retention increase.
- A provider changes pricing, quotas, supported runtimes, regional availability, or deployment terminology.
- Observed logs, traces, or transfer volumes differ from the original estimate.
- The team changes its availability target, release frequency, or on-call capacity.
- Costs rise faster than usage or a platform-specific limit begins shaping application design.
Keep the original assumptions beside the measured results. Review the difference, identify the variable that moved, and update the estimate rather than replacing it with a new unexplained number. If migration becomes necessary, separate the application from its state: externalize files and data, define an interface for queues and storage, containerize a stable build where practical, and move one route or worker at a time. Use a tested rollback plan; the cloud app rollback runbook provides a useful checklist for release recovery.
Finally, document why the current architecture was chosen, which limits matter, and which signals trigger a review. That record turns a hosting decision into a maintainable operating process rather than a one-time guess.