Platform as a service is worth paying for when your application is ordinary and your team is small. You hand over the operating system, the runtime, the patching and most of the scaling, and in exchange you accept less control and a billing model that can behave unexpectedly. For a web application with modest traffic, the published figures are genuinely low: Google’s own worked example for a Cloud Run service handling 10 million requests a month comes to USD 13.69, and a Heroku Basic dyno is USD 7.00 a month. The trap is not price. It is the configuration mistake that turns USD 13.69 into USD 81.72 for exactly the same traffic.

What PaaS is, minus the layer diagram
Every explanation of PaaS starts with the same three-column diagram. Here is the version that actually helps when you are choosing: PaaS is the layer where you deploy code rather than servers, and where somebody else decides how the code runs. You bring an application and a configuration file. The platform builds a container or an image, places it somewhere, gives it a URL and a certificate, watches it, restarts it when it dies, and adds more copies when traffic rises.
What you give up is specific and worth naming. You do not choose the kernel. You often cannot hold state on local disk. Long-running background processes and websockets are supported unevenly. Debugging means reading logs rather than attaching to a process. And when the platform makes a decision you disagree with — a build system, a filesystem layout, a restart policy — your options are to work around it or to leave.
For a small business that trade is usually excellent. The hours you do not spend patching operating systems and configuring load balancers are hours you spend on the product. The trade gets worse as your requirements get stranger, which is the whole of the rest of this article.
- Build and release. Source or container in, running revision out, with a rollback that works.
- Routing and certificates. A URL, HTTPS and traffic splitting without you touching a load balancer.
- Scaling. More copies when traffic rises, fewer when it falls, frequently down to zero.
- Health management. Restarting crashed instances and taking unhealthy ones out of rotation.
Three billing models, and why the invoice surprises people
Almost every surprise invoice comes from not knowing which of three models you are on.
Per-instance, per-month. Heroku dynos and Azure App Service plans work this way. You rent a container of a given size and pay whether or not it is busy. Predictable, easy to forecast, and wasteful for anything with quiet periods. Heroku’s Basic dyno is USD 7 a month, which Heroku’s own documentation describes as roughly USD 0.25 a day.
Per-resource-second. Cloud Run bills CPU and memory by the second, rounded up to the nearest 100 milliseconds. Idle capacity costs nothing unless you have asked for warm minimum instances. Cheap for spiky traffic, and genuinely free for low volumes because of the monthly free tier.
Free platform, paid infrastructure. AWS Elastic Beanstalk charges nothing for the orchestration and bills you for the EC2 instances, load balancer and storage it creates. The platform looks free and the bill looks like IaaS, because underneath it is.
| Platform | Billing model | Entry price | Free allowance | Scales to zero |
|---|---|---|---|---|
| Google Cloud Run (request-based) | Per vCPU-second and GiB-second, plus $0.40 per million requests | $0.000024 per vCPU-second | 180,000 vCPU-seconds, 360,000 GiB-seconds and 2 million requests per month | Yes |
| Google Cloud Run (instance-based) | Per vCPU-second and GiB-second for the whole instance lifetime | $0.000018 per vCPU-second | 240,000 vCPU-seconds and 450,000 GiB-seconds per month | No, billed for full lifetime |
| Heroku | Per dyno, per month | $5 Eco plan, $7 Basic dyno | None; Eco gives 1,000 dyno hours for $5 shared across the account | Eco dynos sleep after 30 minutes idle |
| Azure App Service | Per App Service plan instance, per month | F1 Free plan at $0 | F1 Free: 60 CPU minutes per day, 1 GB RAM, 1 GB storage, no SLA | No |
| AWS Elastic Beanstalk | No service charge; you pay for AWS resources | $0 for the platform itself | Covered by the AWS Free Tier limits of the underlying services | No, unless you build it |
One structural point that is easy to miss: on Cloud Run’s request-based model you are charged for CPU while a request is being handled, during startup and during graceful shutdown. On the instance-based model you are charged for the entire lifetime of the container with a one-minute minimum. Same service, materially different bills, and the choice is a configuration flag.

What real workloads actually cost
Vendor rate cards are hard to reason about, so Google publishes worked examples with explicit assumptions. These are their figures, all for europe-west1, and they are the most useful public reference points for what a PaaS workload costs.
Look at the top and bottom of that chart, because the gap is the whole lesson. The same 10 million requests a month at the same 400 millisecond latency on the same 1 vCPU and 512 MiB cost USD 13.69 with 20 concurrent requests per instance and USD 81.72 with one. That is a six-fold difference produced by a single setting, and it is set to one by default in some frameworks and for any code that is not thread-safe.
The scheduled job at USD 0.00 is also instructive. An hourly batch job running one minute, 730 times a month, falls entirely inside Cloud Run’s free tier; Google notes it would be USD 0.45 without it. If you are currently running a small virtual machine purely to execute cron jobs, that machine is the easiest saving on your bill.
The Elastic Beanstalk figure at USD 52.57 is not a criticism of the platform. It is what a conventional always-on deployment with a load balancer costs, and it buys you predictability, long-lived connections and no cold starts. For an internal application used by forty people during office hours, paying USD 52 for something that behaves like a server you understand is a perfectly rational choice.
Nothing on that chart is expensive. The expensive outcome is paying always-on prices for a workload that is idle nineteen hours a day.
Cold starts, concurrency and the 100-millisecond rule
Three technical details decide whether a per-second platform is pleasant or maddening.
Concurrency. How many requests one instance handles at once. High concurrency is how per-second platforms become cheap, because one warm container serves many callers. It requires your code to be thread-safe and to avoid per-request global state. If you cannot guarantee that, set concurrency to one and budget accordingly — Google’s own example shows exactly what that costs.
Cold starts. Scaling to zero means the first request after an idle period waits for a container to start. For an internal tool, nobody notices. For a public checkout page, a two-second first byte is a conversion problem. The fix is a minimum instance count, which is billed at a reduced idle rate on Cloud Run — USD 0.0000025 per vCPU-second — rather than free. Heroku’s Eco dynos have the same characteristic by design: they sleep after 30 minutes without traffic.
Rounding. Cloud Run rounds billable time up to the nearest 100 milliseconds, and instance-based billing has a one-minute minimum. For very short, very frequent invocations the rounding is a real component of the bill, which is why batching small operations often costs less than dispatching them individually.
- Concurrency: as high as your code safely allows, not the framework default.
- Minimum instances: zero for internal tools, one or more for anything customer-facing where first-byte latency matters.
- Request timeout: shorter than you think, so a stuck request cannot bill for minutes.
- Maximum instances: set a ceiling, so a traffic spike or a retry loop cannot scale your bill.
Where PaaS stops being the right answer
PaaS is the wrong answer more often than its marketing admits. The honest list:
- Steady, predictable, round-the-clock load. If a service runs flat out all month, per-second billing offers nothing and reserved virtual machines or committed-use discounts will be cheaper.
- Heavy local state. Anything that wants a large local disk, a persistent in-memory cache or GPU-attached scratch space fights the model. Managed databases and object storage help, but not always enough.
- Long-lived connections at scale. Websockets, streaming and long polling work on modern platforms but the billing and timeout behaviour needs reading carefully before you commit.
- Licensed or legacy software. If the vendor supports a specific operating system and expects a filesystem layout, you need a virtual machine.
- Strict data residency with an unusual region. PaaS services reach fewer regions than raw compute does. Check the region list before the architecture, not after.
A reasonable pattern for a growing company is to keep the web tier on PaaS, move the awkward thing to a virtual machine, and resist the temptation to move everything because one component did not fit. Our guide to infrastructure as a service covers that lower layer, and the division of labour between the two is explained in our guide to software as a service.

Choosing a platform and keeping the exit cheap
Platform choice is less consequential than it feels, provided you keep one discipline: deploy a container you built, from a Dockerfile you own, defined in a repository. Do that and all of these platforms become interchangeable within a week of work. Use a platform’s proprietary buildpack and bespoke configuration format instead, and you have a migration project.
- Containerise, even if the platform does not require it. Your image is the portable artefact. Buildpacks are convenient and specific to one vendor.
- Keep state outside the platform. Managed PostgreSQL or MySQL and object storage exist everywhere. A proprietary data store does not.
- Put configuration in environment variables and secrets. Not in platform-specific YAML scattered across a console.
- Match the billing model to the traffic shape. Spiky or part-time: per-second with scale-to-zero. Steady and continuous: per-instance or reserved compute.
- Set the ceilings on day one. Maximum instances, request timeout and a budget alert. Every runaway PaaS bill we have been asked to explain was missing at least two of the three.
If you want a second pair of eyes on a deployment before it goes live, or an explanation of a bill that stopped making sense, that is the kind of thing our cloud solutions work covers, delivered remotely. For who typically owns this work inside a company, our cloud career guide sets out the roles.
Frequently asked questions
Is PaaS cheaper than running a virtual machine?
For part-time and spiky workloads, usually yes, because you stop paying for idle capacity. Google’s own example shows an hourly one-minute batch job costing nothing inside the Cloud Run free tier. For a service that runs at a steady load twenty-four hours a day, a reserved virtual machine is normally cheaper, and the PaaS advantage becomes operational rather than financial.
What actually causes a surprise PaaS bill?
Four things, in order of frequency: concurrency set to one so every request gets its own instance, no maximum instance ceiling during a traffic spike or retry storm, long request timeouts letting stuck calls bill for minutes, and minimum instances left warm in environments nobody uses. All four are configuration, and all four are fixable in an afternoon.
Do cold starts matter for a small business application?
Usually only on customer-facing paths. For an internal tool, a one or two-second first request after an idle period is invisible. For a public checkout or signup page it is not, and you should keep at least one warm instance. On Cloud Run that idle capacity is billed at a reduced rate rather than free, which is a fair price for predictable latency.
Can we move off a PaaS platform later?
Yes, if you deploy a container image built from your own Dockerfile and keep your data in a managed database and object storage. In that shape, moving between Cloud Run, App Service, Elastic Beanstalk and others is roughly a week. If you used a vendor buildpack, platform-specific add-ons and a proprietary data store, expect a project instead.
Which platform should a small team pick?
Whichever cloud you already use for everything else, because the identity, networking and billing integration is worth more than any feature difference. If you have no existing commitment, Cloud Run’s free tier makes it the cheapest place to start, Azure App Service is the natural fit for teams already in Microsoft 365, and Elastic Beanstalk suits workloads that want to behave like conventional servers.
Want your deployment and its bill reviewed before the traffic arrives? Get in touch with Eudora Technology to talk about your project.
Sources
- Cloud Run pricing: rates, free tier and worked monthly examples
- Eco dyno hours ($5 per month for 1,000 dyno hours)
- Pricing – App Service for Linux (F1 Free plan: 60 CPU minutes per day, 1 GB RAM, 1 GB storage)
- Azure App Service plans overview
- AWS Elastic Beanstalk pricing (no additional charge)
- Host a .NET web application: services and costs ($52.57 per month for the default configuration)
- Flexera finds cloud value is rising while AI waste grows (29% wasted spend)



