> ## 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.

# Quick start

> Get started with S2 in minutes by creating your first basin and stream

# Quick start

This guide will walk you through setting up S2 Lite locally and creating your first basin and stream. You'll be reading and writing records in just a few minutes.

## Prerequisites

* The S2 CLI installed ([installation guide](/installation))
* A terminal or command prompt

## Start S2 Lite

S2 Lite is embedded in the CLI and provides a fully functional S2 API that runs in-memory. Start it with:

```bash theme={null}
s2 lite --port 8080
```

This starts S2 Lite on port 8080 with in-memory storage. No external dependencies required.

<Note>
  For production use, you can configure S2 Lite to use object storage like AWS S3 or Tigris. See the [S2 Lite documentation](https://github.com/s2-streamstore/s2#s2-lite) for details.
</Note>

## Configure the CLI

In a new terminal, set these environment variables to point the CLI at your local S2 Lite instance:

```bash theme={null}
export S2_ACCOUNT_ENDPOINT="http://localhost:8080"
export S2_BASIN_ENDPOINT="http://localhost:8080"
export S2_ACCESS_TOKEN="ignored"
```

<Tip>
  S2 Lite doesn't require authentication for local development, but you still need to set `S2_ACCESS_TOKEN` to any value.
</Tip>

## Verify the server is ready

Check that S2 Lite is running:

```bash theme={null}
curl http://localhost:8080/health
```

You should see a 200 OK response.

## Create a basin

Create your first basin with automatic stream creation enabled:

```bash theme={null}
s2 create-basin quickstart --create-stream-on-append --create-stream-on-read
```

This creates a basin named `quickstart` that automatically creates streams when you append to or read from them.

<Steps>
  <Step title="Create a basin">
    The basin is created with automatic stream creation enabled
  </Step>

  <Step title="Append records">
    Write your first records to a stream
  </Step>

  <Step title="Read records">
    Read the records back from the stream
  </Step>
</Steps>

## Write records to a stream

Append some records to a new stream:

```bash theme={null}
echo "Hello, S2!" | s2 append s2://quickstart/my-stream
echo "This is my first record" | s2 append s2://quickstart/my-stream
echo "Streaming is fun" | s2 append s2://quickstart/my-stream
```

Each line becomes a separate record in the stream. The stream is created automatically because we enabled `--create-stream-on-append`.

## Read records from a stream

Read all records from the stream:

```bash theme={null}
s2 read s2://quickstart/my-stream
```

You should see all three records printed to stdout.

<CodeGroup>
  ```bash Read from beginning theme={null}
  # Read all historical records
  s2 read s2://quickstart/my-stream
  ```

  ```bash Tail live updates theme={null}
  # Read and wait for new records (like tail -f)
  s2 read s2://quickstart/my-stream --follow
  ```

  ```bash Read from specific position theme={null}
  # Read from sequence number 1
  s2 read s2://quickstart/my-stream --start-seq-num 1
  ```
</CodeGroup>

## Try real-time streaming

Open two terminals to see real-time streaming in action.

**Terminal 1** - Start a live reader:

```bash theme={null}
s2 read s2://quickstart/live-demo --follow 2>/dev/null
```

**Terminal 2** - Stream data in:

```bash theme={null}
for i in {1..10}; do 
  echo "Message $i" | s2 append s2://quickstart/live-demo
  sleep 1
done
```

You'll see messages appear in Terminal 1 as they're written in Terminal 2.

<Tip>
  Try the Star Wars streaming demo for something more fun:

  ```bash theme={null}
  # Terminal 1: Start reading
  s2 read s2://quickstart/starwars 2>/dev/null

  # Terminal 2: Stream Star Wars
  nc starwars.s2.dev 23 | s2 append s2://quickstart/starwars
  ```
</Tip>

## Benchmark performance

Test S2 Lite's performance with the built-in benchmark:

```bash theme={null}
s2 bench quickstart --target-mibps 10 --duration 5s --catchup-delay 0s
```

This writes and reads data at 10 MiB/s for 5 seconds, showing throughput and latency metrics.

## Next steps with the SDK

Now that you have S2 Lite running, try using the SDK to build applications.

### Rust SDK example

Add the SDK to your project:

```bash theme={null}
cargo add s2-sdk tokio futures
```

Write and read records programmatically:

<CodeGroup>
  ```rust Write records theme={null}
  use s2_sdk::{
      S2,
      producer::ProducerConfig,
      types::{AppendRecord, S2Config},
  };

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let client = S2::new(S2Config::new(std::env::var("S2_ACCESS_TOKEN")?))?;
      let stream = client.basin("quickstart".parse()?)
                         .stream("my-stream".parse()?);
      
      let producer = stream.producer(ProducerConfig::new());
      
      let ticket = producer.submit(AppendRecord::new("Hello from Rust!")?).await?;
      let ack = ticket.await?;
      
      println!("Record written with seq_num: {}", ack.seq_num);
      
      producer.close().await?;
      Ok(())
  }
  ```

  ```rust Read records theme={null}
  use futures::StreamExt;
  use s2_sdk::{
      S2,
      types::{ReadInput, S2Config},
  };

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let client = S2::new(S2Config::new(std::env::var("S2_ACCESS_TOKEN")?))?;
      let stream = client.basin("quickstart".parse()?)
                         .stream("my-stream".parse()?);
      
      let mut batches = stream.read_session(ReadInput::new()).await?;
      
      while let Some(batch) = batches.next().await {
          let batch = batch?;
          println!("Received batch: {:?}", batch);
      }
      
      Ok(())
  }
  ```
</CodeGroup>

<Note>
  Remember to export the environment variables pointing to your S2 Lite instance before running SDK examples.
</Note>

## Using S2 cloud

To use the managed S2 service instead of S2 Lite:

<Steps>
  <Step title="Sign up">
    Create an account at [s2.dev](https://s2.dev)
  </Step>

  <Step title="Generate access token">
    Generate an access token from the [dashboard](https://s2.dev/dashboard)
  </Step>

  <Step title="Configure CLI">
    Set your access token:

    ```bash theme={null}
    export S2_ACCESS_TOKEN="your-token-here"
    ```

    Remove the endpoint overrides (or unset them):

    ```bash theme={null}
    unset S2_ACCOUNT_ENDPOINT
    unset S2_BASIN_ENDPOINT
    ```
  </Step>

  <Step title="Create resources">
    Use the same commands to create basins and streams
  </Step>
</Steps>

## Troubleshooting

<Warning>
  If you see connection errors, make sure S2 Lite is running and the environment variables are set correctly.
</Warning>

### Common issues

**Connection refused**

* Check that `s2 lite` is running
* Verify the port matches your `S2_ACCOUNT_ENDPOINT` and `S2_BASIN_ENDPOINT`

**Stream not found**

* Make sure you created the basin with `--create-stream-on-append` or `--create-stream-on-read`
* Or manually create the stream with `s2 create-stream`

**Environment variables not set**

* Re-export the environment variables in each new terminal session
* Or add them to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.)

## Learn more

* [Installation guide](/installation) - Install other SDKs and tools
* [Concepts](https://s2.dev/docs/concepts) - Understand basins, streams, and records
* [API reference](https://s2.dev/docs/api) - Explore the full REST API
* [SDK documentation](https://docs.rs/s2-sdk) - Rust SDK reference
