Live demo · Linear + ChalkSQL

Your Linear backlog,
as SQL tables.

This demo shows ChalkSQL querying issues, projects and teams in Linear. ChalkSQL reads them as tables, turns your WHERE clause into Linear's own GraphQL filter, and joins the open issues with your helpdesk or warehouse in the same query.

Connect a SQL filter to the request Linear receives

The fictional workspace makes both the source request and the returned rows inspectable.

Try this experiment · expected results

  1. 1Run the default query

    Choose Urgent work in flight and inspect the SQL predicates and request panel.

    Expected: Team, priority, and workflow filters appear in the request sent to the example Linear API.

  2. 2Compare the returned rows

    Read the result, then choose Bugs by revenue at stake.

    Expected: The join combines Linear issues with support data; inspect which work stays in ChalkSQL.

Query result

Results appear here.

ChalkSQL

The team, an IN list on priority and the workflow state become one IssueFilter, so Linear only returns the five matching issues.

What Linear received

Run a query to see the requests.

The workspace belongs to Fernhill, a fictional analytics company. Its teams, projects and issues are served by a stand-in for Linear's GraphQL API (the issues, projects and teams queries, their filters and cursor pagination), so the exact requests are visible. The connector does not depend on the stand-in: point it at api.linear.app with an API key and it reads a real workspace. ChalkSQL and the connector run live on a Chalk scaling group.

Built on Chalk

ChalkSQL reads the source through its connector, pushes supported work to that source, and runs the remaining SQL over the returned rows.

  • Issues become a table

    Register a Linear API key and linear.issues, linear.projects and linear.teams appear in the catalog, with state, priority, estimate, assignee, labels, project and dates as typed columns.

  • WHERE becomes an IssueFilter

    Before the scan runs, the optimizer offers it the query's predicates. The ones Linear can evaluate go into the GraphQL query's filter variable, so Linear only returns the issues you asked for.

  • SQL does the rest

    Joins with your helpdesk or warehouse, aggregates, date math and anything Linear cannot evaluate run in ChalkSQL. Results stream in a page at a time by following Linear's cursors.

  • Use ordinary SQL on returned rows

    ChalkSQL applies the remaining joins, grouping, and sorting to the rows returned by the connector. The request panel shows which filters the source received.

Deploy your own

A Linear source in one catalog call

The connector is a ChalkSQL schema provider. Each table is a pushdown-capable batch function over Linear's GraphQL API that translates SQL predicates into the query's filter variable and pages with first and after.

Register it once and Linear is queryable from anywhere ChalkSQL runs, joined with anything else in the catalog.

from linear_chalksql import LinearClient, LinearSchemaProvider, RequestLog, register_client

register_client(
    "workspace",
    LinearClient("https://api.linear.app/graphql", api_key=LINEAR_API_KEY, log=RequestLog()),
)

# linear.issues, linear.projects and linear.teams.
catalog.register_schema_provider("linear", LinearSchemaProvider("workspace"))
Implementation details

How the example works

  • Issues become a table

    Register a Linear API key and linear.issues, linear.projects and linear.teams appear in the catalog, with state, priority, estimate, assignee, labels, project and dates as typed columns.

  • WHERE becomes an IssueFilter

    Before the scan runs, the optimizer offers it the query's predicates. The ones Linear can evaluate go into the GraphQL query's filter variable, so Linear only returns the issues you asked for.

  • SQL does the rest

    Joins with your helpdesk or warehouse, aggregates, date math and anything Linear cannot evaluate run in ChalkSQL. Results stream in a page at a time by following Linear's cursors.

SQL behavior and pushdown rules

  • Numbers and dates

    =, <, <=, > and >= on priority, estimate, due_date, created_at and completed_at become Linear's eq, lt, lte, gt and gte. IN becomes Linear's in. Exact, so ChalkSQL drops them.

  • Text

    = and LIKE 'x%', '%x' or '%x%' on a title become eq, startsWith, endsWith and contains. Linear's string comparators are case-sensitive, like SQL's, so these are exact too.

  • Relations

    state, team, assignee and project become nested filters such as { state: { type: { eq } } }. IS NULL and IS NOT NULL become { assignee: { null: true } }.

  • Labels

    contains(labels, 'bug') becomes { labels: { some: { name: { eq: 'bug' } } } }, matched against the issue's label set.

  • <> and NOT IN

    These become neq and nin to narrow the scan, but SQL drops NULLs and an API may keep them, so ChalkSQL re-checks the rows that come back.

  • LIMIT and paging

    A LIMIT with no ORDER BY becomes first, and the scan stops once it has enough rows. Otherwise it follows endCursor, 100 issues per page.

Query the tools your team already uses

Linear, Notion, your warehouse and your databases in one SQL query. Talk to an engineer about the sources you want to join.