Sinks
Sinks control where your Rerun data goes. They are the output destinations for your logged data.
When you log data with Rerun, that data needs to flow somewhere, whether that's to a live viewer, a file on disk, memory, or multiple destinations at once. Sinks provide this routing layer, giving you flexible control over how and where your recordings are stored and displayed.
Available sink types
Rerun provides several built-in sink types, each designed for specific use cases:
GrpcSink
Streams data to a Rerun Viewer over gRPC. This is the most common sink for live visualization.
"""Create and set a GRPC sink."""
import rerun as rr
rr.init("rerun_example_grpc_sink")
# The default URL is `rerun+http://127.0.0.1:9876/proxy`
# This can be used to connect to a viewer on a different machine
rr.set_sinks(rr.GrpcSink("rerun+http://127.0.0.1:9876/proxy"))
FileSink
Writes data to .rrd files on disk.
"""Create and set a file sink."""
import rerun as rr
rr.init("rerun_example_file_sink")
rr.set_sinks(rr.FileSink("recording.rrd"))
Multiple sinks (Tee pattern)
One of the most powerful features of Rerun's sink system is the ability to send data to multiple destinations simultaneously. This "tee" pattern lets you both visualize data live and save it to disk in a single run.
"""Log some data to a file and a Viewer at the same time."""
import numpy as np
import rerun as rr
# Initialize the SDK and give our recording a unique name
rr.init("rerun_example_set_sinks")
rr.set_sinks(
# Connect to an existing local Viewer or gRPC server.
rr.GrpcSink(),
# To host a gRPC server instead, replace the sink above with:
# rr.GrpcServerSink(),
# Write data to a `data.rrd` file in the current directory
rr.FileSink("data.rrd"),
)
# Create some data
SIZE = 10
pos_grid = np.meshgrid(*[np.linspace(-10, 10, SIZE)] * 3)
positions = np.vstack([d.reshape(-1) for d in pos_grid]).T
col_grid = np.meshgrid(*[np.linspace(0, 255, SIZE)] * 3)
colors = np.vstack([c.reshape(-1) for c in col_grid]).astype(np.uint8).T
# Log the data
rr.log(
# name under which this entity is logged (known as "entity path")
"my_points",
# log data as a 3D point cloud archetype
rr.Points3D(positions, colors=colors, radii=0.5),
)
This pattern is useful when:
- You want to monitor a long-running process while archiving the data
- You're debugging and want both live feedback and a recording to analyze later
- You need to stream to multiple viewers or save to multiple files
Stream to a Viewer and save to a file at the same time (teeing)
Use set_sinks with both a GrpcSink and a FileSink, as in the snippet above.
Calling rr.spawn(), rr.connect_grpc(), or rr.save() replaces all existing sinks.
To start a Viewer without touching your sinks, call rr.spawn(connect=False): it only starts the Viewer process, and your GrpcSink can then connect to it.
rr.init("rerun_example_spawn_and_save")
rr.spawn(connect=False) # Start a Viewer, but leave the sinks alone.
rr.set_sinks(rr.GrpcSink(), rr.FileSink("data.rrd"))Connection lifecycle
These rules apply to the gRPC sink (connect_grpc, spawn, and GrpcSink):
- Connecting: the SDK connects in the background and retries forever, with a backoff of up to one second between attempts. You can start logging before the Viewer is running: data is queued until the connection is up. If the queue fills up before a connection is made, log calls block.
- Flushing:
flushwaits for queued data to be sent. If the SDK has not connected yet,flushgives up after about 5 seconds. In Python, userec.flush(timeout_sec=…)on aRecordingStream(for example the one returned byrr.get_global_data_recording()) to limit how long it waits; it raises an error on timeout. - Shutdown: at shutdown, the SDK waits at most about 5 seconds for a final connection attempt. If it still cannot connect, the queued data is dropped and an error is logged.
- Disconnects: if an established connection fails (for example because the Viewer was closed), the SDK does not reconnect.
Data logged after that is lost for this sink.
If you need the data, also log to a
FileSink. - Status: only the Rust SDK exposes the connection state, through the experimental
GrpcSink::status.
If the Viewer cannot start because its port is taken, run rerun --port auto (or rerun --new) to start a new Viewer on a free port, and connect to the port it prints.
See also
- Recordings: Understand how recordings relate to sinks
- Blueprints: Learn how to configure the viewer's layout
- API References: