Serverless computing was supposed to make infrastructure disappear. Yet in a widely referenced industry survey, a large share of organizations running serverless workloads named cold start latency, monitoring gaps, and security concerns among their top operational headaches. The promise is real, but so is the friction. Function as a Service (FaaS) platforms such as AWS Lambda, Azure Functions, and Google Cloud Functions hide servers from view, not from consequence. Below is a practical, field-tested look at the problems teams actually hit, why they happen, and what genuinely helps.
Cold Starts: The Latency Tax Nobody Budgets For
A cold start happens when the platform must spin up a fresh execution environment before your code runs: loading the runtime, resolving dependencies, initializing the handler. Warm invocations skip this, which is why a function can feel instantaneous in testing and sluggish in production.
The practical mistake is benchmarking only warm paths. A function that responds in 40 milliseconds when warm may take several hundred milliseconds or more on a cold start, and the penalty compounds in chained or user-facing flows. The fix is rarely one thing:
- Keep deployment packages lean. Every megabyte of dependencies adds initialization time.
- Initialize SDK clients and database connections outside the handler so they are reused across invocations.
- Use provisioned or minimum-instance settings where the provider offers them, accepting the added cost.
- Route latency-sensitive traffic to always-warm paths and let background jobs absorb cold starts.
Teams that skip this analysis often discover the problem only after a traffic spike, when scaling creates a burst of new environments all paying the initialization cost at once.
Execution Time Limits and the Long-Running Job Trap

Every FaaS platform caps how long a single invocation may run. AWS Lambda, for example, enforces a 15-minute maximum per invocation, a ceiling it raised from 5 minutes back in 2018. Other providers set their own limits, and they change over time.
The common error is treating FaaS as a general-purpose compute layer. Long batch jobs, video transcoding, and multi-step data pipelines frequently exceed the cap or sit uncomfortably close to it. When they do, work is terminated mid-flight, and partial writes can corrupt downstream state.
What works in practice is decomposition: break long tasks into smaller steps coordinated by a queue or an orchestration service, and make each step idempotent so a retry is harmless. If a workload genuinely needs hours of uninterrupted compute, containers or virtual machines are usually the honest answer, not a function stretched to its limit.
Statelessness Forces Awkward Architecture
FaaS functions are stateless by design. Anything that must persist has to live elsewhere: a database, an object store, a cache. That is a sound principle, but it pushes complexity into the architecture.
Each external call adds latency and a new failure mode. A single user request may fan out into a dozen function invocations, each opening its own connection to a database that was never sized for hundreds of short-lived clients. Connection exhaustion is a classic symptom, and teams often misdiagnose it as a database problem rather than an architectural one.
Practical mitigations include connection pooling through a proxy layer, caching aggressively at the edge, and consolidating chatty call chains into fewer, coarser functions. The lesson: statelessness is a constraint to design around, not a free lunch.
Vendor Lock-In Creeps In Through the Edges
The function code itself is often portable. The surroundings are not. Event source mappings, identity and permission models, proprietary queues, and deployment tooling are all provider-specific, and they are exactly where the real integration work lives.
A team that builds deeply on one provider’s event triggers and managed services may find migration costs far higher than expected. The balanced view is that lock-in is a trade-off, not a sin: accepting some of it in exchange for velocity is often rational. What matters is making the decision consciously. Keeping business logic in plain, portable handlers and confining provider-specific glue to thin adapters preserves most of the exit option at modest cost.
Local Testing and Debugging Remain Painful
Emulating cloud event sources, IAM policies, and network conditions on a laptop is hard. Emulators exist, but they drift from production behavior, and “works locally” is a weak guarantee.
The mistake engineers make most often is skipping integration tests against a real cloud environment until late in development. A better pattern is a small, stable staging environment where functions run against real event sources with realistic permissions, plus contract tests that pin down expected inputs and outputs. Debugging also improves dramatically when structured logging is treated as a first-class requirement rather than an afterthought.
Cost Surprises at Scale
Per-invocation and per-gigabyte-second billing looks trivial in a demo and can look alarming in production. Chatty architectures, retries, and background polling all multiply invocations. A function that runs every second to check a queue generates 86,400 invocations per day before doing any useful work.
Cost modeling deserves the same rigor as performance testing. Instrument invocation counts per feature, watch for retry storms, and prefer event-driven triggers over polling. It is also worth revisiting memory settings: on some platforms, more memory means proportionally more CPU, which can lower total cost by finishing work faster. The counterintuitive cases are exactly why measurement beats intuition.
Concurrency Quotas and Throttling Under Burst Load
Providers impose concurrency limits per account and region. When traffic spikes, new invocations can be throttled, and depending on the event source, those events may be retried or dropped.
Teams commonly assume scaling is infinite until the first launch-day surge proves otherwise. The practical steps are to request quota increases ahead of known peaks, load-test against realistic burst patterns, and design consumers to handle throttling gracefully with backoff and dead-letter queues. If a workload has hard burst requirements, a reserved concurrency allocation or a hybrid architecture may be necessary. For broader reliability work on Windows endpoints, some teams even consult guides like how to fix antimalware service executable high cpu usage when local tooling misbehaves during heavy test runs.
Security and Least-Privilege Complexity
Many small functions, each with its own identity and permissions, expand the attack surface in ways that are easy to overlook. Overly broad roles are the norm in practice because tightening them takes time.
The OWASP Serverless Top 10 catalogued these risks as early as 2018, and the core issues have not vanished: function event injection, broken authentication, and excessive privileges. Defensive habits that actually help include granting each function only the permissions it needs, validating all event payloads as untrusted input, scanning dependencies for vulnerabilities, and rotating secrets through a managed secrets store rather than environment variables in plaintext.
Observability Gaps Across Distributed Functions
Debugging a monolith means reading one log stream. Debugging a serverless system means correlating dozens of short-lived invocations across services. Traditional monitoring tools were not built for this shape of traffic.
The recurring failure is treating logs as sufficient. They are not. Distributed tracing, with correlation IDs propagated through every call, is what turns a pile of logs into a story. OpenTelemetry adoption since roughly 2019 has made vendor-neutral instrumentation far more practical, and teams that invest early spend noticeably less time in incident triage.
Resource Limits You Cannot Argue With
Memory ceilings, payload size caps, and limited ephemeral storage constrain what a single function can do. Large file uploads, big message payloads, and in-memory data processing all hit walls.
The standard workaround is to pass references rather than payloads: write large objects to storage and hand the function a pointer. That pattern is well established, but it adds a round trip and a cleanup responsibility. Resource limits are rarely the first problem a team hits, yet they tend to surface at the worst possible moment, usually during a migration.
When FaaS Is the Wrong Tool
Not every workload belongs in a function. The table below summarizes where FaaS fits and where it fights back.
| Workload characteristic | FaaS fit | Better alternative |
|---|---|---|
| Short, event-driven tasks | Strong | — |
| Spiky, unpredictable traffic | Strong | — |
| Long-running batch jobs | Weak | Containers or VMs |
| Steady high-volume compute | Weak | Reserved instances |
| Latency-critical, always-warm APIs | Conditional | Containers with min instances |
| Complex stateful workflows | Weak | Orchestrated services |
The honest conclusion is that FaaS excels at glue: event handling, lightweight APIs, scheduled jobs, and image or file processing triggered by storage events. It struggles when asked to be a general-purpose runtime. Teams that map workloads to that reality early avoid most of the pain catalogued above. Even adjacent operational choices, from picking a best vpn service for secure remote access to evaluating vendor tooling for a Kia auto dealer near me style local search, benefit from the same discipline: match the tool to the job instead of forcing a fit.
Conclusion
Function as a Service problems are rarely mysterious once named. Cold starts, execution caps, statelessness, lock-in, testing friction, cost drift, concurrency quotas, security sprawl, observability gaps, and resource limits are all well documented. What separates teams that thrive on serverless from those that regret it is not luck but deliberate workload selection and instrumentation from day one. Treat FaaS as a sharp, specialized tool. Measure before you migrate, decompose before you hit limits, and trace everything. Do that, and the servers really do disappear, at least from view.
Frequently Asked Questions
What is the biggest problem with Function as a Service?
Cold start latency is the most frequently cited drawback, because it directly affects user experience and is hard to eliminate entirely. Cost unpredictability and observability gaps are close behind in most practitioner surveys.
Are cold starts avoidable in serverless functions?
Not fully, but they can be minimized. Lean packages, initialization outside the handler, and provisioned concurrency settings reduce their frequency and impact. Some residual cold-start risk is inherent to the model.
Why do serverless functions have execution time limits?
Platforms cap invocation duration to protect shared infrastructure and keep billing predictable. AWS Lambda’s 15-minute limit is the best-known example. Workloads needing longer runs should be split into steps or moved to containers.
Is vendor lock-in a real risk with FaaS?
Yes, though mostly through surrounding services rather than the function code itself. Event sources, identity models, and deployment tooling are provider-specific. Keeping business logic portable and isolating provider glue limits the damage.
How do teams keep serverless costs under control?
They instrument invocation counts per feature, eliminate polling in favor of event triggers, watch for retry storms, and tune memory settings based on measured cost per execution rather than guesswork.
When should a team avoid FaaS entirely?
When workloads run long, need steady high throughput, require always-warm low latency, or carry complex state. In those cases containers, virtual machines, or orchestrated services are usually cheaper and simpler to operate.
The final piece of discipline is organizational rather than technical: ownership. In a monolith, a team owns a service and its runtime. In serverless, ownership fragments across functions, event sources, and the infrastructure-as-code that binds them. Without clear boundaries, nobody feels responsible for the retry policy on a queue or the dead-letter queue nobody monitors. Assigning each function to a owning team, documenting its triggers and downstream dependencies, and reviewing those mappings during incident retrospectives keeps the architecture legible as it grows. Combined with the practices above, this turns serverless from a source of surprises into a predictable, well-understood part of the stack.


