How do I let an AI SRE look at Postgres tables when investigating failed deploys?
Tares reads a Postgres table incrementally with the postgres connector, so each new or changed row becomes an event in the timeline your AI SRE works from. You give it a connection URL, a table and a cursor column. For data behind an API instead of a database, the http_poll connector reads any JSON endpoint on a schedule.
How it works
The postgres connector polls a table and stores one event per new or changed row. It tracks a cursor column, a column that only ever grows, such as an autoincrement id (catches inserts) or updated_at (catches inserts and updates). Each poll reads the rows past the last cursor value, so Tares does not re-read the whole table.
- Entity key: an entity column becomes the key through a label marked
primary. - Columns: you choose which columns to pull. Empty means every column. The cursor, key and time columns are always included.
- Event time:
time_columnsets the event time. By default it is the cursor if that is a timestamp, otherwise the ingest time. - Row summary:
text_templateis an optional template over the row for a one-line summary. - Config labels:
databaseandtableare available as label fields, whichever columns you pull. - Secret handling: the
dsnis stored as a secret. It is redacted in the API and omitted from catalog exports.
The connector supports discovery. Given the connection URL it lists the tables it can see, then reads the chosen table’s columns and proposes the cursor and labels. The result is your application’s source-of-truth data in the timeline. See the Postgres table connector page for every field.
If the data you want sits behind an API, the HTTP API (poll) connector polls a JSON endpoint and stores one event per item. Nested values are reachable by dotted name in labels, trigger filters and trigger conditions.
Set it up
- Make sure a Postgres is reachable from the Tares host. The driver ships with Tares, so there is nothing extra to install.
- Add the source in one of two ways:
- Ask a connected agent to ingest the table from your connection URL. It runs discovery, a dry run that fetches sample rows, and then creates the source.
- In the UI, go to Sources → Add source → Postgres, enter the Connection URL (
dsn) and press Discover. Pick a table. Tares proposes the cursor, entity key and labels from its columns. Choose which columns to pull, then save.
- Or declare the source yourself, or send the same object with
POST /api/sources:
- name: orders
connector: postgres
poll: 10s
config:
dsn: postgresql://user:pass@host:5432/appdb
table: orders
cursor_column: updated_at
columns: id,tenant_id,status,amount,updated_at # empty = every column
labels:
- { name: tenant_id, field: tenant_id, primary: true }
- { name: status, field: status }- Pick the table you want in the timeline, then choose a
cursor_columnthat only grows. Useupdated_atif you want changed rows as well as new ones. - Set
limitif you want to cap how many rows each poll fetches. - Verify. Open the source. Recent events shows rows on the next poll. Fields reports each column’s coverage, which confirms the key column is reliably present.
To read an endpoint instead, add an HTTP API (poll) source with the URL. Press Discover and Tares calls the API once, shows the reply and fills in what becomes an event. If the API needs a credential, it travels in one header. The credential is stored as a secret and never returned by the API.
What you get
- Rows from your Postgres table arrive as events in the Tares timeline, one per new or changed row, so your application’s own data sits in the timeline your agent reads.
- The cursor keeps each poll incremental.
- A primary label gives the rows an entity key, and Fields shows how reliably each column is present.
- Discovery proposes the table, cursor and labels, so you do not write the config from scratch.
- The connection URL is stored as a secret.
- With the HTTP API (poll) connector, any JSON endpoint becomes events as well. The payload is stored as received, so labels you declare later can still reach every field.
When something else fits
The postgres connector reads one table per source, driven by a cursor column. It fits tables where a column only ever grows. If the table has no such column, it is not the right path for that table.
If the data you need is exposed by an API, use the HTTP API (poll) connector. It polls any JSON endpoint, uses id_field to avoid storing the same item twice, and refuses a poll interval under 10 seconds. It also backs off on a 429 or any 5xx, and the source’s health shows when the next try happens.
If you would rather read a table directly, the Postgres connector is the simpler route. If a system can call Tares, the webhook connector is the better fit. The HTTP API (poll) connector is for APIs that Tares calls.
Related
Still stuck? Get help