Lab Recorder and Streaming Layer Anyone who's run a multimodal experiment knows the headache: an EEG headset sampling at 500 Hz, an eye tracker at 120 Hz, and a physiological sensor on its own clock, all needing to line up perfectly for analysis. Manually aligning these streams after the fact invites drift, dropped samples, and hours of cleanup.

Lab Streaming Layer (LSL) exists to solve exactly this problem. Paired with LabRecorder, it's become the de facto open-source standard for capturing synchronized, multi-device data in neuroscience and psychology labs.

This article covers how LSL works under the hood, how LabRecorder captures and saves your streams, step-by-step setup instructions, and the pitfalls that trip up first-time users.

Key Takeaways

  • LSL streams and time-synchronizes multi-device lab data over the network as open-source middleware.
  • LabRecorder writes every active LSL stream into one metadata-rich XDF file.
  • Sound network setup, stream naming, and timing checks stop the most common data-loss errors.
  • When samples or reagents are involved, environmental data integrity matters as much as timing precision.

What Is Lab Streaming Layer (LSL) and Why It Matters

LSL is real-time middleware for exchanging time-series data streams across networked devices in a lab setting. It handles networking, clock synchronization, near-real-time access, and optional recording to disk.

The project started in 2012 at the Swartz Center for Computational Neuroscience (UC San Diego). Christian Kothe built it to solve a concrete problem: labs were running EEG, eye-tracking, and physiological systems with no common way to talk to each other.

A 2025 peer-reviewed reference paper reports the ecosystem now spans over 150 LSL-compatible device classes and more than 2,300 citations since its introduction.

Commonly streamed data types include:

  • EEG and MEG signals
  • fNIRS (functional near-infrared spectroscopy)
  • EMG and other physiological measures
  • Eye-tracking coordinates
  • Event markers and audio triggers

Why Researchers Choose LSL

Manually starting and stopping recordings on separate devices sounds simple until you account for clock drift, mismatched sampling rates, and jitter. The reference paper notes these effects can cause synchronization to drift by many milliseconds within minutes during a typical multimodal setup.

LSL's own validation testing reported less than 1 millisecond of timing error under both single-computer and networked configurations. That's a meaningful margin for anyone doing event-related analysis where timing precision drives the science.

Timing precision is only part of the appeal. Official bindings cover:

  • C and C++
  • Python (pylsl)
  • MATLAB
  • Java and C#

Community-supported bindings extend this to JavaScript, Rust, and Julia. You don't need to be a systems programmer to get a stream running.

How the LSL Streaming Architecture Works

LSL runs on a publish/subscribe model. An outlet publishes a data stream and its metadata onto the local network, making it discoverable. An inlet, built by another application, finds that stream and pulls samples from it using pull_sample() for individual readings or pull_chunk() for batches.

Stream discovery works by name and type. Once your EEG software declares an outlet named "EEG_Stream," any inlet on the same network can find and subscribe to it without manual IP configuration.

Once streams connect, timing has to stay consistent across machines. LSL's clock-offset procedure borrows from Network Time Protocol (NTP).

By default, it performs eight UDP packet exchanges, estimates round-trip time and offset for each, then keeps the offset from the lowest round-trip measurement. The receiving application can then map any remote timestamp to its own local clock.

LSL clock synchronization process showing UDP packet exchange and offset calculation

Two pull strategies cover different stream types:

  • Sample-by-sample: Pulls individual readings; best for low-rate, latency-sensitive streams like event markers
  • Chunk-based: Pulls sample batches; reduces OS calls and network overhead for high-rate signals like EEG

Chunk size is a trade-off. Bigger chunks mean less overhead but higher latency, so pick based on what your experiment can tolerate.

Regardless of how you pull samples, each stream carries a stream_info object documenting name, type, channel count, nominal sampling rate, and data format. This metadata rides along with the data itself, so you're never guessing what a given channel represents months later during analysis.

LSL publish subscribe architecture diagram showing outlet inlet stream discovery

Using LabRecorder to Capture and Save Streams

LabRecorder is the standard application for recording one or more LSL streams into a single XDF file. It's free, open-source, and available on GitHub.

The basic workflow:

  1. Launch your device software and confirm each one has LSL streaming enabled
  2. Open LabRecorder and check the streams listed under "Record from Streams"
  3. Click Update if a device started after LabRecorder opened (this refresh takes about 2 seconds)
  4. Select your streams using the checkboxes, choose a save location, and click Start
  5. Click Stop when the session ends

Why XDF Format Matters

XDF (Extensible Data Format) was designed alongside LSL to hold multi-stream containers with large XML metadata headers and built-in time-synchronization information. Unlike exporting each device to a separate CSV, XDF keeps everything—timestamps, channel labels, and sampling rates—in one file.

Required Streams: A Safety Net

LabRecorder's "Required Streams" feature lets you flag devices that must be present before recording starts. Missing required streams show up in red, and the app prompts for confirmation before proceeding. This catches the classic mistake of starting a session only to realize the eye tracker never connected.

Reading Your XDF File Later

Once recorded, you can load and inspect XDF files using:

  • pyxdf in Python (pyxdf.load_xdf("file.xdf"))
  • MNE-Python, which has a built-in XDF reading example for EEG data
    • MATLAB with the load_xdf function for offline import

Setting Up Your First LSL and LabRecorder Pipeline

Getting your first pipeline running takes fewer steps than most researchers expect.

  1. Install liblsl, the core transport library, via GitHub Releases, Anaconda, vcpkg, or Homebrew
  2. Install language bindings — for Python, run pip install pylsl
  3. Download LabRecorder from its official release page
  4. Configure your acquisition device (EEG software, eye tracker, etc.) to broadcast an LSL outlet with a clear, descriptive stream name
  5. Verify connectivity by opening LabRecorder and confirming the stream appears before you start recording

Example scenario: Syncing an EEG headset with an event-marker stream.

Start the EEG acquisition software first and confirm its LSL outlet is active. Then run your stimulus-presentation script so it sends single-channel string markers at each trial event.

Open LabRecorder, verify both streams appear, mark the EEG stream as required, and hit Start. After the session, load the XDF file and confirm EEG data and marker timestamps are present before analysis.

Common Pitfalls and Best Practices for Reliable Recordings

Hardware latency isn't the same as software latency. LSL's own documentation puts local transport latency under 0.1 ms, but a physical sensor's signal might already be several milliseconds "old" by the time it reaches the outlet. Test each device configuration individually rather than assuming uniform latency across your setup.

Network issues are usually firewall-related. If a stream won't show up:

  • Confirm all devices are on the same local network
  • Check that UDP broadcast/multicast on port 16571 is open
  • Verify TCP/UDP ports 16572–16604 aren't blocked

LSL network troubleshooting checklist for firewall and port configuration issues

Prefer wired connections over Wi-Fi for critical recordings.

Watch effective sampling rate, not just nominal rate. A stream's nominal_srate metadata tells you what it's supposed to run at. Compare that against the effective rate, calculated from actual timestamps, to catch dropped samples before they wreck your analysis. This check only applies to regularly sampled streams. Event markers are irregular by design, so skip the rate comparison for those.

Why Data Integrity Matters Beyond the Lab

LSL and LabRecorder solve timing synchronization for your data streams. But timing precision means little if the samples, reagents, or biological materials behind that data weren't stored under valid environmental conditions.

Labs that pair streaming setups with temperature-sensitive work—cryogenic sample storage, vaccine handling, or reagent stability testing—need traceable proof that storage conditions stayed within range throughout the study. A perfectly synchronized EEG dataset doesn't help if the biological samples it's paired with degraded from a temperature excursion nobody caught.

Realog View's TempTrail™ line covers that environmental side as complementary lab infrastructure, not a replacement for your data pipeline:

  • TempTrail Glacial (–85°C to +70°C) for cryogenic biologics and dry-ice storage
  • TempTrail HiTemp (+5°C to +140°C) for autoclave validation
  • TempTrail RH (0–100% RH) for lab temperature and humidity monitoring

These loggers generate automatic PDF and CSV reports without external software, and they're FDA 21 CFR Part 11 compliant, meaning the records are tamper-evident and audit-ready. That matters for labs operating under regulatory oversight where every data point, streaming or environmental, needs to hold up to scrutiny.

Frequently Asked Questions

What is Lab Streaming Layer used for?

LSL synchronizes and records time-series data streams from multiple devices, such as EEG, eye trackers, and physiological sensors, in research settings. It handles networking and clock alignment so researchers don't have to manually sync files after the fact.

Is LabRecorder free to use?

Yes. LabRecorder is a free, open-source tool available on GitHub, built specifically to capture LSL streams into XDF files.

What file format does LabRecorder produce?

LabRecorder saves data as XDF (Extensible Data Format), a container built to hold multiple time-series streams along with their metadata and timestamp correction information in a single file.

Can LSL be used with any programming language?

LSL has official APIs for C, C++, Python, Java, C#, and MATLAB, with community bindings for JavaScript, Rust, and Julia. Most researchers use Python or MATLAB for their acquisition scripts.

Why can't I find my LSL stream on the network?

The most common causes are devices on different networks, a firewall blocking the required ports (16571 for discovery, 16572–16604 for data), or a misconfigured lsl_api.cfg file. Check firewall settings first.

How do I open and analyze an XDF file after recording?

Use pyxdf in Python, MNE-Python's built-in XDF reader, or MATLAB's load_xdf function. All three preserve the original stream metadata and timestamps for analysis.