Filter and search the host list
Filter and search the host list
The Hosts page lists every endpoint that has ever enrolled, ordered by enrollment time (newest first). In a tenant with thousands of hosts you rarely want the full list — you want this specific machine, or every Windows server, or everything that’s stale right now. The page provides two composable controls for that: a server-side search box and a client-side status filter.
What you get
- A search input at the top of the page that filters the host list
against four columns simultaneously:
hostname,ip_address,os_name,os_version. Case-insensitive substring match (ILIKE in SQL terms). Backslashes, percent signs, and underscores in your query are escaped automatically so a search forhost_01matches the literal hostname, not “any character then host01”. - A row of status filter buttons (All / Online / Stale / Offline)
that further filters the loaded rows in the browser. The status bucket
is computed by the agent’s last contact time:
onlineif within the configured stale-after window (10 minutes by default),stalepast that,offlinepast 24 hours. - A 250-millisecond debounce on the search input: typing fast doesn’t hammer the backend, but the list still feels responsive.
- A stale-response guard on every search request. If you type
linux-prod-and then immediately backspace tolinux-prod, the earlier (slower) request’s results are dropped on arrival — the page always shows the result of your most-recent query.
How the two filters compose
The search box and status buttons stack:
| Search query | Status filter | Result |
|---|---|---|
| (empty) | All | Every host, newest first, 100 per page |
app- | All | Every host whose hostname/IP/OS contains app- |
| (empty) | Online | All hosts, then filtered to only online rows |
app- | Online | All hosts matching app-, then filtered to online only |
Two important notes on this composition:
- The search query goes to the server — it sees the whole fleet, which matters when the matching subset spans multiple pages.
- The status filter is purely client-side, applied after the page loads. If a status bucket has zero matches on the first page but plenty further back, you’ll see “no hosts” until you click Load more. This is intentional — server-side status filtering would require additional indexes and the workflow rarely needs it (operators usually look at the first 100 stale hosts and re-issue a narrower search).
Why use it
Two patterns dominate:
- “Where’s that machine?” Paste a hostname or IP from a Slack message into the search box. The matching row appears as you type. Click the hostname to open detail.
- “What’s broken right now?” Click Stale or Offline to see
every host that hasn’t checked in recently. Combine with a search like
prod-to scope to a specific environment.
How to use it
- Open the Hosts page.
- Type into the search box. Results refresh 250 ms after you stop typing. The placeholder “Search hostname, IP, OS…” is a reminder of which columns are queried.
- Click a status button to narrow further. The active filter is highlighted; click All to clear.
- The “Load more” button at the bottom of the table appears when there are more matching results than fit on the current page (cursor-based pagination; not an offset). Loading more preserves your search + status filter selection.
Troubleshooting
Search returns “No hosts matching '
- The search is a substring match on four specific columns — not on labels, tags, or any custom attribute. Use the hostname, the IP, or the OS family/version.
- The search is case-insensitive but literal-byte for non-ASCII characters. A hostname containing curly quotes won’t match a query typed with straight quotes.
- If you’re searching by hostname and the host has been recently re-enrolled with a new name, the old row still exists with the old name. Look in the Decommission column for a “(decommissioned)” marker, or expand the IOC History on the new host’s detail page to correlate.
The status filter shows zero results but I know there are stale hosts. The first page (100 hosts) is sorted by enrollment time — newest first. Stale hosts that enrolled long ago are further back. Click Load more to pull the next 100; or use a search that scopes the server-side query first, then apply the status filter.
Backslashes/wildcards in my query don’t work. That’s deliberate.
Mimir escapes \, %, and _ in your query before injecting it into
the ILIKE pattern. This protects you from accidentally constructing
queries that pull the whole fleet (a stray % in a tenant with 10k
hosts is no fun). If you genuinely need regex matching, query the
database directly — the UI is intentionally pinned to safe substring
match.
The list flashes / re-orders as I type. The 250 ms debounce means the server is only hit after you pause. If you’re typing into a fast search and the list re-renders mid-keypress, that’s the prior request’s result arriving — the stale-response guard suppresses any result older than the latest request, so the final state is always correct. Filter UX is intentionally noisy mid-type and quiet once you stop.
Permission model
The list endpoint is withAnyAuth — anyone signed in sees the whole
fleet. There is no row-level access control. If you need to scope an
operator’s visibility, deploy a separate Mimir tenant; the search
filter is for ergonomic narrowing, not authorization.