Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/s2-streamstore/s2/llms.txt

Use this file to discover all available pages before exploring further.

Overview

S2 Lite uses object storage as its primary durability layer through SlateDB. This guide covers setup for popular S3-compatible storage providers.

AWS S3

Prerequisites

  • AWS account with S3 access
  • IAM credentials or EC2 instance profile
  • S3 bucket created in your desired region

IAM Permissions

Create an IAM policy with the following permissions:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::your-bucket-name",
        "arn:aws:s3:::your-bucket-name/*"
      ]
    }
  ]
}

Local Development with AWS Profile

1

Configure AWS credentials

Ensure your AWS credentials are configured:
aws configure
2

Create an S3 bucket

aws s3 mb s3://my-s2-lite-bucket --region us-east-1
3

Run S2 Lite with Docker

docker run -p 8080:80 \
  -e AWS_PROFILE=${AWS_PROFILE} \
  -v ~/.aws:/home/nonroot/.aws:ro \
  ghcr.io/s2-streamstore/s2 lite \
  --bucket my-s2-lite-bucket \
  --path s2lite

Production with IAM Roles

EC2 Instance Profile

1

Create IAM role

Create an IAM role with the S2 Lite policy and attach it to your EC2 instance.
2

Launch S2 Lite

s2 lite --bucket my-s2-lite-bucket --path s2lite
S2 Lite automatically discovers and uses the instance profile credentials.

Kubernetes with IRSA (EKS)

1

Create IAM role for service account

eksctl create iamserviceaccount \
  --name s2-lite \
  --namespace default \
  --cluster my-cluster \
  --attach-policy-arn arn:aws:iam::123456789012:policy/S2LitePolicy \
  --approve
2

Install Helm chart with IRSA

# values.yaml
objectStorage:
  enabled: true
  bucket: my-s2-lite-bucket
  path: s2lite

serviceAccount:
  create: true
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/s2-lite-role
helm install my-s2-lite s2/s2-lite-helm -f values.yaml
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1

s2 lite --bucket my-s2-lite-bucket --path s2lite
Avoid using static credentials in production. Use IAM roles or instance profiles instead.

Tigris

Tigris provides globally distributed S3-compatible object storage with low latency.

Setup

1

Create Tigris bucket

Sign up at tigrisdata.com and create a bucket.
2

Get credentials

Generate access credentials from the Tigris console:
  • AWS Access Key ID
  • AWS Secret Access Key
3

Run S2 Lite

docker run -p 8080:80 \
  -e AWS_ACCESS_KEY_ID=${TIGRIS_ACCESS_KEY_ID} \
  -e AWS_SECRET_ACCESS_KEY=${TIGRIS_SECRET_ACCESS_KEY} \
  -e AWS_ENDPOINT_URL_S3=https://fly.storage.tigris.dev \
  ghcr.io/s2-streamstore/s2 lite \
  --bucket my-tigris-bucket \
  --path s2lite

Kubernetes Deployment

1

Create secret for credentials

kubectl create secret generic s2-lite-tigris \
  --from-literal=AWS_ACCESS_KEY_ID=${TIGRIS_ACCESS_KEY_ID} \
  --from-literal=AWS_SECRET_ACCESS_KEY=${TIGRIS_SECRET_ACCESS_KEY}
2

Deploy with Helm

# values.yaml
objectStorage:
  enabled: true
  bucket: my-tigris-bucket
  path: s2lite
  endpoint: https://fly.storage.tigris.dev

env:
  - name: AWS_ACCESS_KEY_ID
    valueFrom:
      secretKeyRef:
        name: s2-lite-tigris
        key: AWS_ACCESS_KEY_ID
  - name: AWS_SECRET_ACCESS_KEY
    valueFrom:
      secretKeyRef:
        name: s2-lite-tigris
        key: AWS_SECRET_ACCESS_KEY
helm install my-s2-lite s2/s2-lite-helm -f values.yaml

Cloudflare R2

Cloudflare R2 provides S3-compatible storage with zero egress fees.

Setup

1

Create R2 bucket

Create a bucket in the Cloudflare dashboard under R2.
2

Generate API token

Create an R2 API token with read and write permissions:
  • Access Key ID
  • Secret Access Key
  • Account ID (for endpoint)
3

Run S2 Lite

docker run -p 8080:80 \
  -e AWS_ACCESS_KEY_ID=${R2_ACCESS_KEY_ID} \
  -e AWS_SECRET_ACCESS_KEY=${R2_SECRET_ACCESS_KEY} \
  -e AWS_ENDPOINT_URL_S3=https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com \
  ghcr.io/s2-streamstore/s2 lite \
  --bucket my-r2-bucket \
  --path s2lite

Public Endpoint (Optional)

Cloudflare R2 supports custom domains for public bucket access:
# Use public domain endpoint
docker run -p 8080:80 \
  -e AWS_ENDPOINT_URL_S3=https://pub-*.r2.dev \
  ghcr.io/s2-streamstore/s2 lite \
  --bucket my-r2-bucket

MinIO (Self-Hosted)

MinIO is a high-performance, self-hosted S3-compatible object store.

Local Development

1

Start MinIO server

docker run -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=minioadmin \
  -e MINIO_ROOT_PASSWORD=minioadmin \
  minio/minio server /data --console-address ":9001"
2

Create bucket

Access MinIO console at http://localhost:9001 and create a bucket named s2lite.
3

Run S2 Lite

docker run --network host \
  -e AWS_ACCESS_KEY_ID=minioadmin \
  -e AWS_SECRET_ACCESS_KEY=minioadmin \
  -e AWS_ENDPOINT_URL_S3=http://localhost:9000 \
  ghcr.io/s2-streamstore/s2 lite \
  --bucket s2lite \
  --path data

Production Deployment

For production MinIO deployments:
# values.yaml for S2 Lite
objectStorage:
  enabled: true
  bucket: s2lite
  path: data
  endpoint: http://minio.minio-system.svc.cluster.local:9000

env:
  - name: AWS_ACCESS_KEY_ID
    valueFrom:
      secretKeyRef:
        name: minio-credentials
        key: accesskey
  - name: AWS_SECRET_ACCESS_KEY
    valueFrom:
      secretKeyRef:
        name: minio-credentials
        key: secretkey

Advanced Configuration

SlateDB Settings

Customize SlateDB behavior using SL8_ prefixed environment variables:
# Adjust flush interval (defaults: 50ms for S3, 5ms for in-memory)
SL8_FLUSH_INTERVAL=10ms s2 lite --bucket my-bucket

# Configure manifest poll interval
SL8_MANIFEST_POLL_INTERVAL=5s s2 lite --bucket my-bucket
See SlateDB Settings Reference for all options.

Enable Pipelining (Experimental)

Enable append pipelining for improved performance:
S2LITE_PIPELINE=true s2 lite --bucket my-bucket
Pipelining is currently experimental and disabled by default. See issue #48 for status.

Path Organization

Use the --path flag to organize multiple S2 Lite instances in the same bucket:
# Production instance
s2 lite --bucket shared-bucket --path production/s2lite

# Staging instance
s2 lite --bucket shared-bucket --path staging/s2lite

# Development instance  
s2 lite --bucket shared-bucket --path dev/s2lite

Testing Your Setup

1

Check server health

curl http://localhost:8080/health
Should return 200 OK.
2

Configure S2 CLI

export S2_ACCOUNT_ENDPOINT="http://localhost:8080"
export S2_BASIN_ENDPOINT="http://localhost:8080"
export S2_ACCESS_TOKEN="ignored"
3

Create a basin

s2 create-basin test --create-stream-on-append
4

Test write and read

# Write data
echo "Hello S2 Lite" | s2 append s2://test/greetings

# Read it back
s2 read s2://test/greetings --limit 1

Troubleshooting

Connection Issues

  • Verify bucket name is correct
  • Check endpoint URL format (must include https:// or http://)
  • Ensure credentials have proper permissions
  • Test connectivity: aws s3 ls s3://your-bucket --endpoint-url $AWS_ENDPOINT_URL_S3
  • Review IAM policy permissions
  • Verify bucket exists in the specified region
  • Check that credentials are not expired
  • For IRSA, ensure service account annotations are correct
S2 Lite auto-detects region from AWS config. Set explicitly if needed:
export AWS_REGION=us-west-2
s2 lite --bucket my-bucket

Performance Issues

  • Reduce SL8_FLUSH_INTERVAL for faster acknowledgment (at cost of more object store writes)
  • Enable pipelining with S2LITE_PIPELINE=true (experimental)
  • Ensure S2 Lite is deployed in the same region as your object storage
S2 Lite sleeps for one manifest_poll_interval on startup to ensure proper fencing. This is expected behavior. Reduce interval if needed:
SL8_MANIFEST_POLL_INTERVAL=1s s2 lite --bucket my-bucket

Next Steps

Production Deployment

Deploy S2 Lite on Kubernetes with Helm

Backup & Restore

Configure backup strategies for your data

Build docs developers (and LLMs) love