# Stream Send (/sdks/java/how-to/events-store/stream-send)



## Overview [#overview]

**Stream send** covers publishing a batch of persistent events back-to-back, without pausing your producer between messages. A single `publishEventStore` call is fine for one-off writes, but if you're bulk-loading history, replicating a firehose of records, or backfilling an Events Store channel, sending events in rapid succession turns network latency into your throughput ceiling instead of an app-level bottleneck.

Each `publishEventStore(message)` call still confirms storage synchronously, returning an `EventSendResult` whose `isSent()` flag tells you the broker persisted the event before the loop advances to the next one. Tracking elapsed time and successful sends across the batch gives you a real throughput number you can compare against other publishing strategies. &#x2A;*Gotchas:** each call blocks on its own confirmation, so this loop is latency-bound — very high fan-out workloads need concurrent sends rather than one tight loop; a single failed `isSent()` doesn't stop the batch, so you must check every result if you need all-or-nothing delivery; and don't treat printed throughput numbers as a benchmark without warming up the connection and running a realistic payload size first.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Java SDK installed (`implementation 'io.kubemq.sdk:kubemq-sdk-Java:3.1.1'` (Gradle) or Maven dependency from [Getting Started](/sdks/java))

## Code [#code]

```java title="StreamSendExample.java"
package io.kubemq.example.eventsstore;

import io.kubemq.sdk.common.ServerInfo;
import io.kubemq.sdk.pubsub.*;

import java.util.UUID;

/**
 * Stream Send Example (EventsStore)
 *
 * Demonstrates high-throughput streaming of events store messages.
 */
public class StreamSendExample {

    private static final String ADDRESS = "localhost:50000";
    private static final String CLIENT_ID = "java-eventsstore-stream-send-client";
    private static final String CHANNEL = "java-eventsstore.stream-send";

    public static void main(String[] args) throws InterruptedException {
        // Create a client connected to the KubeMQ server
        PubSubClient client = PubSubClient.builder()
                .address(ADDRESS)
                .clientId(CLIENT_ID)
                .build();

        // Verify connection to the server
        ServerInfo info = client.ping();
        System.out.println("Connected to: " + info.getHost());
        // Create the events store channel
        client.createEventsStoreChannel(CHANNEL);

        int messageCount = 10;
        // Send multiple events store messages (high-throughput)
        System.out.println("Sending " + messageCount + " events store messages via stream...\n");

        long start = System.currentTimeMillis();
        int successCount = 0;

        for (int i = 1; i <= messageCount; i++) {
            EventStoreMessage message = EventStoreMessage.builder()
                    .id(UUID.randomUUID().toString())
                    .channel(CHANNEL)
                    .body(("Stream store event #" + i).getBytes())
                    .metadata("stream-batch")
                    .build();

            EventSendResult result = client.publishEventStore(message);
            if (result.isSent()) {
                successCount++;
            }
        }

        long elapsed = System.currentTimeMillis() - start;
        System.out.println("Sent " + successCount + "/" + messageCount + " events in " + elapsed + "ms");
        System.out.println("Throughput: " + (messageCount * 1000 / Math.max(elapsed, 1)) + " msg/sec");

        // Clean up resources
        client.deleteEventsStoreChannel(CHANNEL);
        client.close();
        System.out.println("\nStream send example completed.");
    }
}

```

## How It Works [#how-it-works]

* `client.publishEventStore(message)` returns `EventSendResult` synchronously; each call confirms storage on the broker before the loop advances.
* `successCount` tracks acknowledged sends; any broker-side rejection would decrement from the expected 10.
* Elapsed time and throughput printed at the end measure the cost of synchronous acknowledgement per message — useful for comparing against plain Events publish or batching strategies.

## Related [#related]

* [Pattern overview](/learn/events-store/getting-started)
* [Java SDK Reference](/sdks/java/reference/events-store)
* [Persistent Pub/Sub](/sdks/java/tutorials/persistent-pubsub)
* [Cancel Subscription](/sdks/java/how-to/events-store/cancel-subscription)
