New to Kestra?
Use blueprints to kickstart your first workflows.
Audit Kinesis stream throttling and consumer lag on a schedule using real CloudWatch metrics and alert Slack before retention-window data loss.
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.
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.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.route_by_stream_health (io.kestra.plugin.core.flow.Switch) branches on that status:log_healthy logs it.SlackIncomingWebhook task alerts with the exact
sum and maximum values from the two queries, never an invented number.log_audit_summary always runs last and logs the final classification.errors block posts to Slack if the flow itself fails outside the gate logic above.WriteProvisionedThroughputExceeded sum and
GetRecords.IteratorAgeMilliseconds maximum, never an invented number.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.io.kestra.plugin.aws.cloudwatch.Query against a real AWS namespace with dimensions.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.
cloudwatch:GetMetricStatistics permission.
Reads from CloudWatch, nothing in this blueprint writes to the stream or its shards.taskRunner and no Docker network to join, any machine Kestra runs on
that can reach the AWS CloudWatch API works.UpdateShardCount, resharding has to be done with the
AWS CLI or console. CRITICAL is deliberately alert-only.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.
| 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 |
stream_name to a real stream and run this flow manually.log_audit_summary for the classification, and compare window_seconds against
window if you change either, they must match.fifteen_minutely trigger, whose cron matches the default window.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.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.iterator_age_critical_ms from the stream's actual RetentionPeriodHours instead
of a fixed constant, so the threshold scales automatically if retention changes.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.HEALTHY since there is nothing to throttle or fall behind on, not
as a reason to alert.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.