# Idle Kinesis Stream -- No Records Read

> ZopNight compares IncomingRecords against GetRecords.Records over 30 days. A stream still receiving data that nothing consumes is the expensive failure mode: you pay per shard-hour to buffer records that then expire unread after the retention period, while producers see successful writes and no error surfaces anywhere.

Source: https://zop.dev/integrations/aws/recommendations/idle-kinesis-stream-no-records-read
Updated: 2026-08-19

---

## The dangerous case is not an empty stream

A Kinesis stream with no producers and no consumers is obvious and cheap to reason about. The
finding that matters is a stream that is **still receiving records nobody reads**, with
producers writing faithfully into a pipeline whose consumer was decommissioned.

That costs money continuously, per shard-hour, and it fails silently: the producer sees
successful writes, no error surfaces anywhere, and the records simply expire after the retention
window having been read by nothing.

## Two metrics, compared rather than thresholded

`IncomingRecords`, one of [the per-stream series Kinesis publishes to CloudWatch](https://docs.aws.amazon.com/streams/latest/dev/monitoring-with-cloudwatch.html), tells you data is arriving. `GetRecords.Records` tells you something is
consuming it. The finding is the gap between them, which is why both are required. Either one
alone gives you half the picture.

## Where the cost sits

Kinesis [bills per shard-hour plus a per-record charge](https://aws.amazon.com/kinesis/data-streams/pricing/), and the shard count is provisioned rather
than automatic on a standard stream. An abandoned consumer does not reduce the shard count, so
the stream keeps its full provisioned capacity indefinitely.

Extended retention is worth checking too. A stream configured for 7 or 30 days of retention
costs meaningfully more than the 24-hour default, and long retention on a stream nobody reads is
paying to keep data for a consumer that no longer exists.

## Comparing GetRecords.Records with IncomingRecords

```bash
aws cloudwatch get-metric-statistics \
  --namespace AWS/Kinesis --metric-name GetRecords.Records \
  --dimensions Name=StreamName,Value=my-stream \
  --start-time "$(date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)" \
  --end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --period 86400 --statistics Sum
```

Compare against `IncomingRecords` over the same window.

## Before deleting

Find the producers first. Deleting a stream that something is still writing to turns silent waste
into loud errors in an unrelated service. That is arguably an improvement, but not one to
discover by surprise. Stop the producers, confirm the stream drains, then delete.
