Cloud Compute Options and Trade-offs Questions
Choosing among compute abstractions independent of provider: virtual machines, containers, managed container services, serverless functions, and bare metal. Covers the cost, control, cold-start, scaling, and operational trade-offs of each model; how to pick an instance family or hardware accelerator (general-purpose, compute-optimized, memory-optimized, GPU, TPU) and a purchasing model (on-demand, reserved, spot); and how workload characteristics (latency, statefulness, burstiness) drive the decision. Managed-versus-self-managed reasoning lives here.
You're deploying an ML inference service requiring a GPU-backed model with 100 requests per second baseline and p95 latency under 50ms. Compare serverless GPU options, containers on managed Kubernetes with GPU nodes, and VMs with GPUs. Provide a recommended approach and justify trade-offs for latency, cost, and operational complexity.
Sample Answer
Direct answer
For a steady 100 requests-per-second baseline with a hard 95th-percentile latency ceiling of 50 milliseconds, recommend containers on managed Kubernetes (a platform that runs, schedules, and scales containers across a fleet of machines) with graphics-processing-unit-backed nodes. It gives warm, predictable-latency capacity sized to a known baseline, autoscaling for traffic variance above it, and far less operational burden than running graphics-processing-unit virtual machines directly, while avoiding the cold-start risk that serverless graphics-processing-unit options carry against a tight latency target.
Comparing the three options
Serverless graphics-processing-unit options. Cold starts on accelerator-backed serverless tend to be heavier than on processor-only serverless, since they often add driver or execution-context initialization on top of model loading, which is a serious risk against a 50 millisecond 95th-percentile ceiling unless provisioned or pre-warmed concurrency is used continuously at the full 100 requests-per-second baseline. At that point, the platform is being paid to stay always warm, and most of serverless's cost advantage is gone. This option only makes sense if traffic is genuinely spiky, and a steady 100 requests-per-second baseline is not.
Containers on managed Kubernetes with graphics-processing-unit nodes. Warm replicas eliminate cold-start risk entirely for steady baseline traffic. The managed control plane removes cluster-operations burden while the team still controls replica count, autoscaling policy, and node-pool sizing. This is the best fit for a known, steady baseline with a firm tail-latency requirement.
Virtual machines with graphics processing units. Gives full control over the accelerator driver and runtime stack, which can be the right call if the team needs operating-system-level customization the managed container platform doesn't expose. Otherwise, this option takes on all of the node, operating-system, and driver patching and scaling automation directly, for no latency advantage over the container option at this traffic level, since both are running warm processes on the same class of hardware. The extra operational burden isn't bought back by anything this workload specifically needs.
Worked capacity check
At 100 requests per second with a sub-50-millisecond 95th percentile, expected concurrent in-flight requests, by Little's Law intuition (concurrency is approximately arrival rate multiplied by time in system), works out to:
100×1000ms50ms=5 concurrent requests, at minimumIf a single accelerator-backed replica can serve, say, 10 concurrent requests within that latency budget, a figure to measure by load-testing the actual model rather than assume, the bare-minimum fleet needs less than one full replica's worth of concurrency. That's exactly why bare-minimum sizing is the wrong target: real traffic isn't perfectly smooth, and provisioning only enough capacity for the textbook average leaves zero headroom for burstiness, an occasional slow request, or a single replica failing. Provision meaningfully more, spread across at least two or three replicas for failover, so ordinary traffic variance or one replica's failure doesn't blow the 95th-percentile target.
Trade-offs and pitfalls
The main pitfall is picking serverless graphics-processing-unit options because serverless is assumed to be simpler, without checking whether continuous provisioned concurrency at the actual baseline load erases both the cost and the simplicity advantage; at a steady, known baseline, that check almost always favors containers. The second pitfall is sizing the container fleet to the bare capacity minimum with no headroom, which looks correct on average load but blows the tail-latency target the moment traffic or per-request latency has any real-world variance. Always load-test the chosen replica count against the full expected traffic distribution, not the mean.
Spot (or preemptible) instances offer a steep pricing discount in exchange for the provider being able to reclaim the instance on short notice. Describe how an architecture can safely use spot instances for stateless web tiers, batch processing, and other compute-intensive jobs, and what you'd design in to handle interruptions gracefully.
Sample Answer
Direct answer
Spot (or preemptible) instances are the same underlying hardware as on-demand capacity, sold at a steep discount because the provider can reclaim it with little warning when it needs the capacity back. That makes them safe for exactly one category of workload: work where losing an individual instance mid-task costs you nothing more than retrying that unit of work elsewhere. The architecture you build around them isn't really about spot instances at all, it's about making every unit of work idempotent (safe to run more than once with the same correct end result), checkpointed or cheaply restartable, and never the sole copy of anything.
Structured elaboration
- Stateless web tier: run spot instances as part of a larger autoscaling group that also includes a baseline of on-demand capacity. When a spot instance is reclaimed, the load balancer's health check simply routes around it and the autoscaler replaces it, exactly the same failure mode as a normal instance crashing, provided the tier holds no local, unreplicated state.
- Batch processing: design each job as a small, independently retryable unit rather than one long monolithic run. If an instance is reclaimed mid-unit, the orchestrator (a job queue or a workflow scheduler) simply re-dispatches that unit to another instance. The smaller the unit, the less work is lost per interruption.
- Other compute-intensive jobs (a rendering farm, a large parallel simulation): checkpoint progress periodically to durable storage outside the instance, so a reclaimed instance loses at most the work since the last checkpoint, not the whole job.
Designing for graceful interruption, concretely:
- Listen for the interruption notice. Providers give some advance warning before reclaiming an instance, but the length of that window varies a lot by provider and isn't safe to assume: AWS EC2 Spot gives a fixed two-minute notice, while Google Cloud's and Azure's default Spot/preemptible notice is far shorter, as little as zero to thirty seconds unless you explicitly opt into a longer notice window on the platforms that offer one. Design the shutdown handler for the shortest window your actual provider guarantees, not for the longest one any provider offers, since assuming a two-minute AWS-style window on a platform that only gives thirty seconds will leave in-flight work unfinished when the instance is actually reclaimed. A small agent on the instance watches for that signal and triggers an orderly shutdown: stop accepting new work, finish or checkpoint what's in flight, deregister from the load balancer, then exit.
- Diversify instance types and availability zones. Spot capacity availability and reclaim risk vary independently across instance types and zones; spreading a fleet across several types and zones means a capacity crunch in one pool doesn't take out the whole fleet simultaneously.
- Keep a floor of on-demand (or reserved) capacity for anything that must never fully disappear. A pure spot fleet can, in the worst case, be reclaimed almost entirely at once if the provider needs that capacity broadly; a baseline of guaranteed capacity underneath the spot layer keeps the service alive even in that scenario.
- Make retries idempotent. If a unit of work is re-dispatched after an interruption, running it twice (once partially, once fully) must produce the same correct result as running it once, otherwise interruption doesn't just cost time, it corrupts output.
Worked example
A video-rendering batch pipeline processes 10,000 independent frame-ranges, each taking about 3 minutes on one spot instance:
- Each frame-range is submitted as a separate job to a queue, not one 500-hour job for the whole batch.
- A worker pulls one job, renders it, and writes the output to durable object storage under a deterministic, content-addressed key (say, keyed by the input range and a version hash) before acknowledging the job as complete.
- If the instance is reclaimed mid-render, the job's visibility timeout expires unacknowledged, the queue makes it available again, and a different worker picks it up and re-renders it. Because the output key is deterministic, re-rendering the same range twice (once by the interrupted worker, if it partially wrote output before being killed, and once by the replacement worker) either overwrites the same key harmlessly or is caught by a "does this key already exist" check before starting, so no partial or duplicate output survives.
- The blast radius of losing any one instance is bounded to at most one 3-minute unit of work, not the whole 500-hour job, which is the entire point of choosing a small unit size.
Trade-offs and pitfalls
- Where spot goes wrong: putting a stateful primary (a database, a message broker holding unacknowledged state only it has) on spot capacity. Losing that instance doesn't cost you a retry, it costs you the state itself, unless it's independently replicated elsewhere, which defeats the cost savings if you now need extra replicas just to make spot safe.
- A subtler pitfall: sizing the on-demand floor too thin. Teams sometimes run "mostly spot with a token on-demand instance," which technically has a floor but not enough capacity to serve real traffic if a large fraction of spot capacity is reclaimed at once during a genuine capacity crunch.
- The real trade-off being made: significant cost savings in exchange for engineering effort spent making work interruptible, checkpointed, and idempotent. That engineering cost is often paid once and amortized across every future workload you run on spot, so it's worth investing in the primitives (a resilient job queue, a checkpointing convention, idempotent writes) rather than solving it ad hoc per workload.
A team needs to run nightly batch jobs with variable parallelism and a limited budget; jobs can run up to 4 hours. Compare using serverless functions, container-based batch runners, and a managed batch service for this. Recommend an approach and justify it on cost, execution-time limits, cold starts, and operational effort.
Sample Answer
Direct answer
For nightly batch jobs up to 4 hours with variable parallelism and a limited budget, I'd recommend a managed batch service over both serverless functions and a self-built container-based batch runner. Serverless is ruled out immediately: most serverless platforms cap execution time well under an hour, so a 4-hour job can't run as a single invocation at all without an artificial checkpoint-and-resume workaround. Between the two container-based options, a managed batch service wins specifically because of the budget constraint: it typically integrates spot (or preemptible) capacity natively, which is where the real savings are for interruption-tolerant batch work, without the team having to build that integration themselves.
Structured elaboration
| Option | Execution-time fit | Cold starts | Cost | Operational effort |
|---|---|---|---|---|
| Serverless functions | Fails outright: most platforms cap execution time well below 4 hours, forcing an artificial split into many short invocations even for a naturally sequential job | Irrelevant here, since serverless isn't a viable option for this duration | Would be low per-invocation, but that's moot given the duration limit | Low, but again moot |
| Container-based batch runner (self-scheduled, e.g. a scheduled job on a container platform you manage) | Fits: no execution-time ceiling | Not applicable to a scheduled batch job the way it is to a request-serving function | Moderate: you can use spot/preemptible capacity yourself, but you build and maintain the interruption-handling logic | Higher: your team owns scheduling, retry logic, and parallelism management |
| Managed batch service | Fits: designed for exactly this shape of workload | Not applicable | Lowest achievable here: native spot/preemptible integration with built-in retry-on-interruption, capturing most of the cost savings without building it yourself | Lowest: the service handles queuing, scaling parallelism, and interruption recovery |
Worked example
A nightly extract-transform-load (ETL) pipeline needs to process a variable number of data partitions each night, sometimes 20, sometimes 200, each partition taking anywhere from a few minutes to just under the 4-hour ceiling. On a managed batch service, each partition is submitted as an independent job; the service scales the number of concurrently running workers to match how many partitions are ready, uses interruption-tolerant (spot) capacity by default for the bulk of the work since ETL partitions are independently retryable, and automatically resubmits any partition whose worker was reclaimed mid-run. The budget-conscious part of the design isn't a special decision the team has to make, it's the default behavior of the managed service, whereas building the same interruption-aware retry logic on a self-managed container batch runner is exactly the kind of undifferentiated infrastructure work a small or budget-limited team is worst positioned to build and maintain well.
A distinct concern worth naming for ETL specifically: debugging a failed partition and keeping the pipeline portable across environments both matter more here than for a generic batch job. A managed batch service (or a comparable managed ETL/data-pipeline offering, naming the category rather than a specific vendor tool) that surfaces per-partition logs and lets a failed partition be re-run in isolation, with the same container image used in staging and production, avoids the common failure mode where a nightly job fails at 3am and the on-call engineer can't reproduce the failure locally because the batch environment differs from anywhere they can debug it.
Trade-offs and pitfalls
- Justification against the four named criteria: cost favors the managed batch service due to native spot integration; execution-time limits rule out serverless outright; cold starts are not a meaningful factor for scheduled batch work at all (a common wrong turn is treating cold starts as decisive here, when they matter far more for latency-sensitive request-serving workloads than for a job that already runs for minutes to hours); and operational effort favors the managed service over a self-built runner because interruption handling, retries, and parallelism scaling come built in rather than needing to be engineered and maintained.
- The most common wrong turn on this kind of question: reaching for serverless because "it's cheap and scales automatically" without first checking the execution-time ceiling against the stated 4-hour job length; the duration constraint alone eliminates the option before cost even enters the comparison.
- What would flip the recommendation: if any individual partition genuinely cannot tolerate interruption (a job with expensive, non-checkpointable intermediate state), spot-based savings stop being safely available regardless of which platform runs it, and the team would need to run that specific job on guaranteed (non-preemptible) capacity, accepting the higher cost for that one job while keeping the rest of the pipeline on interruption-tolerant capacity.
Compare serverless functions (e.g. AWS Lambda, GCP Cloud Functions) versus container-based deployments on Kubernetes (EKS/GKE/AKS) for serving ML models. Discuss cold starts, concurrency limits, model size limits, latency characteristics, state management, operational complexity, and cost behavior at low and high traffic volumes. Provide recommendations for small batch inference and for serving large transformer models.
Sample Answer
Direct answer
For serving machine-learning models, recommend containers on managed Kubernetes (a platform that runs, schedules, and scales containers across a fleet of machines) as the default, especially once the model is large, latency-sensitive, or serves meaningful sustained traffic, because a model loaded into memory is exactly the kind of state serverless's scale-to-zero, size-limited execution environment handles worst. Reserve serverless functions for small models, low or unpredictable traffic, or offline batch-style inference, where cold starts and package-size limits aren't binding constraints.
Comparison across the workload's dimensions
Cold starts. Serverless pays a cold start that's often worse for machine-learning serving than for a typical web function, because the cold path usually has to load model weights into memory in addition to bootstrapping the runtime. Containers avoid this entirely once a pod is warm and can keep the model resident continuously.
Concurrency limits. Serverless platforms cap per-account or per-function concurrent executions, which can throttle a burst of inference requests. A container deployment's concurrency is governed by however many replicas you run and scale to, which you control directly.
Model size limits. Serverless functions have deployment-package and memory limits that can make a large model, especially a large transformer, difficult or impossible to package directly. Containers have no comparable ceiling beyond the node's own memory or accelerator capacity.
Latency characteristics. Containers give consistent, predictable per-request latency once warm, with no cold-start tail. Serverless's latency distribution has a long tail driven by the cold-versus-warm mix, a poor fit for a firm latency target.
State management. A loaded model, and for some serving setups an in-memory cache of recent requests or intermediate results, is exactly the kind of long-lived in-process state serverless's stateless, ephemeral execution model works against. Containers hold the model resident across requests naturally.
Operational complexity. Serverless is operationally simpler for small, infrequent workloads, since there's no cluster to run. Containers on Kubernetes require the fleet-management, autoscaling, and monitoring investment, but that investment pays off once traffic and model size grow.
Cost at low traffic. Serverless wins clearly at low, spiky traffic, since billing is per invocation and nothing is charged when idle. A container fleet, even autoscaled to a minimum of one or two replicas for availability, pays for that floor continuously.
Cost at high traffic. Containers usually win at sustained high traffic, since per-invocation billing adds up faster than amortized instance-hours once utilization is consistently high, and a large model paying its load-time cost on every serverless cold start is pure waste at volume.
An easier worked example
An internally facing analytics model, used by a handful of employees with traffic that's unpredictable but modest and no public service-level target, is a good fit for a small Kubernetes deployment with horizontal pod autoscaling (a Kubernetes controller that adds or removes replica pods based on observed load), scaled down to a single replica at idle, rather than serverless. That's specifically because the model's load time makes serverless's cold start expensive relative to how rarely a genuinely new instance would even be needed. A minimum of one warm replica avoids ever paying the model-load cold-start tax, at a small, predictable standing cost.
Recommendations
Small batch inference. Batch inference, processing a queued set of records with no single user waiting synchronously, tolerates a cold start well, since the consumer is a queue, not a person. A serverless function triggered per batch, or per chunk of a batch, is a reasonable, low-operational-cost choice as long as the model fits within the platform's package and memory limits.
Large transformer models. Recommend containers on managed Kubernetes with accelerator-backed nodes, kept warm continuously with no scale-to-zero on serving replicas, since reloading a large transformer's weights on every cold start is both slow and expensive. Use request batching within the serving layer to improve accelerator utilization per request, and size replica count to the sustained request rate, autoscaling on a request-based metric, such as queue depth or in-flight request count, rather than processor utilization, since accelerator-bound inference often doesn't show that as the bottleneck signal.
A harder follow-up: the recommender-system case
A production recommender system combines a latency-tail requirement, since a user-facing response has to come back fast, with sustained high throughput, since traffic is constant rather than spiky. That combination is exactly the profile that most favors containers over serverless: the tail-latency requirement rules out cold starts, and the sustained-throughput profile removes serverless's main cost advantage, since paying only for idle-free capacity stops mattering once the fleet is never idle.
Trade-offs and pitfalls
A common pitfall is choosing serverless for model serving purely because the rest of the stack is serverless, without checking whether this specific model's load time and traffic pattern actually fit. A large model on a platform sized for lightweight functions will either fail to package or cold-start badly enough to violate any real latency expectation. A second pitfall is running a container-based serving fleet with zero warm replicas at idle to save cost, which reintroduces a cold-start-like penalty, since the first request after scaling to zero has to wait for a pod to schedule and the model to load, without the benefit of serverless's per-invocation billing simplicity.
Explain the operational trade-offs between using managed GPU clusters from a cloud vendor versus running your own self-hosted GPU clusters on Kubernetes. Cover productivity, cost predictability, hardware control, scheduling complexity, portability, and long-term maintenance.
Sample Answer
Direct answer
Managed graphics processing unit (GPU) clusters trade a real cost premium for productivity and predictability: someone else handles driver and firmware updates, hardware failures, and scheduling, and you get GPU capacity on demand without a capital commitment. Self-hosted GPU clusters on Kubernetes (an open-source system for running and scaling many containers across a fleet of machines) trade that convenience for cost efficiency at sustained high utilization and full control over the hardware and stack. The crossover isn't about which is "better," it's about whether your utilization is sustained enough, and your team large enough, to make owning the operational burden pay off.
Structured elaboration
| Dimension | Managed GPU clusters | Self-hosted GPU on Kubernetes |
|---|---|---|
| Productivity | High: request capacity, get a working cluster, focus on the workload | Lower initially: you own driver/firmware compatibility, GPU device plugin configuration, and node health, all before a single training job runs |
| Cost predictability | Pay-as-you-go or reserved pricing, invoiced regularly, easy to forecast | Large upfront capital cost (or a long-term reservation) amortized over time; predictable if utilization stays high, unpredictable if hardware sits idle or fails |
| Hardware control | Limited to what the provider exposes (instance shapes, GPU generations they offer) | Full: choose exact GPU models, interconnect topology (how GPUs within and across nodes are networked for multi-GPU training), and firmware versions |
| Scheduling complexity | Provider's scheduler handles GPU allocation; you consume it through the platform's interface | You own GPU-aware scheduling in Kubernetes (device plugins, topology-aware placement so multi-GPU jobs land on GPUs with fast interconnects, not scattered ones), a genuinely hard problem at scale |
| Portability | Tied to whichever provider you're consuming from; migrating means re-provisioning capacity elsewhere | Higher, since the workload runs on standard Kubernetes primitives, though the underlying hardware and drivers are still specific to whatever you bought |
| Long-term maintenance | Provider's responsibility: replacing failed hardware, patching firmware, handling driver updates | Yours: hardware failures need physical or remote-hands intervention, firmware and driver drift across a heterogeneous fleet needs active management |
Worked example
Consider two teams with different utilization profiles:
- A team running occasional fine-tuning jobs, a few days a month, with long idle stretches between them. Managed GPU capacity is the clear fit: paying only for the days actually training, with zero standing hardware to maintain, easily wins over carrying idle, depreciating GPU hardware between jobs. The productivity gain (no driver or scheduler debugging before the first job even runs) matters even more for a small team without dedicated infrastructure staff.
- A team running near-continuous, large-scale training as its core, ongoing workload, effectively saturating GPU capacity around the clock for a sustained period. Here the on-demand premium that managed capacity charges compounds daily at high utilization, and a self-hosted (or long-term-committed) cluster starts to pay for itself; the team can also tune hardware topology and scheduling precisely for its own workload shape, a lever managed capacity doesn't expose. This trade only pays off because the team is large and sustained enough to also own driver drift, hardware failures, and GPU-aware scheduling as ongoing responsibilities, not a one-time setup cost.
The deciding question isn't "how much would we save on paper," it's "does the utilization curve stay high enough, for long enough, that the savings exceed what it costs to staff the operational burden being taken on."
Trade-offs and pitfalls
- The most common wrong turn is comparing only the headline hourly price difference between on-demand managed GPU capacity and owned hardware, without pricing in the operational staffing cost of running GPU-aware Kubernetes scheduling and hardware lifecycle management well; that cost is real and ongoing, not a one-time setup fee.
- A hybrid posture is common and often correct: a self-hosted baseline sized to sustained, predictable demand, with managed GPU capacity absorbing bursts above that baseline, capturing most of the cost benefit of ownership without needing to size owned hardware for peak demand that only occurs occasionally.
- What would flip the recommendation: a sudden drop in a self-hosted team's utilization (a project pausing, demand shrinking) turns previously cost-efficient owned hardware into a straight liability, since unlike managed capacity, idle owned GPUs still cost the same to have bought and still need maintaining.
Unlock Full Question Bank
Get access to all 8 Cloud Compute Options and Trade-offs interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.