Coming from Trino or Spark
If you’ve run Trino, Spark, or Databricks, you have a mental model of how distributed query execution works: a coordinator, a pool of workers, a shared cluster you size and manage. Icebreaker works differently enough that it’s worth making the contrast explicit.
The model you know: shared cluster
Section titled “The model you know: shared cluster”In Trino or Spark, there is a persistent cluster — a coordinator (or driver) and a pool of worker nodes that stay running between queries. When a query arrives, the coordinator breaks it into fragments and distributes them across the workers. Workers share CPU, memory, and sometimes local disk.
This model is powerful and familiar, but it creates problems that anyone who has run it in production knows well:
- Cluster sizing is a permanent guess. You size for expected peak workload, which means you either overprovision (pay for idle workers around the clock) or underprovision (queries queue or fail under burst).
- Queries compete for resources. Multiple concurrent queries share the worker JVM heap. A poorly-written query, or an AI agent submitting hundreds of small queries at once, degrades performance for everyone else on the cluster.
- Spot is not practical. When a Spot worker is reclaimed, every query with tasks on that node fails immediately — by default, Trino does not retry them automatically, so those queries are lost and must be resubmitted by the client. Meanwhile, all pending work stalls until a replacement node is provisioned and the cluster stabilizes. A single Spot interruption is a cluster-level event. Most teams avoid Spot entirely for production Trino or Spark.
- Multi-tenancy requires partitioning. Giving different teams resource guarantees means configuring separate queues, pools, or clusters — and teams still share the underlying JVM. The practical result is departmental warehouses: one per team, each sized independently, each sitting idle between jobs.
The Icebreaker model: one pod per query
Section titled “The Icebreaker model: one pod per query”Icebreaker has no persistent worker pool. Each query gets its own ephemeral Kubernetes pod — a self-contained execution environment created when the query arrives and destroyed when it finishes.
The pod runs DataFusion, a Rust-native query engine that starts in under a second. It reads source Parquet files directly from S3, computes results, writes them to your results bucket, and exits. Nothing is shared with any other query.
If you’re new to Kubernetes: a pod is roughly a container — a lightweight, isolated process with its own CPU and memory enforced by the Linux kernel. Think of it as a temporary compute environment spun up for one purpose and discarded when done.
How this changes the operational picture
Section titled “How this changes the operational picture”No cluster to size or manage
Section titled “No cluster to size or manage”There is no fixed worker pool. Karpenter — the Kubernetes node autoscaler built into EKS Auto Mode — provisions an EC2 node when a pod needs one that doesn’t exist yet, and terminates the node when it’s idle. Capacity follows demand automatically, within the limits of your Capacity Policy. Your FinOps team defines the envelope; Karpenter fills it per query.
Queries cannot interfere with each other
Section titled “Queries cannot interfere with each other”Each pod has its own kernel-enforced CPU and memory limits. A runaway query hits its own pod’s ceiling and is terminated — no other query is affected. In Trino, a bad query can starve the whole worker pool. In Icebreaker, a bad query degrades only itself.
Spot becomes production-grade
Section titled “Spot becomes production-grade”When a Spot node is reclaimed, only the queries running on that node are interrupted — typically one or two. The Job Manager detects them and resubmits automatically. Every other query continues running. The failure boundary is a single query, not the cluster.
This is why Icebreaker can reliably run production workloads on Spot. The expected savings are 70–90% off On-Demand rates. Combined with serverless elasticity — no idle cluster between queries — most customers see 85%+ cost reduction compared to a static On-Demand Trino or Spark cluster sized for the same workload.
Multi-tenancy is inherent
Section titled “Multi-tenancy is inherent”Because every query runs in its own isolated pod, a heterogeneous mix of users — people, AI agents, scheduled jobs — running analytical queries, exploratory queries, and heavy data transformations can all submit to the same Data Server simultaneously. Each gets its own execution environment; none can affect the others. There is nothing to configure and no infrastructure to partition.
This is the serverless model: one shared Data Server, per-query isolation by default. You do not split your data platform by department. As query tagging becomes available, cost can be attributed per query, team, or workload type — without any infrastructure partitioning.
Side by side
Section titled “Side by side”| Trino / Spark | Icebreaker | |
|---|---|---|
| Persistent cluster | Yes — size, monitor, tune | No — Karpenter provisions per query |
| Idle cost | Full worker cluster runs continuously | Agent and Data Server only — no worker nodes when idle |
| Spot viability | Impractical — lost worker fails active queries (not retried by default) and stalls all pending work | Production-safe — one query retried automatically; nothing else affected |
| Noisy neighbor | Yes — shared JVM heap | No — kernel-enforced isolation per pod |
| Concurrency limit | Fixed by cluster size | Dynamic — scales with available EC2 capacity |
| Multi-tenancy | Requires partitioning — separate queues, pools, or clusters per team | Inherent — one Data Server serves all users; isolation is per-query by default |
| Cost attribution | Approximate — cluster share | Exact — cost per query, by pod |
What Kubernetes is doing here
Section titled “What Kubernetes is doing here”Kubernetes is the orchestration layer that makes the per-query pod model practical. It handles scheduling (which EC2 node does each pod land on), health management (what happens if a pod crashes), resource accounting (how much CPU and memory is each pod consuming), and networking (how pods reach S3 and each other).
If you’ve used AWS Lambda: query executor pods work on a similar principle — each spins up for a single invocation, runs to completion, and is discarded. The key difference is that they run on your own EC2 capacity inside your VPC, not on AWS’s shared infrastructure. Your data never leaves your environment, and you keep your negotiated EC2 rates.
The Icebreaker Agent manages the long-lived components. Per-query pod lifecycle is handled by the Data Server’s Job Manager, which creates and destroys pods via the Kubernetes API as queries arrive and complete.