Query icon
Return icon
Switch icon
Log icon
SlackIncomingWebhook icon
Schedule icon

Kinesis Stream Throughput Quota Gate

Audit Kinesis stream throttling and consumer lag on a schedule using real CloudWatch metrics and alert Slack before retention-window data loss.

Categories
DataInfrastructure

A Kinesis stream's shard count is a hard capacity limit: 1,000 records or 1 MB per second per shard to write, 2 MB per second per shard to read. Outgrow it and PutRecords starts silently dropping records under WriteProvisionedThroughputExceeded, or a slow consumer falls behind until its iterator age approaches the stream's retention window, by default 24 hours, after which the unread records are gone for good. AWS's own CloudWatch documentation recommends alarming on exactly these two metrics, but nothing fires that alarm until you wire it up. This blueprint turns both metrics into a Day 2 capacity gate: it reads the real values CloudWatch reports, classifies the stream, and alerts Slack with the exact numbers before a producer starts failing or a retention window runs out.

How it works

  1. probe_throughput_exceeded and probe_iterator_age (io.kestra.plugin.aws.cloudwatch.Query) each read one AWS/Kinesis metric for stream_name over window, with periodSeconds set equal to window_seconds so CloudWatch returns exactly one aggregated datapoint instead of several. Both have allowFailure: true so a credentials or region problem does not stop the flow before it can be classified as PROBE_FAILED below.
    • probe_throughput_exceeded reads WriteProvisionedThroughputExceeded with the Sum statistic, any non-zero sum means records were throttled on the way in.
    • probe_iterator_age reads GetRecords.IteratorAgeMilliseconds with the Maximum statistic, AWS's own guidance is to alarm on this once it passes roughly half the stream's retention period.
  2. classify_stream_health (io.kestra.plugin.core.debug.Return) reads .series | first from whichever queries alert_on selects (guarded with is not defined for a probe that produced no output at all) and compares .sum or .maximum against throttled_records_threshold and iterator_age_critical_ms. PROBE_FAILED, CRITICAL, or HEALTHY.
  3. route_by_stream_health (io.kestra.plugin.core.flow.Switch) branches on that status:
    • HEALTHY: log_healthy logs it.
    • CRITICAL, PROBE_FAILED: a SlackIncomingWebhook task alerts with the exact sum and maximum values from the two queries, never an invented number.
  4. log_audit_summary always runs last and logs the final classification.
  5. The errors block posts to Slack if the flow itself fails outside the gate logic above.

What you get

  • A real answer to whether a Kinesis stream is being throttled or falling behind, built from the exact metrics AWS recommends alarming on, not a derived guess.
  • A Slack alert carrying the actual WriteProvisionedThroughputExceeded sum and GetRecords.IteratorAgeMilliseconds maximum, never an invented number.
  • A choice of which signal matters for a given stream (alert_on), a stream with bursty producers and a fast consumer may only care about throughput, one with a slow batch consumer may only care about iterator age.

Who it's for

  • Data platform and streaming teams who own a Kinesis stream's shard count and need to know about throttling or consumer lag before a producer starts failing or records expire.
  • Teams evaluating the CloudWatch plugin who want a working example of io.kestra.plugin.aws.cloudwatch.Query against a real AWS namespace with dimensions.

Why orchestrate this with Kestra

CloudWatch can fire a native alarm, but wiring an SNS topic, a Lambda, and a Slack integration just to get a readable message is its own small project. Kestra adds the schedule, the single declarative query against both metrics, the classification that picks which signal matters per stream, and a Slack alert built from the real numbers, all as one YAML file you can version and review like code next to the rest of your data pipelines.

Prerequisites

  • A Kinesis stream and an AWS credential with cloudwatch:GetMetricStatistics permission. Reads from CloudWatch, nothing in this blueprint writes to the stream or its shards.
  • A Slack incoming webhook for alerts.
  • This plugin calls the AWS SDK directly from the Kestra worker process, there is no sub-container taskRunner and no Docker network to join, any machine Kestra runs on that can reach the AWS CloudWatch API works.
  • No remediation action ships with this blueprint on purpose: the Kestra Kinesis plugin has no task to split a shard or call UpdateShardCount, resharding has to be done with the AWS CLI or console. CRITICAL is deliberately alert-only.

Secrets

  • AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION: credentials used by both io.kestra.plugin.aws.cloudwatch.Query tasks.

  • SLACK_WEBHOOK: Slack incoming webhook URL used by the alert tasks and the errors block.

    In Kestra OSS, set all four as base64-encoded environment variables: SECRET_AWS_ACCESS_KEY_ID, SECRET_AWS_SECRET_ACCESS_KEY, SECRET_AWS_DEFAULT_REGION, SECRET_SLACK_WEBHOOK.

Inputs

Input Type Default Allowed values
stream_name STRING orders-stream any Kinesis stream name
window STRING PT15M any ISO-8601 duration
window_seconds INT 900 must equal window in seconds
throttled_records_threshold INT 1 any non-negative integer
iterator_age_critical_ms INT 43200000 any non-negative integer, in milliseconds
alert_on SELECT both throughput, lag, both

Quick start

  1. Add the AWS and Slack secrets.
  2. Set stream_name to a real stream and run this flow manually.
  3. Read log_audit_summary for the classification, and compare window_seconds against window if you change either, they must match.
  4. Enable the fifteen_minutely trigger, whose cron matches the default window.

How to extend

  • When CRITICAL fires on throughput, chain a downstream task that calls the AWS CLI's aws kinesis update-shard-count via a script task to double the shard count, behind a manual approval task, since the Kestra plugin itself has no such task.
  • Add the ShardId dimension and enable enhanced shard-level monitoring on the stream to find which specific shard is hot, instead of only the stream-level aggregate.
  • Read iterator_age_critical_ms from the stream's actual RetentionPeriodHours instead of a fixed constant, so the threshold scales automatically if retention changes.

Pitfalls

  • periodSeconds and window must describe the same length of time. If window_seconds is smaller than window, CloudWatch returns more than one datapoint and .series | first reads only the earliest one, not the whole window.
  • WriteProvisionedThroughputExceeded and GetRecords.IteratorAgeMilliseconds are basic, stream-level metrics billed at no extra charge, this blueprint does not require enabling Kinesis enhanced (shard-level) monitoring, which has its own per-shard charge.
  • A brand new or genuinely idle stream can return zero datapoints for a window, which this blueprint treats as HEALTHY since there is nothing to throttle or fall behind on, not as a reason to alert.
  • This reads GetRecords.IteratorAgeMilliseconds, which only has data if something is actually calling GetRecords against the stream. A stream with no active consumer reports zero datapoints for this metric even while records pile up unread.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.