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 |
| Topic | Topic name (for example, /gps) | Recordings where the topic exists — answered from file-level metadata, no message decoding |
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 |
Topic field search
Topic field conditions answer "does this topic appear in any recording?" without decoding message contents. Use them when you only need to filter by topic presence — the query engine reads file-level metadata only, so these searches are dramatically faster than Message field searches that scan chunk bytes.
Topic fields support only the exists operator and a bare topic name (for example, /gps); field-path suffixes (/gps.latitude) belong on a Message field.
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.
Granularity
Foxglove groups matching message results into buckets to avoid noise from high-resolution topics. Each result row in the List and Timeline views represents one bucket: every message that matches your query within that bucket contributes to the same row.
The default granularity is 10 seconds. Use the Granularity dropdown next to the time range to pick a different bucket width — 250ms, 1s, 10s, 1m, 1h, or 1d. Smaller buckets give finer detail on dense data; larger buckets keep the result count manageable for sparse hits over long ranges. The chosen value is shown in the results header (e.g. Granularity: 1m).
Saving and reusing searches
Once you've run a search, you can come back to it without rebuilding the query. The Search page keeps your recent searches automatically, and lets you save the searches you want to keep or share with your team.
Open these panels from the Recent and Saved buttons at the top of the Search page.
Recent searches
Every search you run is added to your recent searches automatically. Open the Recent panel to re-run a previous search with one click.
Recent searches:
- Keep your 15 most recent searches, newest first.
- Live in your browser, so they're private to you and don't sync across devices.
- Collapse duplicates — re-running the same query moves it back to the top instead of adding another entry.
To keep a recent search around permanently, hover over it and click the bookmark icon to save it.
Saving a search
Click Save search in the Search page header to save the search you've run. You can also save a recent search from the bookmark icon in the Recent panel. Each saved search has:
- Name — required, up to 32 characters.
- Description — optional, up to 200 characters.
- Visibility — who can see it:
- Only me — the saved search is private to you.
- Everyone in this project — everyone with access to the Project can see and run it.
Saved searches belong to a Project.
Visibility is set when you save and can't be changed afterward. To change it, delete the saved search and save it again.
Running a saved search
Open the Saved panel to browse your saved searches, grouped into Personal (private to you) and Project (shared with the Project). Use the All, Personal, and Project filters or the filter box to narrow the list.
Click a saved search to load its query into the builder and run it.
Editing and deleting saved searches
Click the edit icon on a saved search to change its name or description, or to delete it. You can edit or delete a saved search if you created it, or if you're an organization admin. The visibility and the query itself can't be changed after a search is saved.
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.




