Install
$ agentstack add skill-estuary-agent-skills-capture-postgres-create ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Create PostgreSQL Capture
Create a PostgreSQL CDC capture that continuously streams changes from Postgres tables into Estuary collections.
Applies to: source-postgres, source-amazon-aurora-postgres, source-amazon-rds-postgres, source-google-cloud-sql-postgres, source-supabase-postgres, source-neon-postgres
Step 0: Load Connector Documentation
Before proceeding, fetch the official connector docs for prerequisites, config reference, and cloud-specific setup.
Always load the main page: https://docs.estuary.dev/reference/Connectors/capture-connectors/PostgreSQL/
Then load the variant subpage based on the user's Postgres type:
| Variant | Docs URL | |---------|----------| | Self-hosted / Vanilla | Main page covers this | | Amazon Aurora | Main page covers this | | Azure Database | Main page covers this | | Amazon RDS | https://docs.estuary.dev/reference/Connectors/capture-connectors/PostgreSQL/amazon-rds-postgres/ | | Google Cloud SQL | https://docs.estuary.dev/reference/Connectors/capture-connectors/PostgreSQL/google-cloud-sql-postgres/ | | Supabase | https://docs.estuary.dev/reference/Connectors/capture-connectors/PostgreSQL/Supabase/ | | Neon | https://docs.estuary.dev/reference/Connectors/capture-connectors/PostgreSQL/neon-postgres/ |
Use WebFetch to load these pages. Together they cover:
- Prerequisites (WAL level, user creation, publication setup, watermarks table)
- Full config property reference
- Cloud-specific setup instructions
- SSH tunnel configuration
- Network access / IP allowlisting
This skill provides the flowctl workflow and troubleshooting that docs don't cover.
Step 1: Gather Requirements
Before writing any YAML, ask the user:
- Postgres variant? — Vanilla, Amazon RDS, Aurora, Google Cloud SQL, Supabase, Neon
- Network path? — Direct connection (cloud-hosted with IP allowlist), SSH tunnel (private network/on-prem), Private Link (AWS/Azure/GCP), or ngrok (local dev)
- Non-default data plane? — Most users use the default. Ask if they need a non-default data plane.
- Tables to capture? — All standard tables in the publication is the default. A specific subset, partitioned tables (must capture child partitions, not the parent), views (require batch connector instead of CDC), or tables not yet in the publication all require additional configuration.
- History mode? — Standard CDC (
false) or full event history (true)
Step 2: Find the Correct Connector Version
Always use the latest numbered version tag. Query the connector registry to find it:
# For standard Postgres
flowctl raw get --table connector_tags \
--query 'documentation_url=eq.https://go.estuary.dev/source-postgres' \
--query 'select=image_tag,documentation_url' \
--output yaml
To find any Postgres variant version:
flowctl raw get --table connector_tags \
--query 'documentation_url=ilike.**' \
--query 'select=image_tag,documentation_url' \
--output yaml
Choose the connector image based on the user's Postgres variant: | Variant | Connector Image | |---------|----------------| | Vanilla / self-hosted | ghcr.io/estuary/source-postgres | | Amazon RDS | ghcr.io/estuary/source-amazon-rds-postgres | | Amazon Aurora | ghcr.io/estuary/source-amazon-aurora-postgres | | Google Cloud SQL | ghcr.io/estuary/source-google-cloud-sql-postgres | | Supabase | ghcr.io/estuary/source-supabase-postgres | | Neon | ghcr.io/estuary/source-neon-postgres |
Step 3: Help User Complete Prerequisites
Walk the user through the prerequisites from the docs page loaded in Step 0. Key items:
- Logical replication —
SHOW wal_level;must returnlogical - WAL retention safety — Recommend setting
max_slot_wal_keep_size(50GB is a good starting point, more for high-change-rate databases). Without this, Postgres retains unbounded WAL if the capture ever stalls, which can fill the disk and crash the database. The connector does not check this — it's a safety net for the source database, not a replication prerequisite. - Capture user — needs REPLICATION permission and SELECT access
- Publication —
CREATE PUBLICATION flow_publication FOR ALL TABLES; - Watermarks table — recommended for backfill accuracy
If the user is on a managed service (RDS, Cloud SQL, Supabase), refer to the cloud-specific section in the docs.
Step 4: Create the Capture Spec File
Build flow.yaml using the config reference from the docs. Minimal required config:
captures:
//source-postgres:
endpoint:
connector:
image: ghcr.io/estuary/source-postgres:
config:
address: ":"
database: ""
user: ""
credentials:
auth_type: "UserPassword"
password: ""
historyMode: false
bindings: []
For SSH tunnel, add networkTunnel.sshForwarding block — see docs for full config.
For AWS IAM or GCP IAM auth, set credentials.auth_type accordingly — see docs for required fields.
Step 5: Discover Tables
flowctl discover --source flow.yaml
Note: The first discover attempt occasionally fails with a generic error. If this happens, simply retry — it typically succeeds on the second attempt.
What this does:
- Connects to the database
- Discovers all tables in the publication
- Generates JSON schemas from table structures
- Updates
flow.yamlwith bindings - Creates SOPS-encrypted config file
Generated file structure:
flow.yaml # Updated with bindings
source-postgres.config.yaml # SOPS-encrypted credentials
/
flow.yaml # Import file
/
flow.yaml # Collection definitions
public/
.write.schema.yaml # Write schema per table
.read.schema.yaml # Read schema per table
Step 6: Review and Customize Bindings
After discovery, review the generated bindings in flow.yaml:
- Remove unwanted tables — Delete the binding entry
- Rename target collections — Change the
targetfield
Step 7: Publish
flowctl catalog publish --source flow.yaml --auto-approve
The --auto-approve flag is required for non-interactive use.
Step 8: Verify
# Check status (expect PENDING → Backfilling → OK: Streaming CDC Events)
flowctl catalog status //source-postgres
# View recent logs
flowctl logs --task //source-postgres --since 5m | jq -c '{ts, message}'
# Read captured data
flowctl collections read --collection //public/ --uncommitted | head -20
Status progression:
WARNING: waiting for task shards to be ready(PENDING) — normal for ~30 secondsBackfilling Tables (N tables backfilling)— initial data syncOK: Streaming CDC Events— capture is running normally
Step 9: Test Real-Time CDC
Insert a row in the source database and verify it appears in the collection within seconds:
flowctl collections read --collection //public/ --uncommitted | \
jq 'select(. == "")'
Troubleshooting
"no connector tag found for image"
Cause: Wrong image tag (e.g., :dev)
Fix: Query connector_tags for the correct version (see Step 2).
"Config failed schema validation"
Cause: Config structure is wrong. Common mistakes:
- Password at root level instead of
credentials.password - Missing
credentials.auth_type: "UserPassword" - Missing
historyMode: false
"connection refused" or timeout
Cause: Database not reachable from Estuary cloud
Fix:
- Verify firewall allows Estuary IPs (see docs for current list)
- Use SSH tunnel for private networks
- For local dev:
ngrok tcp 5432
"permission denied for replication"
Cause: User lacks REPLICATION permission
Fix:
ALTER USER flow_capture WITH REPLICATION;
GRANT pg_read_all_data TO flow_capture; -- Postgres 14+
"publication does not exist"
Cause: Publication not created or wrong name in advanced config
Fix:
CREATE PUBLICATION flow_publication FOR ALL TABLES;
No tables discovered
Cause: Publication exists but has no tables, or the capture user lacks permissions to see them. This is a very common support issue.
Debug:
-- Check publication has tables (run as admin)
SELECT p.pubname, pt.schemaname, pt.tablename
FROM pg_publication p
JOIN pg_publication_tables pt ON p.oid = pt.pubid
ORDER BY p.pubname, pt.schemaname, pt.tablename;
-- Check capture user can see tables (run as capture user)
SELECT table_schema, table_name, table_type
FROM information_schema.tables
WHERE table_schema NOT IN ('pg_catalog', 'pg_internal', 'information_schema');
If the publication is empty, add tables or recreate with FOR ALL TABLES. If the capture user sees fewer tables than admin, it's a permissions/schema visibility issue.
Capture stuck in PENDING
Wait 30-60 seconds — this is normal during shard assignment. If still stuck:
flowctl logs --task //source-postgres --since 5m | jq 'select(.level == "error" or .level == "warn")'
Watermarks table warning
Warning: relation "public.flow_watermarks" does not exist
Impact: Capture still works, but backfill accuracy may be affected.
Fix: Create the watermarks table per docs prerequisites.
Discover fails on first attempt
This is a known intermittent issue. Simply retry flowctl discover --source flow.yaml — it typically succeeds on the second attempt.
Related Skills
connector-disable-enable— Pause/restart existing capturesconnector-delete-recreate— Nuclear option for stuck capturesestuary-logs— Deep log analysisestuary-catalog-status— Status checking
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: estuary
- Source: estuary/agent-skills
- License: Apache-2.0
- Homepage: https://estuary.dev
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.