Skip to main content

Timing and data quality

This page explains the timing infrastructure and data-quality safeguards built into the participation pipeline. Understanding these mechanisms helps you design studies that produce clean, analyzable data and gives reviewers confidence in your methodology.

Reaction-time measurement

Every behavioral task that records a participant response measures reaction time (RT) using the browser's high-resolution performance clock. This clock provides sub-millisecond precision and is not affected by system clock adjustments, making it the recommended timing source for web-based experiments.

  • How it works: When a stimulus appears, the platform records the onset time. When the participant responds (key press, click, or touch), the platform records the response time and computes the difference. The result is stored in milliseconds as latency_ms alongside each trial response.
  • Reference timeline: At the start of each session, the platform establishes a reference point that anchors all subsequent timestamps. Every event (stimulus, response, marker, phase transition) is recorded relative to this reference, so you can reconstruct the exact sequence and spacing of events during analysis.
  • Dual timestamps: Each logged event carries both an ISO wall-clock timestamp (for human-readable dates) and a high-resolution value in milliseconds (for precise interval calculations). Use the high-resolution values when computing RTs; use the wall-clock timestamps for session identification and sorting.

What affects web-based timing precision

Web experiments run inside a browser, which introduces sources of variability that do not exist in laboratory software:

  • Display refresh rate: Stimuli appear at the next screen refresh after the draw call. On a 60 Hz monitor this adds up to ~16.7 ms of jitter; at 144 Hz the window shrinks to ~6.9 ms. The platform does not lock stimulus presentation to specific video frames.
  • Input device latency: Keyboard and mouse events pass through the operating system's input stack before reaching the browser. Typical added latency is 4 to 20 ms depending on hardware, OS, and whether the device uses USB polling or Bluetooth.
  • Browser event scheduling: JavaScript timers (used for fixation crosses, inter-stimulus intervals, and stimulus durations) rely on the browser's event loop. Under normal conditions the scheduling error is ≤4 ms; heavy page activity or background tabs can increase it.
  • Cross-browser differences: All modern browsers (Chrome, Firefox, Edge, Safari) implement the same high-resolution timer, but micro-level precision varies. Chrome-based browsers tend to report the most consistent sub-millisecond values.

Practical guidance: For paradigms where timing precision is critical (masked priming, attentional blink, backward masking), consider requiring participants to use a desktop or laptop with a wired keyboard and a Chrome-based browser. Use the device-gating and screen-metrics features described below to record the participant's setup.

Spoken (auditory) stimulus timing

Some tasks present stimuli aloud by playing audio clips the researcher recorded or uploaded once in the study configuration (for example list-learning tasks and continuous-performance / vigilance tasks play items one at a time). Every participant hears the same recording, and the platform starts each clip on the browser's audio clock. Reaction times measured from spoken stimuli still carry a residual caveat:

  • Onset is the scheduled clip start, not the acoustic wavefront: the platform marks the stimulus onset when the clip is started on the audio clock. The remaining gap to the sound actually leaving the speaker is the device's audio-output pipeline, typically a few milliseconds up to ~20 ms, larger and more variable on Bluetooth audio. The platform records the browser-reported output-latency values with each clip onset so this residual can be inspected per participant. A precise cross-browser bound is pending bench measurement.
  • Implication: spoken-stimulus reaction times are now interpretable for most purposes, but their floor is still above the ~1 ms visual measurement floor and depends on the participant's audio hardware. Comparisons within the same participant and setup are the most robust.
  • Steady-rate streams stay evenly spaced: when a task plays a continuous stream of items at a fixed rate, the schedule is anchored to a single start point rather than chained off each previous item, so the spacing does not drift over a long run. The configured item duration is authoritative: a shorter clip is followed by silence, and analyses of change-over-time (for example a vigilance decrement) should use the recorded onset times of each item.
  • Playback failures are flagged: if a clip cannot be played on a participant's device, the affected task falls back (words shown on screen, or the task is skipped when it is auditory-only) and the data is marked. Exclude flagged items from auditory reaction-time analysis.
  • Recommendation: when strict reaction-time precision matters, present stimuli visually rather than spoken.

Session-level data quality

Device gating

The platform always enforces three device requirements before allowing participation. These checks ensure participants have the minimum hardware capabilities needed for behavioral research:

  • Camera support: The browser must support camera access (required for video-recorded sessions).
  • Microphone support: The browser must support microphone access (required for speech-based tasks and audio recording).
  • Minimum viewport width: The browser's inner width must be at least 768 pixels to ensure task stimuli display correctly.

These requirements are not configurable and apply to all studies. Participants who fail any check see a message explaining the requirement. They are not allowed to proceed until the issue is resolved or they close the page.

Environmental metadata

Each participation session automatically records a snapshot of the participant's environment. This metadata is available in the exported session data and helps you assess whether environmental differences might explain outlier results.

Screen metrics

Captured at the start of each session and updated whenever the participant resizes the window or rotates their device:

  • Screen resolution: Physical screen width, height, available width, and available height in pixels.
  • Viewport size: The browser's inner dimensions (the area where stimuli are displayed).
  • Device pixel ratio: Indicates high-DPI ("Retina") displays. A ratio of 2 means the display renders at twice the nominal pixel count.
  • Screen orientation: Portrait or landscape, plus the rotation angle.
  • Color and pixel depth: The screen's color bit depth.
  • Browser and language: User agent string and browser language setting.

Interaction telemetry

When enabled for a study, the platform records a continuous stream of participant interactions throughout the session:

  • Keyboard events: Each key press is logged with a high-resolution timestamp (individual characters are anonymized to "char" to avoid capturing typed passwords or personal information).
  • Pointer events: Mouse clicks, taps, and cursor movements are recorded with viewport-relative coordinates (as percentages, not absolute pixels).
  • Scroll events: Scroll position changes.
  • Focus and visibility: When the participant switches away from the browser tab or returns to it. This is particularly useful for detecting participants who multitask during a session.

All telemetry events carry the same high-resolution timestamps as task data, so you can align interaction patterns with stimulus and response events in your analysis.

Media timeline

For sessions with camera or screen-share recording, the platform records start and end timestamps for each media stream. This lets you synchronize the video recording with behavioral markers, responses, and task transitions.

Recording synchronization and timing accuracy

When a session is recorded, the platform aligns the behavioral data (markers, responses, gaze, transcription) with the video so that everything sits on a single timeline. In exported data this shared timeline is recording time: milliseconds from the camera's first frame. This is what lets you replay a recording and see each stimulus and response land at the right moment.

Synchronization quality

Every recorded participation is assigned a synchronization quality, reported in the export and surfaced as the Approximate sync label on the participations list:

  • Precise: the behavioral data and the video are reliably aligned. Use the recording-time values freely.
  • Approximate: alignment could be established only roughly. The data is still usable, but treat recording-time values as having wider uncertainty, and note the limitation if you rely on them.
  • Unavailable: no reliable alignment could be established. Recording-time values are left blank; analyze the behavioral data on its own and exclude the session from video-aligned analyses.

You can filter on the Approximate sync label to review or exclude affected sessions.

What accuracy to expect

When synchronization is precise, a behavioral event can be located on the video to within roughly one video frame, because the recording is delivered at a fixed frame rate. That is the practical limit of placing an event on the recorded timeline; it is separate from the reaction-time precision described above, which is measured from the browser's high-resolution clock and does not depend on the recording.

When synchronization is approximate, the uncertainty is larger and is not bounded by the frame rate; reserve frame-accurate claims for sessions marked precise.

For analysis-level reporting and the recording-time fields in your export, see Data and exports.

Absolute wall-clock times

Recording time tells you where an event sits within a session, but it does not tell you when the session happened on a global clock. For that, the platform adds an optional absolute layer called precise_times. It is additive: the legacy session timestamps are untouched, and recording time keeps working exactly as described above. The wall-clock layer answers a different question, namely "what UTC instant does the camera's first frame correspond to," so you can place a session, or any event inside it, on the same timeline as data collected by an external instrument.

How the absolute clock is anchored

A browser's own system clock is not trustworthy for research: it can be wrong by minutes, and it can jump or sleep mid-session. So instead of reading the local clock, the platform performs a single calibrated offset read against the server clock once, near the consent moment. It records the round trip of that one read and treats the server commit as the true instant. From the measured offset it can convert the browser's high-resolution timeline into UTC.

That one calibration yields two values stored on the participation and in log.json:

  • clock_offset_ms: the measured difference between the server clock and the browser timeline. Used to convert high-resolution times to UTC. It is null (never 0) when the read could not be completed.
  • clock_offset_error_ms: the worst-case half of the read's round trip, rounded up. This is the uncertainty of the calibration itself.

The three precise times

precise_times reports up to three anchored instants. Two are stored, and the third is derived in the export:

  • participation_start: the UTC instant the participation page opened.
  • participation_end: the UTC instant the participation finished.
  • record_time_0: the UTC instant of the camera's first frame, that is, the instant where recording time equals 0. This one is not stored on the participation; it is reconstructed in the export's metadata.json because computing it needs the recording's own start offset, which is known only at export time.

Each precise time is an object with the same shape:

  • epoch_ms: the instant as UTC milliseconds.
  • iso: the same instant as an ISO-8601 string in UTC (it ends with Z).
  • error_ms: the uncertainty bound in milliseconds, or null when no bound applies.
  • bounded: true when the value carries a trustworthy error bound, false otherwise.
  • clock_source: server_offset when the calibrated offset was used, or local_fallback when it was not.
  • recording_sync_source: present on record_time_0 only: chirp_anchored or approximate_sync.
  • clock_anomaly: present (and true) only when a clock step or sleep was detected; see below.

record_time_0 is the anchor you use to convert any recording-time value into a wall-clock instant: wall_clock_ms = record_time_0.epoch_ms + recording_ms. Because recording time 0 is the camera's first frame, this single relationship reconstructs the UTC time of every marker, response, or transition on the recorded timeline.

What error_ms means: calibration, not drift

This is the single most important point on this page. error_ms is calibration uncertainty: it describes the round trip of the one offset read taken near consent. It is not a measure of how much the clock drifted over the session.

The offset is measured once and then assumed stable for the rest of the session. That means participation_start.error_ms does not somehow "cover" the whole interval from page-open to session-end. It tells you how tightly that one calibration pinned the clock at the moment it was taken, nothing more. If you need to reason about drift over a long session, treat the offset as a single calibration point, not as a continuously maintained bound.

The honest consequence: if the clock actually stepped or slept during the session, the calibration is no longer valid, and the platform says so by marking the session as approximate rather than pretending the bound still holds (see the clock-anomaly case below).

How this differs from the legacy session timestamps

Exports and the participations list also carry the legacy session_started_at and session_ended_at values. These come from the browser's local machine clock and have no error bound. They can be off by whatever the participant's clock is off by, and nothing flags it.

precise_times is different in kind: it is server-anchored and carries an explicit, honest uncertainty. Never mistake one clock for the other. If you are aligning to an external instrument or reporting absolute times, use precise_times; treat the legacy timestamps only as a rough, unbounded local-clock reference.

Durations are not recomputed from the precise epochs: recomputing a duration from two precise times would double-count the offset. session_duration_ms is a high-resolution wall-clock delta and stays offset-invariant. recording_duration_ms is the end of the last task expressed on the recording clock (0 = the camera's first frame), so it is measured from that single frame-zero anchor; this one-time re-zero to the camera frame is not a recompute from two precise epochs and does not double-count the offset.

When the clock is only approximate

A precise time is reported with bounded: false (and error_ms: null) in three situations. The platform never invents a fake or zero bound; an honest "approximate" is always preferred to a false "precise."

  • Local fallback: the offset read failed or the device was offline at consent. clock_source is local_fallback, clock_offset_ms is null, and the times fall back to the local clock with no bound.
  • Clock anomaly: the platform checks clock stability at three anchors (page init, consent, finalize) by comparing how much the wall clock advanced against how much the high-resolution clock advanced. If they diverge by more than the tolerance (a fixed CLOCK_STEP_TOLERANCE_MS of 250 ms), the clock stepped or slept. clock_anomaly is set, and the whole session becomes unbounded. This is exactly the case the calibration-not-drift point warns about: a large step invalidates the single offset read.
  • Approximate sync: affects record_time_0 only. When there is no usable recording start offset (no chirp anchor, or the offset is unknown or 0), record_time_0 is emitted with recording_sync_source: approximate_sync and bounded: false. The participation start and end are unaffected and can still be precise.

The two quality dimensions are independent. The clock offset (clock_source) and the recording sync (recording_sync_source) are measured separately, so a session can have a solid clock but only approximate recording sync, or vice versa. They combine only for record_time_0:

  • For participation_start and participation_end (no sync dimension): bounded is true when clock_source is server_offset and there is no clock_anomaly.
  • For record_time_0: bounded is true when clock_source is server_offset and recording_sync_source is chirp_anchored and there is no clock_anomaly.

When record_time_0 is bounded, its error_ms is clock_offset_error_ms + RECORDING_SYNC_BOUND_MS. RECORDING_SYNC_BOUND_MS is a conservative policy constant of 5 ms, not a per-session measured value. Its physical floor is the chirp cross-correlation precision (about 0.67 ms); the 5 ms figure is a deliberate margin over that floor. Treat it as a policy constant in any reporting.

Aligning external or hardware data

record_time_0.epoch_ms + recording_ms gives you a wall-clock label for any point on the recorded timeline, which is what you want for coarse alignment: lining a session up against logs, sensors, or instruments to within tens of milliseconds.

For sub-millisecond external or hardware synchronization, do not use the wall clock. The wall clock is bounded by the offset read's round trip (tens of milliseconds) plus the external device's own clock error, so it cannot deliver sub-millisecond alignment. Instead, use the in-band chirp already present in the recording's audio: a second device that captures the same audio cross-correlates the chirp and aligns directly to recording time, sub-millisecond, with no dependence on any wall clock. Think of record_time_0 as the coarse wall-clock label of the recorded timeline, and the chirp as the precise synchronization mechanism.

How precise times appear in the interface

On the participations list, the precise start and end render in place of the legacy local-clock timestamps, with a tooltip that shows the +/- bound. The tooltip wording frames that bound as calibration uncertainty measured near consent, not as session-long drift. When a value is not bounded (either a local fallback or a clock anomaly), an amber Approximate clock badge appears. Participations recorded before this feature existed simply fall back to the legacy local-clock string, with no badge.

Quality summary in exported data

When you export a participation, the quality summary includes:

  • Device gating results: What the participant's device supported and whether they passed the required checks.
  • Screen metrics: The initial snapshot and any changes during the session.
  • Interaction telemetry: The full event stream with timestamps relative to the session reference point.

Best practices

  • Enable interaction telemetry for exploratory studies where you want to understand participant behavior beyond task responses (e.g., hesitation patterns, tab-switching frequency).
  • Report timing methodology in your manuscript. State that reaction times were measured using the browser's high-resolution performance clock. Note that all participants met the platform's device requirements (camera, microphone, minimum 768px viewport width). If you applied additional exclusion criteria during analysis, describe them clearly.