How to Install CloudQuery and Run Your First Sync

Updated

CloudQuery installs as a single binary, then syncs cloud and SaaS sources into a database you already run. The whole flow is three steps: install the binary, define your sources and destination in YAML, and run the sync. It works on Linux, macOS, and Windows, and the destination can be Postgres, BigQuery, Snowflake, or S3. This guide covers each step, how to verify it worked, and where people typically get stuck.

Before you start

You need two things in place before the first sync:

  • A destination database you already operate. CloudQuery writes into Postgres, BigQuery, Snowflake, or S3 — it does not host storage for you.
  • Credentials for at least one source. CloudQuery covers 80+ cloud and SaaS sources (AWS, GCP, Azure, GitHub, Okta, and others). You'll point it at whichever you want to pull from.

Because CloudQuery is self-hosted, credentials and synced data stay on your network unless you choose otherwise. Plan for where the binary runs and where the destination lives before you install.

Step 1: Install CloudQuery

Pick the install path that matches your machine or pipeline.

Environment Command
macOS (Homebrew) brew install cloudquery/tap/cloudquery
Linux, CI, or agents curl -fsSL https://cloudquery.io/install.sh | sh
Windows or Docker See the full install options on the site

The result is a single binary on your machine. There's no server to stand up and no agent fleet to manage — the binary is the whole runtime.

Step 2: Define sources and destination in YAML

This is where you tell CloudQuery what to pull and where to put it. You write two things in YAML:

  • Sources — the cloud providers and SaaS apps you want to sync.
  • Destination — the database you already operate.

The config is version-controlled, so it can be reviewed in pull requests like any other code. That matters once more than one person owns the sync: you get a single source of truth and a history of changes instead of a pile of one-off scripts.

Step 3: Run the sync

Run it once to test, or put it on a schedule in your pipeline for ongoing syncs. Data lands in your destination database in a normalized relational shape — AWS, GCP, Azure, GitHub, Okta, and the other 80+ sources all arrive in the same schema rather than 80 different raw API formats.

Once the data is in, you query it with standard SQL. There's no proprietary query language to learn, and the same synced data can back an MCP server so agents can query your cloud estate directly.

Verify the first sync worked

After the run completes, connect to your destination database and check that tables exist and hold rows. Because everything lands in one normalized schema, you can query across sources with plain SQL — for example, joining an identity source like Okta against a cloud provider's resource tables in a single statement. If the tables are populated and a cross-source query returns results, the sync is working end to end.

Common places people get stuck

  • No destination ready. CloudQuery syncs into a database you run. If you haven't provisioned Postgres, BigQuery, Snowflake, or S3 yet, do that first.
  • Credentials scoped too narrowly. A source connection needs permission to read the resources you expect. If tables come back empty, check the credential's scope before assuming the sync failed.
  • Expecting a hosted service. CloudQuery is open-source and self-hosted. You own the runtime and the data path.
  • Scaling by adding scripts. The failure mode CloudQuery is built to replace is gluing together a separate exporter per provider. Keep new sources in the same YAML config rather than reaching for another script.

When this approach fits

Choose CloudQuery if you want your cloud and SaaS data in a database you already operate, queried with standard SQL, with config kept in version control. It's a strong fit when you're syncing across many accounts or providers and want one tool instead of a per-provider exporter, and when you want the same data to serve as a context layer for AI agents.

If you'd rather not run or maintain the sync yourself, or you don't have a destination database to write into, this self-hosted model won't match your setup — you'd be taking on infrastructure you don't want.