on
Choosing Serverless (and Knowing When Not To)
Serverless has matured from a novelty into a mainstream backend pattern — but that doesn’t mean it’s the right choice for every service. Recent platform improvements (faster cold starts, database proxies, and even serverless inference at the edge) have extended serverless’ reach, but trade-offs around cost, state, and runtime constraints still matter. This short guide walks through when serverless shines today, where it still struggles, and a practical checklist to help you decide.
What’s changed lately that matters
- Faster cold starts: providers now offer snapshot and warm-start techniques that dramatically reduce first-invocation latency for many runtimes, making synchronous APIs far more viable on functions. (docs.aws.amazon.com)
- Better database support: managed connection proxies let short-lived serverless functions share and pool database connections so you don’t exhaust database resources as your functions scale. That reduces one of the classic “don’t use serverless for DB-backed apps” objections. (docs.aws.amazon.com)
- Edge and serverless GPUs: edge function platforms and newer offerings let you run low-latency logic (and even small-model inference) close to users, with pay-as-you-go pricing and global reach. That pushes serverless beyond simple webhooks and cron jobs into more latency-sensitive, distributed workloads. (cloudflare.com)
Those improvements widen the list of good fit scenarios — but they don’t erase trade-offs. The rest of this article focuses on practical guidance.
When to use serverless
- Bursty, unpredictable traffic: if requests spike and idle time is common, serverless avoids paying for always-on capacity. For many teams this is the single biggest cost advantage. (dev.to)
- Event-driven backends: short-running handlers for pub/sub, webhooks, file processing, and streaming transforms map naturally to function triggers. Serverless simplifies wiring events → code and scales automatically.
- Lightweight APIs and middleware at the edge: authentication, A/B routing, localization, response transforms and caching benefit from running close to the user for lower latency and simpler scaling. Edge serverless is especially useful for per-request logic that needs to run globally. (cloudflare.com)
- Cost-conscious microservices and MVPs: when you want to launch quickly without managing infra, serverless is fast to iterate on and keeps per-request costs low for modest volumes. (taskew.com)
Example: a notification system that receives sporadic spikes during business hours and is idle overnight — serverless reduces cost, simplifies scaling, and maps neatly to event triggers.
When not to use serverless
- Long-running jobs and heavy compute: functions typically have execution-time limits and are not priced for sustained CPU/GPU consumption. For batch jobs, model training, or HPC you’ll usually prefer containers, VMs, or managed GPU clusters. (dev.to)
- Stateful services that need tight consistency or socket-level control: serverless is best for stateless, request-oriented logic. Stateful systems (custom session stores, long-lived TCP sockets, in-memory caches that must persist) are harder to implement and often perform better on dedicated services.
- Predictable, high-throughput production services: if you run a service 24/7 with predictable load, reserved instances or a container cluster often cost less per unit of work and give more predictable latency under sustained load. FinOps comparisons repeatedly show containers winning for steady workloads. (dev.to)
- Database-heavy transactions with many concurrent connections: although proxies reduce connection pressure, complex transactional patterns and long-lived DB sessions can still be an awkward fit. If your architecture depends on many concurrent DB transactions or extensive connection affinity, plan carefully or choose a different platform. (docs.aws.amazon.com)
Practical checklist (5 questions)
Answer these quickly to narrow the choice.
- Are requests short and stateless (sub-second to a few seconds)? If yes, serverless is a strong candidate.
- Is traffic highly variable with long idle periods? If yes, serverless usually reduces cost. (dev.to)
- Do you need GPUs, long-running compute, or fine-grained control of the runtime? If yes, prefer containers or specialized services. (dev.to)
- Does the service require many concurrent DB connections or complex transactions? If yes, investigate database proxies and test at scale — serverless can work but needs careful design. (docs.aws.amazon.com)
- Is global, low-latency execution important (personalization, auth, A/B testing)? If yes, consider edge serverless offerings. (cloudflare.com)
Quick patterns and mitigations
- Reduce cold-start risk: enable provider snapshotting/warm-start features where available, or use a small provisioned concurrency layer for critical endpoints. (docs.aws.amazon.com)
- Handle DB scale: use a managed connection proxy to pool connections and avoid per-invocation connection churn. (docs.aws.amazon.com)
- Split responsibilities: put latency-sensitive, global logic at the edge; keep heavy business logic or stateful operations in containers or dedicated services. (cloudflare.com)
Final thought
Serverless is no longer just for tiny one-off functions — platform improvements make it a practical choice for many production backends. Still, the right decision depends on workload shape: short-lived, stateless, bursty, or event-driven services are ideal; long-running compute, heavy state, and predictable high-volume services usually belong elsewhere. Use the checklist above, validate with a small prototype, and choose the pattern that matches your operational and cost constraints.