Apache Iggy
ConnectorsSinks

S3 Sink

Write messages from Iggy streams to Amazon S3 and S3-compatible object stores such as MinIO, R2, Spaces and B2.

The S3 sink connector writes messages from Iggy streams to Amazon S3 and S3-compatible object stores (MinIO, Cloudflare R2, DigitalOcean Spaces, Backblaze B2). Messages are buffered in memory and uploaded as files, rotated by size or message count, under configurable path templates with offset ranges in the object names.

This page is a curated subset of the documentation. The canonical reference is the upstream s3_sink README in the apache/iggy repository.

Configuration

type = "sink"
key = "s3"
enabled = true
version = 0
name = "S3 sink"
path = "target/release/libiggy_connector_s3_sink"
plugin_config_format = "toml"

[[streams]]
stream = "application_logs"
topics = ["api_requests", "errors"]
schema = "json"
batch_length = 1000
poll_interval = "100ms"
consumer_group = "s3_sink"

[plugin_config]
bucket = "my-data-lake"
prefix = "iggy/raw"
region = "us-east-1"
path_template = "{stream}/{topic}/{date}/{hour}"
file_rotation = "size"
max_file_size = "8MiB"
output_format = "json_lines"

Common Options

OptionTypeDefaultDescription
bucketstringrequiredS3 bucket name
regionstringrequiredAWS region, e.g. us-east-1 (auto for R2)
prefixstringnoneKey prefix prepended to all objects
endpointstringnoneCustom S3 endpoint for MinIO, R2, and other compatible stores
path_templatestring{stream}/{topic}/{date}/{hour}Directory structure for S3 keys
file_rotationstringsizesize or messages
max_file_sizestring8MiBRotation threshold when file_rotation = "size"
max_messages_per_fileu64noneRotation threshold, required when file_rotation = "messages"
output_formatstringjson_linesjson_lines, json_array, or raw
include_metadatabooltrueInclude stream/topic/partition/offset in the output
include_headersboolfalseInclude message headers in the output

Further options cover credentials (access_key_id / secret_access_key), retries (max_attempts 3, retry_delay 1s with exponential backoff and jitter), and path_style addressing (auto-enabled when endpoint is set). See the upstream s3_sink README for the full reference.

Path templates support {stream}, {topic}, {partition}, {date}, {hour}, and {timestamp}. The time-based variables derive from the first message timestamp in each buffer. File names embed the partition (zero-padded to 5 digits, to prevent cross-partition collisions) and the offset range (zero-padded to 20 digits), e.g. application_logs/api_requests/2026-03-16/14/00000-00000000000000000000-00000000000000000999.jsonl.

Credentials

Credentials resolve in order of precedence: explicit access_key_id + secret_access_key in the config (both together or neither), the standard AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN environment variables, the AWS shared credentials file (~/.aws/credentials), then container credentials or the instance profile when running on EC2/ECS/EKS.

MinIO example

[plugin_config]
bucket = "my-bucket"
region = "us-east-1"
endpoint = "http://localhost:9000"
access_key_id = "minioadmin"
secret_access_key = "minioadmin"

Delivery Semantics

The connector runtime commits consumer offsets before consume() runs and does not inspect its return value, so the effective guarantee is at-most-once: upload failures are retried only by the sink's internal retry loop, and a crash loses whatever is buffered in memory but not yet flushed to S3 (there is no write-ahead log or dead-letter queue). Size your rotation thresholds accordingly: smaller files bound the loss window, larger files upload more efficiently.

Transforms

Transforms can be applied before writing to S3. See the transforms documentation for the available types and their configuration.

On this page