---
title: "Firebolt vs Druid: Engines or Segments"
excerpt: "Idle FBU hours versus always-on Historicals, and why CREATE STREAM is not a supervisor."
authors: "Tinybird"
categories: "AI Resources"
createdOn: "2026-09-30 00:00:00"
publishedOn: "2026-09-30 00:00:00"
updatedOn: "2026-09-30 00:00:00"
status: "published"
---

Firebolt and Apache Druid are both sold as sub-second dashboards. One of them scales compute to zero when you stop the engine. The other does not.

Firebolt is a cloud warehouse: tablets in object storage, a sparse primary index per tablet, optional aggregating indexes, isolated engines billed in FBUs. Standard US compute is **$0.23 per FBU-hour**. A compute-optimized Small is 4 FBU, **$0.92/hour** while the engine runs, per-second billing ([Firebolt billing](https://docs.firebolt.io/managed-service/billing)). An idle engine you forgot to stop is a warehouse you left on.

Druid is a streaming OLAP database: Kafka supervisors, realtime tasks, immutable segments, Historicals, Brokers. The dashboard hits local bitmaps. The cluster does not go away when the workbook closes.

Firebolt documents [`DATE_TRUNC`](https://docs.firebolt.io/reference-sql/functions-reference/date-and-time/date-trunc):

```sql
SELECT
  DATE_TRUNC('minute', ts) AS minute,
  country,
  COUNT(*) AS events,
  SUM(revenue) AS revenue
FROM page_views
WHERE ts >= NOW() - INTERVAL '1 hour'
GROUP BY 1, 2
```

In Firebolt that is an engine scan pruned by `PRIMARY INDEX (country, ts)`, or served from an aggregating index whose grouping keys match. In Druid that is scatter/gather over segments that may already be rolled up at ingest.

[ClickHouse® vs Firebolt](https://www.tinybird.co/blog/clickhouse-vs-firebolt-real-time-data-warehouse) is the engine comparison. [ClickHouse vs Druid](https://www.tinybird.co/blog/clickhouse-vs-druid) is the process graph. This page is what you pay when nobody is looking, and whether Kafka ingest looks like a supervisor or like `INSERT`.

## CREATE STREAM is not a supervisor

Druid **pulls** the topic. Realtime tasks answer during the in-flight interval. `maxRowsPerSegment` defaults to 5,000,000 post-aggregation rows. Kafka `handoffConditionTimeout` defaults to 15 minutes ([Druid supervisor](https://druid.apache.org/docs/latest/ingestion/supervisor/)). Handoff publishes to deep storage. Historicals load. Freshness is seconds if the supervisor is healthy. There is no "stop the Historicals overnight."

Firebolt **writes tablets**, then queries with an engine. `COPY` from object storage still applies. Kafka is documented as `CREATE STREAM` plus `INSERT INTO … SELECT FROM READ_STREAM(...)`. Offsets advance in that write transaction ([CREATE STREAM](https://docs.firebolt.io/reference-sql/commands/data-definition/create-stream), [READ_STREAM](https://docs.firebolt.io/reference-sql/functions-reference/table-valued/read_stream)):

```sql
CREATE LOCATION kafka_src WITH (SOURCE = KAFKA, BROKERS = 'broker:9092');

CREATE STREAM page_views_stream (
  ts TIMESTAMP,
  country TEXT,
  revenue DOUBLE
)
TOPIC = 'page_views'
LOCATION = 'kafka_src'
TYPE = 'JSON';

INSERT INTO page_views
SELECT ts, country, revenue
FROM READ_STREAM(STREAM page_views_stream);
```

No realtime task. No segment handoff. No Historicals. The engine must be running for the `INSERT`. That is warehouse-shaped ingest: a SQL write on billed compute, not scatter/gather over in-flight segments.

## Add the cube after the table exists

Firebolt's primary index is a sparse sort, one key sample per granule (default 8,192 rows), not a uniqueness constraint. Filters that match the leading columns prune granules by binary search inside each tablet. Same idea as a MergeTree `ORDER BY`, with tablet metadata on top.

An aggregating index is a precomputed `GROUP BY` stored as partial aggregate state. Firebolt maintains it in the same transaction as the base write. You query the base table. The planner rewrites to the index when grouping keys match. Get the grouping order wrong and you scan the fact table anyway.

```sql
CREATE AGGREGATING INDEX page_views_1m ON page_views (
  DATE_TRUNC('minute', ts),
  country,
  COUNT(*),
  SUM(revenue)
);
```

Druid ingest rollup is the same economic idea with a harder contract. Dimensions and metrics are declared in the supervisor spec. Change `country` to `campaign` and you reindex. Bitmaps sit on every dimension. High-cardinality IDs as dimensions are how segments explode.

Firebolt lets you add the aggregating index after the table exists. Druid wants the cube at ingest if you want the cheap segment. Query-time SQL over raw events is ClickHouse or a warehouse scan, not classic Druid.

## Isolation you buy with FBU

You can run isolated engines so concurrency in workbook A does not steal CPU from workbook B. That is a usage pattern, not a product rule that one workbook equals one engine. FBU = node FBU × nodes × clusters ([engine consumption](https://docs.firebolt.io/managed-service/engine-consumption)).

A Medium compute-optimized engine is 8 FBU, **$1.84/hour** on Standard US. Two of those left on 12 hours/day, 22 days is `2 × $1.84 × 12 × 22 ≈ $973/month` compute before storage (arithmetic, not a quote). Storage is pass-through S3. us-east-1 is **$27.07 per TiB/month** on Firebolt's billing table.

Auto-stop helps if resume is acceptable. A 15-second customer tile cannot auto-stop. Then you are paying FBU hours the way you pay a warehouse that never sleeps. A compute-optimized Small left up 12 hours × 22 days is `$0.92 × 12 × 22 ≈ $243/month` for that engine. Storage-optimized Small is a different node (8 FBU, $1.84/hour Standard US). Do not mix the two.

Druid isolation is segment placement. Historicals serve many datasources. A noisy dashboard is another Broker query on the same Historicals unless you split clusters. You pay the process graph whether anyone is looking. The **marginal cost of another 15-second refresh is ~0** once segments are local. That is why Druid wins high-QPS closed cubes, and why the cluster never looks cheap on a quiet Sunday.

[Apache Druid alternatives](https://www.tinybird.co/blog/apache-druid-alternatives) is people looking at Coordinators, Overlords, MiddleManagers, Historicals, Brokers, ZK. Firebolt's people cost is index design plus whoever owns `COPY` / `READ_STREAM` cadence. An aggregating index that does not match the `GROUP BY` is a silent full scan. Primary index column order is the same trap as a bad MergeTree `ORDER BY`.

## Kafka ingest without leaving an engine on

Neither an engine nor a Broker is an HTTP contract. Tinybird publishes ClickHouse SQL as a pipe. Kafka ingest is a [connector](https://www.tinybird.co/docs/forward/ingest-data/connectors/kafka), not `READ_STREAM` on billed FBU. HTTP ingest is the [Events API](https://www.tinybird.co/docs/forward/ingest-data/events-api) (documented default: 100 requests/sec per datasource).

The aggregating index analog is a materialized pipe into `AggregatingMergeTree`. You declare it in git. The engine is not sitting on waiting for `INSERT`:

```tinybird
DESCRIPTION >
    Minute-country rollup. States, not finished counts.

NODE minute_country
SQL >
    SELECT
        toStartOfMinute(ts) AS minute,
        country,
        countState() AS events,
        sumState(revenue) AS revenue
    FROM page_views
    GROUP BY minute, country

TYPE MATERIALIZED
DATASOURCE page_views_1m
```

Target datasource holds the states. The endpoint reads merges:

```tinybird
DESCRIPTION >
    Last hour from the rollup, not from the raw fact table.

SCHEMA >
    `minute` DateTime,
    `country` LowCardinality(String),
    `events` AggregateFunction(count, UInt64),
    `revenue` AggregateFunction(sum, Float64)

ENGINE "AggregatingMergeTree"
ENGINE_SORTING_KEY "country, minute"
```

```tinybird
DESCRIPTION >
    Serve the rollup.

NODE from_rollup
SQL >
    SELECT
        minute,
        country,
        countMerge(events) AS events,
        sumMerge(revenue) AS revenue
    FROM page_views_1m
    WHERE minute >= now() - INTERVAL 1 HOUR
    GROUP BY minute, country
    ORDER BY minute, country

TYPE ENDPOINT
```

`npx tinybird preview` / `npx tinybird deploy`. The 15-second tile is compute on that rollup, not an engine left on and not a Broker pool. Developer plans and vCPU overage at **$0.0002 per vCPU-second** are on [Tinybird pricing](https://www.tinybird.co/pricing).

You do not get Firebolt's isolated engines for BI concurrency, or Druid's ingest-time bitmaps. Wrong buy for a BI team that already lives in Firebolt workbooks. Wrong buy for a Druid CoE with a frozen cube. Right buy when ingest is Kafka or HTTP, the `GROUP BY` will change, and the consumer is an app.

## If you need in-flight segments, you still need Druid

Use Firebolt when tablets will be loaded, the primary index will be designed, and BI concurrency needs isolated engines. Use Druid when Kafka must be queryable in seconds on a closed cube and a team already runs supervisors. Use Tinybird when those same events have to be an API.

## Frequently Asked Questions (FAQs)

### Does Firebolt replace a Druid supervisor?

No. Supervisors, realtime tasks, and handoff are a streaming indexer. `READ_STREAM` is a SQL write into tablets on a running engine. Aggregating indexes are a warehouse rollup maintained on that write. Different process, similar SQL shape.

### Can Firebolt ingest Kafka at all?

Yes. `CREATE STREAM` plus `INSERT INTO … SELECT FROM READ_STREAM(...)`. Offsets commit with the write. That is not in-flight segments and Broker scatter/gather. If the engine is stopped, the `INSERT` does not run.
