🎁 Free starter workshopHaving a SW issue?
Back to blog
TechnologyServerlessCloudArchitectureBackend

Serverless Architecture: When It's Worth It and When It's Not

Lukáš HusoApril 21, 20269 min read
Serverless Architecture: When It's Worth It and When It's Not
Photo: NASA / Unsplash

Serverless has become one of those terms that appears in every other tech presentation and every third article about modern development. Cloud provider marketing departments present it as a revolution that will eliminate all infrastructure problems. The reality is considerably more nuanced. Serverless architecture is a powerful tool, but like every tool, it has its ideal use cases -- and situations where it creates more problems than it solves.

What serverless actually means

The name "serverless" is somewhat misleading -- servers obviously still exist, you just don't manage them. Instead of running your own server (or a virtual machine in the cloud), you write a function, upload it to a provider, and they handle everything else: provisioning, scaling, monitoring, OS updates.

Three major platforms you will encounter most frequently in practice:

AWS Lambda is the pioneer and still the most widely adopted serverless platform. It supports Python, Node.js, Java, Go, and other languages. It integrates with dozens of other AWS services, which is simultaneously an advantage and a disadvantage -- more on that later.

Vercel and Netlify Functions bring serverless closer to frontend developers. If you're building an application in Next.js or a similar framework, serverless functions are a natural part of the deployment. Configuration is minimal and the developer experience is excellent.

Cloudflare Workers offer a unique approach -- functions run on the edge, as close to the end user as possible. This means extremely low latency but also specific limitations (V8 isolates instead of full Node.js, CPU time limits).

Beyond these main players, there are Google Cloud Functions, Azure Functions, and a number of smaller platforms. The principle is the same everywhere: you pay for actual usage, not reserved capacity.

The real cost analysis

The most common argument for serverless is cost. "You only pay for what you actually use." That sounds great, but it requires context.

When serverless genuinely saves money. If you have an API handling 10,000 requests per day with an average execution time of 200 ms, you will pay roughly a few dollars per month on AWS Lambda. An equivalent EC2 instance would cost $15-50, even the smallest one. For sporadic workloads -- applications with significant spikes and long periods of inactivity -- the savings are even more dramatic. An internal tool used only during business hours, or a seasonal e-shop with a Black Friday spike, are ideal candidates.

When serverless surprises you with cost. The problem arises with constant load. If your API handles millions of requests per day evenly across 24 hours, serverless will cost more than a dedicated server or reserved cloud instance. AWS Lambda charges approximately $0.20 per million requests plus compute time. At high, steady load, these micro-payments add up faster than you might expect.

It's important to calculate total costs. The Lambda function itself is cheap, but add API Gateway ($3.50 per million requests), CloudWatch logs, and possibly a NAT Gateway for VPC access ($32 per month just for existing), and the total bill looks entirely different. We have seen projects where the Lambda functions themselves cost $20 per month, but the supporting infrastructure around them cost $200.

The cold start problem

A cold start is the delay on the first invocation of a function when the platform needs to allocate resources and initialize the runtime. For Node.js and Python, we are typically talking about 100-500 ms. For Java or .NET, it can be 1-5 seconds, sometimes more.

For most API endpoints, a 200 ms cold start is acceptable -- the user won't notice it. The problem arises in three scenarios.

First, function chaining. If a single request sequentially triggers three Lambda functions and each has a cold start, the user waits an extra 600 ms. In a microservices architecture with dozens of functions, this adds up quickly.

Second, sporadic traffic. Paradoxically, the very use case where serverless saves the most money suffers from cold starts the most. If a function receives a request once every 15 minutes, almost every request will be a cold start.

Third, real-time applications. Chatbots, live dashboards, or game servers need consistent response times. A cold start that occurs occasionally degrades the user experience more than a consistently 50 ms slower but predictable response.

Solutions exist: provisioned concurrency on AWS (but you pay for reserved capacity, losing the main serverless advantage), warm-up pings (unreliable and impractical), or moving to edge runtimes like Cloudflare Workers where cold starts are under 5 ms.

The vendor lock-in risk

This is a topic that surprisingly doesn't appear in cloud provider marketing materials. When you write a Lambda function that uses DynamoDB for data, SQS for queues, S3 for files, and SNS for notifications, you are not just tied to AWS Lambda. You are tied to the entire AWS ecosystem.

Migrating such an application to Google Cloud or Azure is not rewriting one function. It is rewriting the entire data layer, communication layer, and often authentication too. In practice, this means months of work and the risk of new bugs.

How to minimize lock-in. Separate business logic from infrastructure code. Your domain logic should not know whether it's running on Lambda or a regular Express server. Use the adapter pattern for database access and other services. And when possible, prefer open standards (PostgreSQL over DynamoDB, Redis over ElastiCache).

The reality, though, is that some degree of lock-in is inevitable and often acceptable. If AWS Lambda solves your problem and you have no realistic reason to migrate, optimizing for portability may be an unnecessary investment.

Drawbacks
  • Vendor lock-in to a specific provider
  • Cold starts degrade latency
  • Execution time limits (15 min on Lambda)
  • More expensive under constant high load
  • Debugging and monitoring are more complex
Serverless pros
  • Pay only for actual usage
  • Automatic scaling with zero configuration
  • Rapid deployment and prototyping
  • No server management or OS updates
  • Ideal for event-driven and sporadic workloads

Where serverless truly excels

There are use cases for which serverless is a perfect fit.

Event-driven processing. A user uploads an image, Lambda resizes it and stores thumbnails. An order comes in, a function sends a confirmation email and updates inventory. A webhook from a payment gateway triggers payment processing. These one-off, event-reactive operations are ideal serverless candidates -- short, isolated, and with unpredictable frequency.

APIs for mobile and web applications. A REST or GraphQL API serving CRUD operations is a classic serverless use case. Especially if traffic is irregular (more during peak hours, less at night) and individual endpoints are relatively simple.

Scheduled tasks and cron jobs. Instead of a server that does nothing for 23 hours and 55 minutes a day and runs a data sync once per hour, use a scheduled Lambda function. You only pay for those few seconds of actual execution.

Prototyping and MVPs. When you need to validate an idea quickly, serverless saves you time on infrastructure configuration. Deploy a function, connect a database, and you have a working backend in an afternoon. If the project grows, you can migrate to a more traditional architecture later.

Where serverless is not a good fit

Knowing when not to use serverless is equally important.

Long-running processes. AWS Lambda has a maximum timeout of 15 minutes. Cloudflare Workers have a CPU time limit of 30 seconds (50 ms on the free plan). If you need to process a large dataset, perform complex computation, or maintain long-lived connections (WebSockets), serverless is not the right tool.

Heavy computation. Machine learning inference, video processing, code compilation -- operations that need significant CPU or GPU are expensive and slow on serverless. A dedicated GPU instance on AWS costs a fraction of what you would pay for equivalent compute time on Lambda.

Stateful applications. Serverless functions are stateless. Each invocation starts with a clean slate. If your application needs to maintain state between requests (session data, in-memory cache, persistent connections), you must externalize it to a database or cache service. This adds latency and complexity.

Complex transactional systems. Banking systems, reservation platforms, or any application requiring distributed transactions across multiple services are challenging to implement correctly with serverless. It's not impossible, but orchestration via Step Functions or the Saga pattern adds layers of complexity.

Serverless pays off the most for projects with irregular traffic (internal tools, seasonal e-shops, MVPs) and event-driven processing (webhooks, image resizing, emails). If you have constant 24/7 load, calculate total costs including API Gateway and supporting services -- a traditional server may end up cheaper.

The hybrid approach as a pragmatic solution

In practice, a combination works best. The application core -- the main API with constant traffic -- runs on a traditional server or in a container. Serverless functions then handle peripheral tasks: processing webhooks, generating reports, sending emails, resizing images.

This hybrid approach combines the predictable costs and performance of traditional hosting with the elasticity and simplicity of serverless for tasks where it makes sense. It's not as elegant as "everything is serverless," but it's pragmatic and works reliably in production.

Another option is container-based serverless (AWS Fargate, Google Cloud Run). You get the benefits of the serverless model (pay-per-use, automatic scaling) without the limitations of classic functions (longer execution, full runtime, statefulness). It's a compromise worth considering.

When to stick with traditional hosting

Sometimes the best choice is the simplest one. A VPS at $10-20 per month with Nginx, your application, and a PostgreSQL database is a solution that works for a huge number of projects. It's predictable, easy to debug, has no cold starts, and you're not dependent on a specific cloud provider.

If you have a small team, predictable traffic, and an application that doesn't need to scale to thousands of instances, a classic server or managed hosting is a legitimate and often better choice than serverless.

Conclusion

Serverless architecture is not the future of all backend development. It is a specific tool for specific problems. It excels at event-driven processing, irregular traffic, and rapid prototyping. It falls short for long-running processes, constantly loaded systems, and complex stateful applications.

The decision between serverless and traditional hosting should never be based on what's currently trendy. It should be based on an analysis of your specific project -- your traffic profile, latency requirements, team size, and budget. A well-chosen architecture saves you thousands of dollars per year and dozens of hours of work per month. A poorly chosen one adds problems you didn't have before.

Get your custom price

Our configurator shows you an indicative price for your project in 2 minutes.

Related Articles

API-First Approach: Why Start with the Backend
TechnologyAPIBackend

API-First Approach: Why Start with the Backend

What API-first development means, its benefits, and how it can save time and money. REST vs GraphQL, documentation, and real-world experience.

March 17, 20269 min read
The two biggest challenges of AI development: quality assurance and big-model dependency

The two biggest challenges of AI development: quality assurance and big-model dependency

Code generation is nearly free now — the bottleneck is QA and human judgment. And the second challenge: when production really needs a large LLM, and when deterministic code or a small local model does the job.

July 7, 20267 min read
A Database Full of Surprises: Migration Stories
TechnologyDatabaseMigration

A Database Full of Surprises: Migration Stories

A table with 500 columns, dates as strings in 12 formats, address fields full of phone numbers. Real database migration stories.

March 19, 20267 min read