Kafka Pipelines — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Kafka Pipelines (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Partition count is the one Kafka decision that is nearly permanent: it caps consumer parallelism forever, and increasing it later rehashes keys and breaks per-key ordering for every keyed consumer. The two costly mistakes this skill prevents are under-partitioning a topic that later gets hot, and committing offsets before processing - which silently loses records on the first crash.
Collect these before choosing any number. Label estimates as guesses and revisit after load testing.
Compute both bounds and take the larger:
Then multiply by a 2x growth headroom factor and round to a highly divisible number (12, 24, 30, 60) so consumer counts divide evenly. Keep per-broker partition counts in the low thousands (roughly under 4,000 per broker); thousands of near-idle partitions inflate rebalance and recovery time.
Records with the same key go to the same partition and preserve order. Pick a key that both balances load and groups what must stay ordered (e.g. customerId for per-customer ordering). Check cardinality: a key with fewer distinct values than roughly 10x the partition count risks hot partitions. Never key on a low-cardinality field like country or status.
min.insync.replicas=2, so one broker can die without losing acks or availability.acks=all
enable.idempotence=true
max.in.flight.requests.per.connection=5
compression.type=zstdIdempotent producers with acks=all give exactly-once delivery to a partition and prevent duplicates from retries. Batch with linger.ms (5-20 ms is a reasonable throughput/latency trade) and batch.size for throughput.
props.put("enable.auto.commit", "false");
// process records, then:
consumer.commitSync();Commit after processing, not before, or a crash loses every record in the uncommitted batch.
max.poll.interval.ms defaults to 300,000 ms (5 minutes); exceed it between polls and the broker evicts the consumer and rebalances. Budget: max.poll.records × worst-case per-record time must stay under ~50% of max.poll.interval.ms. At 200 ms per record, the default 500 records needs 100 s - fine; at 2 s per record, cap max.poll.records at ~75 or raise the interval.
When a record cannot be processed after retries, route it to a dead-letter topic rather than blocking the partition:
orders -> [process] --fail--> orders.DLQ (with headers: error, original-offset, timestamp)For read-process-write flows staying within Kafka, use transactions to commit offsets and output atomically, or use Kafka Streams, which manages this. When the sink is external (a database, an API), transactions do not reach it - make processing idempotent instead (idempotency keys, upserts) and accept at-least-once. Idempotent processing is mandatory regardless, because rebalances reprocess records.
Monitor consumer lag per partition. Alert on lag that grows monotonically for 10+ minutes, or lag exceeding the equivalent of a few minutes of peak production - rising lag means undersized or stalled consumers. Use a schema registry (Avro or Protobuf) with a compatibility mode enforced so producers cannot break consumers.
Orders topic: peak 40 MB/s produce rate, ~2 KB messages. A load test shows one consumer sustains ~4 MB/s per partition once the Postgres write (the dominant cost) is batched; producers comfortably push 8 MB/s per partition.
customerId (millions of distinct values, per-customer ordering required).Produce a topic design document containing: partition count with the sizing math shown, partition key with its cardinality justification, retention and compaction settings, replication and min.insync.replicas, producer and consumer config blocks, poll-budget arithmetic, DLQ policy (retry count, backoff, headers, replay plan), and the lag-alert thresholds.
A finished design passes only when: the partition count shows both producer and consumer bounds and names which one binds; the key's cardinality is stated; retention is derived from a replay window, not defaulted; the poll budget arithmetic is shown against max.poll.interval.ms; the DLQ has bounded retries and a replay path; and every "measured" number is either measured or labeled a guess with a plan to load-test it.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.