← Back to Blog

How to Filter and Search Thousands of HTTP Requests on macOS

· 8 min read

Leave a proxy running against a real app for a minute and the traffic list fills up. A single screen load can fire dozens of requests; a background sync, a polling endpoint, and a chatty SDK together push the count into the hundreds or thousands. Somewhere in that stream is the one call you actually care about — the checkout request that returned 500, the auth handshake missing a header, the endpoint that returned the wrong JSON — and scrolling for it by eye is a waste of the debugging session.

The outcome of this guide is a short list. Instead of scanning every row, you narrow the capture down to the exact flows that match a host, a method, a status, a path, or a value buried inside a JSON body — and then inspect, replay, or diff just those. Rockxy does this on macOS with multi-field filters, saved filters you reuse across sessions, and a JSONPath filter that reaches into decrypted request and response bodies.

Why a busy capture hides the request you want

A traffic list is chronological by default. That is the wrong ordering for debugging, because the request you are chasing rarely arrives last — it is interleaved with everything else the app is doing. Three things make the noise worse:

  1. Volume. Modern apps are talkative. Analytics beacons, feature-flag polls, image and font fetches, and retry storms all land in the same list as your one meaningful call.
  2. Similar-looking rows. A dozen requests to the same host and path can differ only by a query parameter, a status code, or one field in the body. The list view cannot show all of that at a glance.
  3. Timing. The failing request may have fired seconds ago and scrolled off screen while the app kept working.

Filtering fixes all three at once. A filter is a question you ask the capture — "show me only the POSTs to the API host that returned a 4xx" — and the list answers by hiding everything that does not match. Keep in mind one thing that matters later: a filter hides rows, it does not stop capture. Everything is still recorded; you are only changing what you see.

What you will need

  • Rockxy on macOS 14 (Sonoma) or later. It is a native app; download it from the Rockxy download page.
  • A capture with real traffic in it — run your app, a browser, or a script against Rockxy until the list has a few hundred rows to work against.
  • For JSON-body matching: the relevant flows must be readable. Plain HTTP is readable as-is; HTTPS bodies must be inside Rockxy's SSL Proxying scope with certificate trust in place, otherwise the body stays encrypted and there is nothing for a JSONPath filter to match.

Step 1 — Narrow by the obvious fields first

Start with the coarse cut. Most searches begin with one or two attributes you already know: the host you are debugging, the HTTP method, a status code, or a fragment of the path. Rockxy's filter bar matches across these request fields, so a single expression can drop a thousand-row list to the handful that share a host or a status class.

Work from broad to narrow. Filter to the API host first, then add the method, then the status. Each condition you add is another row of noise removed. The exact operator syntax — how you combine fields, and the keyword for each attribute — is shown inline in Rockxy's filter bar as you type; the current set is documented in the filters and search reference. Follow what the UI offers rather than guessing at a syntax.

What you should see in Rockxy: the row count drops immediately as each condition takes effect. If you filter to one host and a POST method, only the POSTs to that host remain visible; everything else is hidden, not deleted. If the list does not shrink, the filter did not match anything — loosen a condition and confirm the traffic you expect is actually present.

Step 2 — Save a filter you keep reusing

Some filters are worth keeping. If you debug the same API every day, the expression that isolates its error responses is something you will re-type dozens of times. Rockxy lets you save a filter and recall it later, so the same cut is one click away in the next session instead of a re-typed query.

Save the filters that map to a recurring task: "errors on the payments host," "auth-related requests," "everything hitting the GraphQL endpoint." A saved filter turns a debugging routine into a named view. Reach for it whenever you reopen the app to chase the same class of problem.

Step 3 — Match on a value inside the JSON body

Sometimes the field you are searching by is not the host or the status — it is a value inside the payload. You want the request whose body carried a specific userId, or the response that came back with a particular error code in a nested field. The URL and headers look identical across all of them; only the body differs.

This is what a JSONPath filter is for. Instead of matching request metadata, it evaluates a JSONPath expression against the decrypted JSON body of each flow and keeps the ones where the path resolves to the value you are after. That lets you isolate a single request out of many that are otherwise indistinguishable — the one order with a given ID, the one response carrying a specific flag.

Rockxy's filter bar accepts a JSONPath expression for this content-level matching; the accepted expression form and where to enter it are shown in the filters and search docs. One requirement is worth repeating: JSONPath matches decrypted JSON. For an HTTPS flow, that means the host must be in SSL Proxying scope with certificate trust established — otherwise the body is still ciphertext and no content filter can read it. If your JSONPath filter matches nothing on an HTTPS host, check decryption before you doubt the expression.

Step 4 — Combine filters to isolate one flow, then act on it

The real narrowing comes from stacking conditions. A host filter plus a method plus a status plus a JSONPath body match can take a thousand rows down to one. Once the list shows only the flow you were chasing, the rest of Rockxy's tools apply to it directly: open it to read the full request and response, Replay it to re-send the exact call, or Diff Compare it against another flow to see what changed between a working request and a broken one.

That is the point of filtering — not to admire a short list, but to hand a single, known flow to the next step of the investigation.

Rockxy's advanced filter and search on macOS narrowing a long request list down to the matching flows by host, method, status, and JSON content.
A busy capture narrowed to the flows that matter. Stacking a host, method, and content filter isolates one request out of thousands, ready to inspect, replay, or diff.

If it does not work

The filter hides everything, including the request you know is there. One of your conditions is too strict or has a typo. Remove conditions one at a time until the expected rows return, then re-add them and watch which one empties the list. Follow the syntax the filter bar shows as you type rather than assuming an operator.

"My traffic disappeared." A filter left active is the single most common reason a capture looks empty. The rows are hidden, not gone — clear the filter and they return. If the list is genuinely empty from the start (no traffic ever arrived), that is a routing problem, not a filter problem; the requests not showing checklist walks through why a capture stays blank.

A JSONPath filter matches nothing on an HTTPS host. The body is probably still encrypted. Confirm the host is in SSL Proxying scope and that certificate trust is set up, so the JSON is decrypted and available to match. A tunnel-only row has no readable body for a content filter to evaluate.

The count looks wrong even with no filter. Remember that filtering never stops capture — a hidden row is still being recorded. If the app produced a request during a filtered view, it is in the store; clear the filter or broaden it and the row appears.

What filters do and do not do

Filters are a view, not a capture control. They change which rows you see; they do not decide what Rockxy records, and they do not reduce what is stored. That distinction is worth internalizing because it cuts both ways: a filter can never make you miss a request that was captured, and it can never trim a capture down on disk. If you want to control what enters the store in the first place, that is a different mechanism from filtering the view.

JSONPath and other content filters also depend on readable bodies. They operate on decrypted JSON, so their reach is bounded by your SSL Proxying scope and certificate trust. Metadata filters — host, method, status, path — work regardless, because that information is available even for a tunnel.

Next steps

The workflow is short: cut by the obvious fields first, save the filters you reuse, reach into JSON bodies with JSONPath when metadata is not enough, and stack conditions until one flow remains. Then inspect, replay, or diff that flow instead of scrolling a thousand rows.

From here, apply it to a specific protocol with the GraphQL over HTTP guide, where filtering by operation name and payload field is the whole game. If your list is empty rather than crowded, start with the requests not showing checklist or the localhost capture guide. The full operator reference lives in the filters and search docs, and you can grab the app on the download page.

Rockxy — native macOS proxy debugger

Try Rockxy — Free and Open Source

A native macOS proxy debugger for HTTP, HTTPS, WebSocket, and API traffic. No cloud account. No subscription. Download the app or audit the source directly on GitHub.

Open source · AGPL-3.0 · Native macOS · No account required · Source available to audit