Search
Use the Search page to find recordings, events, and sessions across every device in your organization.
How search works
Run a query from the Search page to find recordings, events, and sessions across your organization. Each query combines one or more conditions on fields like device, time range, event type, topic, or metadata.
- List view: Results in a sortable table.
- Timeline view: Results plotted across time.
Open a result to visualize the matching data.
For self-hosted Primary Sites, scans of recording contents run on the query service in your Primary Site, so message contents and attachments never leave your infrastructure. See the Primary Site FAQ for more detail.
Building a query
A query is made up of one or more condition groups. Conditions within a group are joined with AND, and groups are combined with OR. Each condition picks a field (such as device ID, event type, or a metadata key), an operator, and a value.
Click "Run" to execute the query. Switch between the "List" and "Timeline" views to see results in a table or plotted across time.
Searchable fields
You can search across several categories of fields:
| Category | Examples | Description |
|---|---|---|
| Recording | ID, Key, Device ID, Device Name, Path | Built-in fields on every recording |
| Recording metadata | Any key from your recording metadata | String values attached to recordings |
| Event | ID, Event Type, Device ID | Built-in fields on events |
| Event properties | Custom properties defined for events | User-defined properties |
| Event metadata | Any key from your event metadata | String key-value pairs on events |
| Device | ID, Name, Enabled | Built-in fields on devices |
| Device properties | Custom properties defined for devices | User-defined properties |
| Session | ID, Key, Device ID | Built-in fields on sessions |
| Session properties | Custom properties defined for sessions | User-defined properties |
| Message | Topic and field path (for example, /gps.latitude) | Values decoded from message contents in your recordings |
Operators
The operators available for a condition depend on the field's data type:
| Data type | Operators | Used by |
|---|---|---|
| String | =, ≠, like, exists | Most built-in fields, metadata keys, string message fields |
| Number | =, ≠, >, ≥, <, ≤, exists | Numeric custom properties, message fields |
| Boolean | =, ≠, exists | Boolean fields (for example, Device → Enabled), boolean message fields |
| Multi-select | has, does not have | Multi-select custom properties |
For message field conditions, the query builder infers the field's data type from the topic's schema and filters operators accordingly.
Message field search
Message field conditions let you search across the decoded contents of your recordings. Specify a topic and field path using message path syntax (for example, /gps.latitude, /diagnostics.status).
Supported field types
The query engine can search message fields that resolve to a primitive scalar leaf or an array of primitives. Searchable message fields resolve to one of:
- Numeric — integers and floats of any width (
int32,float64,uint8, etc.) - Boolean —
bool - String —
string - Arrays of the above — for example,
float64[],string[]
Unsupported field types
The following field types are not searchable. The query builder's autocomplete only suggests supported leaf fields, so these types generally do not appear as suggestions:
- Nested messages — compound types like
geometry_msgs/Poseor a protobuf sub-message - Arrays of messages — lists of non-primitive types
- Maps — key-value map fields
Querying nested fields
To search a scalar value inside a nested message, use dot notation to drill down to the leaf field:
# Given a ROS message type:
# geometry_msgs/PoseStamped
# std_msgs/Header header
# geometry_msgs/Pose pose
# geometry_msgs/Point position
# float64 x
# float64 y
# float64 z
# ✅ Valid — targets a scalar leaf:
/robot_pose.pose.position.x
# ❌ Invalid — targets a nested message, not a scalar:
/robot_pose.pose
/robot_pose.pose.position
Arrays and repeated fields
Arrays of primitive scalars (float64[], repeated double in protobuf, sequence<double> in IDL) are searchable. You can select the bare array path (for example, /topic.values) or use a slice (/topic.values[:]) — the query engine matches if any element in the array satisfies the condition.
You can also use a slice to reach scalar leaves inside an array of messages (for example, /topic.items[:].value matches if any element's value satisfies the condition). You cannot condition on an array of messages itself, only on scalar leaves within it.
Supported schema encodings
Message predicates work with all schema encodings supported by Foxglove:
| Message encoding | Schema encodings |
|---|---|
protobuf | protobuf |
ros1 | ros1msg |
cdr (ROS 2) | ros2msg, ros2idl, omgidl |
json | jsonschema |
flatbuffer | flatbuffer |
Making queries faster
Queries run faster when they scan fewer files. To speed up a slow search:
- Filter by device ID or device name so Foxglove only searches the devices you need.
- Reduce the time range.
Visualizing a match
From the Search page, click a row in the List view or a selection in the Timeline view to open its recording for visualization with your query attached.
Your matches appear above the playback bar, similar to events. Hover over a match to see its details.


