Amazon Data Firehose (formerly Kinesis Data Firehose)

Amazon Data Firehose is the serverless delivery service for streaming data. It captures, buffers, optionally transforms, and loads streams into S3, Redshift, OpenSearch, Splunk, Snowflake, HTTP endpoints, and Iceberg tables — with no cluster to manage and automatic scaling.


Firehose vs. Kinesis Data Streams:


Key Features:


Common Use Cases:


Service Limits & Quotas:


Pricing Model:


Code Example:


import boto3, json

firehose = boto3.client("firehose", region_name="us-west-2")

# Send a batch of events to a Firehose stream that delivers to S3 as Parquet
records = [
    {"Data": (json.dumps({"user_id": uid, "event": "click", "ts": 1714000000}) + "\n").encode()}
    for uid in (101, 102, 103)
]

resp = firehose.put_record_batch(
    DeliveryStreamName="events-to-lake",
    Records=records,
)
print(f"Failed: {resp['FailedPutCount']}/{len(records)}")
  

A matching Lambda transform receives base64-encoded records and returns enriched output:


import base64, json

def lambda_handler(event, _ctx):
    out = []
    for rec in event["records"]:
        payload = json.loads(base64.b64decode(rec["data"]))
        payload["ingested_at"] = "2026-04-25T00:00:00Z"
        out.append({
            "recordId": rec["recordId"],
            "result": "Ok",
            "data": base64.b64encode((json.dumps(payload) + "\n").encode()).decode(),
        })
    return {"records": out}
  


Common Interview Questions:

When would you choose Firehose over Kinesis Data Streams?

Choose Firehose when you only need to land data in a managed sink (S3, Redshift, OpenSearch, Splunk, Snowflake, Iceberg) and you don't need replay or multiple custom consumers. Choose Data Streams when you need ordered replay, multiple independent consumers, or sub-second latency.

How does Firehose batch records, and how does that affect downstream files?

Firehose buffers until either the buffer size (1–128 MiB) or interval (60–900 s) threshold is reached, then writes one file per delivery. Tuning these values controls file size in S3 — too small and you create the small-file problem in Athena; too large and you delay availability.

How do you transform records mid-stream?

Attach a Lambda transform. Firehose invokes it per batch with base64-encoded records and expects each record back with a result of Ok, Dropped, or ProcessingFailed. Failed records are sent to the error S3 prefix.

How does dynamic partitioning work and what does it cost?

Dynamic partitioning extracts values from each record (via JQ expressions or Lambda) and uses them to build the S3 prefix at write time, e.g. tenant=acme/year=2026/month=04/. It adds per-GB and per-object surcharges and works best when partition cardinality is bounded.

How is JSON to Parquet conversion configured?

Enable record format conversion on the delivery stream and reference a Glue table with the target schema. Firehose deserializes JSON, casts to the schema, and writes Parquet files — billed per GB processed. Mismatched schemas produce conversion errors that go to the error prefix.

What happens to records that fail delivery?

Firehose retries with exponential backoff for the configured retry duration. After that, records are written to the configured S3 error prefix (one per source: processing-failed, format-conversion-failed, delivery-failed) so you can reprocess them.