Vigilfield Docs
Query and investigate

Queries

Run an ad-hoc VFQL query, follow its state, read its results, and know the limits.

A query is one run of a VFQL query. Vigilfield keeps every run: its text, its state, its timing, and its results. Use an ad-hoc query to answer a quick question. When you want to keep the query or build on it, save it as an investigation.

This page covers the product workflow. For the language, read VFQL, the query language.

Run a query

  1. In the sidebar, open Queries.

  2. Click New Query. The Run Query page opens.

  3. Type your query in the editor. For example:

    SecurityEvents
    | where Timestamp > ago(1d)
    | where Result == 'Fail'
    | summarize count() by Account
  4. Click Run, or press Ctrl+Enter (⌘+Enter on a Mac).

The status next to the page title follows the run: Queued…, Running…, then Succeeded or Failed. When the run succeeds, its rows appear under Results.

The editor checks your query as you type

When you pause typing, the editor checks your query against the tables you can see. It underlines problems in place, such as an unknown table or a misspelled column. The check creates no run and costs nothing. The same check is available over the API as POST /queries/compile.

The editor also suggests table and column names as you type.

If the check cannot reach the server, the editor says Live checking is unavailable right now. Your query can still be run.

If you click Run on a query that does not compile, nothing runs. The problems are marked on the text, the same way.

Query states

State in the appMeaning
QueuedAccepted, and waiting to start.
RunningThe query engine is running it.
StoppingYou asked to cancel a running query. Vigilfield is waiting for the engine to confirm it stopped.
SucceededFinished. Its results are ready.
FailedThe run ended with an error. The app shows the error message.
CancelledThe run was stopped.

Over the API, these are queued, running, cancelling, succeeded, failed and cancelled.

Read the results

On the Run Query page, results show 100 rows per page. Use the page buttons under the table to move between pages.

Every run also has its own page. Open Queries and click a query to see:

  • the query text, read-only
  • its state, the time it ran, and how long the engine took
  • a preview of its results
  • for a succeeded run, a Result table link. A succeeded query writes its result to a table. From there you can browse, query or export the full result.

Over the API, read rows with GET /queries/{id}/results. Pages are zero-based. The default page size is 100 and the maximum is 1,000. A response sets has_more when at least one more row exists.

Results expire after 7 days

A query's result table is deleted 7 days after the run finishes. The run and its query text stay in your history. The app marks the run result expired and shows no rows. To get the rows again, run the query again.

Cancel a query

Cancel a query over the API with DELETE /queries/{id}. The app has no cancel button.

  • A queued query is cancelled at once.
  • A running query moves to Stopping. It becomes Cancelled only once the engine confirms the work has stopped.
  • Cancelling a query that has already finished, or is already stopping, changes nothing.

A stopped run keeps the rows it produced before it stopped, and you can still read them. Those results carry a warning: Results may be incomplete. Over the API, the results response sets results_may_be_incomplete.

Do not draw a count, a total, or a "nothing found" conclusion from a stopped run. Its rows may be only part of the answer.

Parameters

A query can declare parameters. See Parameters in the VFQL guide.

The app sends no parameter values when it runs a query. So in the app, every declared parameter needs a default:

declare query_parameters (rows: long = 100);
SecurityEvents | take rows

To supply values, submit the query over the API with POST /queries, and put the values in the parameters map, next to the text:

{
  "query": {
    "text": "declare query_parameters (account: string);\nSecurityEvents | where Account == account",
    "vfql_version": "2",
    "parameters": { "account": { "str": "root" } }
  }
}

A value is bound to the parameter. It is never pasted into the query text, so a value can change what a query matches but never what it means.

Keep a result

When a run succeeds, two buttons appear next to Run:

  • Save as Investigation creates a new investigation named "Untitled investigation". It holds one artifact, "Query 1", linked to the run you just made. The app then opens the investigation. See Investigations.
  • Save as table turns the query into a view: a table that always reflects the query's result. Give it a Table name: lowercase letters, numbers and underscores, starting with a letter. You can also name an Event time field (optional): the result column to use as the event time. Leave it blank to use ingestion time.

Your query history

The Queries page lists the runs made by you or by your teams, newest first. You can search by query text, or by rule name for runs made by a rule. The list over the API is GET /queries.

To open a run, you need query access to every table it read. That access is checked again each time you open the run or read its rows. If you lose access to one of its tables, you can no longer read that run.

System tables and the admin override

System tables, such as vf_audit_events, are for admins only. They are hidden from everyone by default, including admins.

If you are an admin, the Run Query page and investigations show a Run as admin (audited) switch. Turn it on and enter a Reason to add the system tables to that run. A reason is required, and every override is recorded in the audit trail with it.

  • The editor still underlines a system table as unknown, even with the switch on. The check uses your normal set of tables. The run is what carries the override.
  • The override is also needed to open that run or read its rows later.
  • Over the API, add as_admin=true and a non-empty reason to the query string. A request with as_admin=true and no reason is rejected.

Limits

LimitWhat happens
16 queries and exports running or queued at once, per personA new query is refused with 409 Conflict until one finishes.
Your plan's monthly query limitOnce reached, new queries are refused with 409 Conflict.
1,000 rows per results pageA larger page size is clamped to 1,000.
7 days of result retentionAfter that, the rows are gone. The run stays in your history.