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



## Overview [#overview]

Publishing events one at a time means each call pays its own round-trip: write the request, wait on the connection, then move to the next event. That's fine for occasional notifications, but it caps throughput when you need to push hundreds or thousands of events per second — log forwarding, sensor telemetry, change-data-capture feeds — where per-call overhead dominates.

`client.create_events_sender` opens one persistent gRPC stream up front and returns a sender. Each subsequent `sender.publish(msg)` writes onto that already-open stream instead of negotiating a new call, so a tight publishing loop isn't blocked waiting on a broker round-trip for every event.

**Gotchas:** events are still fire-and-forget pub/sub underneath — no subscriber means a streamed event is dropped just like a regular one, and `publish` returning doesn't guarantee delivery. Always close the sender explicitly (`sender.close`) when finished; it will also close when the client closes, but leaving it dangling in a long-running process holds a gRPC connection open on the broker. Reach for a stream sender only when publishing many events in a burst — for occasional events, the overhead of managing a sender's lifecycle isn't worth it.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Ruby SDK installed (`gem install kubemq`)

## Code [#code]

```ruby title="main.rb"
require 'kubemq'

address = ENV.fetch('KUBEMQ_ADDRESS', 'localhost:50000')
channel = 'ruby-events.stream-send'

begin
  client = KubeMQ::PubSubClient.new(address: address, client_id: 'stream-send-example')
  puts "Connected to #{address}"

  sender = client.create_events_sender
  puts 'Created stream sender'

  10.times do |i|
    msg = KubeMQ::PubSub::EventMessage.new(
      channel: channel,
      metadata: "stream event #{i}",
      body: "payload-#{i}"
    )
    sender.publish(msg)
    puts "Sent event #{i} via stream"
  end

  sleep 1
  puts 'All events sent via stream'
rescue KubeMQ::Error => e
  puts "KubeMQ error: #{e.message}"
ensure
  sender&.close
  client&.close
  puts 'Done'
end
```

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

* `create_events_sender` opens a persistent gRPC stream for low-latency, high-throughput publishing.
* Close the sender explicitly when finished, or it will be closed when the client is closed.
* Use stream sending when publishing many events in a tight loop — the persistent connection avoids per-message overhead.
* Review timeouts, channel names, and client IDs before running against shared environments.

## Related [#related]

* [Pattern overview](/learn/events/getting-started)
* [Ruby SDK Reference](/sdks/ruby/reference)
* [Basic Pub/Sub](/sdks/ruby/tutorials/basic-pubsub)
