On this page

Last updated: April 24, 2026

SQL Query

Guara Cloud lets you run read-only SQL statements against your managed PostgreSQL and MySQL catalog services without ever exposing the database to the public internet. Queries run inside the cluster, results stream back through the platform API, and the same surface is available from both the dashboard and the CLI.

Where it works

Catalog serviceSupported
PostgreSQL
MySQL
MongoDB / Redis / NATS / others— (no SQL surface)

The service must be running and healthy. SQL access is part of the standard catalog feature set and follows the same project-membership rules as the rest of the dashboard.

Safety model

Every request runs inside an explicit read-only transaction (BEGIN READ ONLY for PostgreSQL, START TRANSACTION READ ONLY for MySQL). The platform also enforces:

LimitValue
Statement timeout30 s
Maximum query length50 KB
Maximum returned rows1 000 (server appends LIMIT)
Concurrent queries per user × service3
Result cache TTL15 s

A request can only carry one SQL statement. Compound or chained statements (SELECT 1; SELECT 2) are rejected up front. If your result hits the row cap the response carries truncated: true, and the CLI prints a yellow ⚠ result truncated line under the table.

Use it from the CLI

Two commands ship under the existing catalog topic:

guara catalog query   # execute a SQL statement
guara catalog schema  # list tables and columns

Both pick up the project + service from --project/--service, environment variables (GUARA_PROJECT, GUARA_SERVICE), or a .guara.json link file.

guara catalog query

Pass the SQL through --query, load it from a file with --file (alias -f, or - to read from stdin), or pipe it on stdin (auto-detected when stdin is non-TTY):

# Inline statement
guara catalog query --query "SELECT id, email FROM users LIMIT 10"

# From a .sql file
guara catalog query --file ./reports/active-users.sql --format csv > users.csv

# Piped from stdin (auto-detected when stdout is non-TTY)
cat ./reports/active-users.sql | guara catalog query --service my-postgres

Output formats — pick one with --format (TTY/file rendering):

--formatResult
table (default)Pretty cli-table3 table with a {rows} · {ms} footer (plus · cached @ {time} when the result was served from cache).
csvRFC-4180 escaped CSV (quotes around values that contain commas, quotes, or newlines). Cells starting with =, +, -, @, tab, or carriage return are prefixed with ' to neutralise spreadsheet formula injection — disable with --no-csv-safe if you need raw fidelity.
tsvTab-separated values. Tabs and newlines inside cells are replaced with spaces so each row stays on one line. Same --no-csv-safe opt-out applies.

Global output flags (apply regardless of --format):

FlagResult
--jsonFull SqlQueryResponse envelope — columns, rows, rowCount, truncated, executionTimeMs, fromCache, cachedAt. Bypasses --format. Raw control bytes from cells are preserved here so machine consumers see the truth.
--quietThe integer row count on a single line (handy for shell conditionals). Bypasses --format.

ANSI/OSC control bytes inside string cells are stripped from the table/CSV/TSV renderings so a malicious value cannot move the cursor, spoof the terminal title, or mask hyperlinks. --json is the escape hatch when you need the original bytes.

guara catalog schema

guara catalog schema                       # list every table and its columns
guara catalog schema --filter users        # narrow the table list (case-insensitive)
guara catalog schema --json | jq .         # full machine-readable schema
guara catalog schema --quiet               # one table name per line

Each table renders as its own block with a small column table (Column, Type, Constraint).

Error codes

The CLI maps the platform error codes to actionable hints. Each surfaces as a one-line Hint: underneath the red message and uses the standard CLI exit codes (1 for failure, 2 for auth).

CodeWhenWhat to do
SQL_QUERY_SERVICE_NOT_CAPABLEService is not PostgreSQL/MySQLUse a database service that lists sql-query in its capabilities.
SQL_QUERY_SERVICE_NOT_RUNNINGService is not running + healthyWait for the service to stabilise (guara services info).
SQL_QUERY_TOO_LONGQuery exceeds 50 KBSplit the query, or load a smaller --file.
SQL_QUERY_TIMEOUTQuery hit the 30 s statement timeoutAdd a LIMIT, narrow the filter, or pre-aggregate.
SQL_QUERY_EXECUTION_FAILEDDatabase rejected the SQLRe-run with --json to read the full payload.
SQL_QUERY_CONNECTION_FAILEDCould not reach the databaseService may be restarting — retry shortly.
SQL_QUERY_SCHEMA_UNAVAILABLESchema introspection failedService may be unhealthy — check status and retry.
SQL_QUERY_MULTI_STATEMENTMore than one statement in the bodySend statements one at a time.
SQL_QUERY_CONCURRENCY_EXCEEDEDThree queries already in flight on this serviceWait for one to finish, or cancel it, then retry.

Use it from the dashboard

The same surface lives on every PostgreSQL and MySQL service detail page under the SQL Query tab: a CodeMirror editor, a virtualised result grid, a schema browser on the side, and locally-persisted draft + history. Both the dashboard and the CLI talk to the same backend endpoints, so a query you ran from the CLI is subject to the same limits and audit trail (catalog.sql_query and catalog.sql_schema).