Generated banner for Dsql
Generated logo for Dsql

Dsql

AWS LabsOfficialPublished by AWS Labs

  • Skill
  • Tool integration
  • Data and AI
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Build with Aurora DSQL — manage schemas, execute queries, handle migrations, diagnose query plans, diagnose cluster performance, load data, and develop applications with a serverless, distributed SQL database. Covers IAM auth, multi-tenant patterns, MySQL-to-DSQL and PostgreSQL-to-DSQL schema conversion, foreign key constraints, OCC retry patterns, ORM migration (Django/EF Core/Hibernate/Rails/SQLAlchemy), DDL operations, query plan explainability, system diagnostics via CloudWatch AAS, SQL compatibility validation, and bulk data loading. Load before answering DSQL limit or error-code questions; it has limits docs omit. Triggers on phrases like: DSQL, Aurora DSQL, distributed SQL database, serverless PostgreSQL-compatible database, migrate to DSQL, DSQL query plan, DSQL EXPLAIN ANALYZE, DSQL ENUM, DSQL foreign key, DSQL OCC retry, DSQL multi-region, DSQL JSONB, DSQL GIN index, load into DSQL, load CSV into DSQL, bulk load DSQL, aurora-dsql-loader, DSQL slow, DSQL performance, DSQL wait events, DSQL AAS.
— the description by AWS Labs

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The dsql skill provides a structured framework for interacting with Amazon Aurora DSQL. It encompasses schema management, migration strategies from MySQL and PostgreSQL, performance diagnostics, and bulk data loading. The skill integrates with MCP tools for direct database operations and provides extensive documentation on IAM authentication, multi-tenant patterns, and transaction management to ensure safe and efficient database operations.

What it does

  • Executes SQL queries and DDL operations via MCP tools.
  • Provides migration paths and type mapping for MySQL and PostgreSQL to DSQL.
  • Offers diagnostic workflows for cluster performance and query plan explainability.
  • Facilitates bulk data loading using specialized loaders.
  • Enforces best practices for IAM authentication and scoped database roles.
  • Validates SQL compatibility and provides linting for DSQL-specific constraints.

When to use it

  • When building or migrating applications to Aurora DSQL.
  • When performing schema changes or complex DDL migrations.
  • When troubleshooting performance issues or query plan inefficiencies.
  • When setting up multi-tenant database architectures.
  • When bulk loading data into a DSQL cluster.

Advantages

  • Ensures adherence to DSQL-specific transaction and concurrency limits.
  • Promotes secure access patterns through IAM and scoped roles.
  • Provides clear, phased workflows for complex tasks like performance tuning.
  • Reduces migration friction with automated linting and type mapping guidance.
  • Standardizes diagnostic reporting for query plan analysis.

Usage examples

“How do I migrate my existing PostgreSQL schema to Aurora DSQL?”
The agent will guide you through pg-migrations/type-mapping.md and schema-objects.md, providing steps to convert indexes, enums, and data types while ensuring compatibility.
“My query is running slowly on DSQL, can you help?”
The agent will initiate Workflow 9 (Query Plan Explainability) to analyze the query plan, check for full scans, and provide a structured diagnostic report.
“How do I set up a multi-tenant table in DSQL?”
The agent will provide instructions on using tenant_id in your schema design, enforcing it in WHERE clauses, and using separate transact calls for DDL.
“What are the transaction limits for DSQL?”
The agent will consult the limits-and-error-codes.md or awsknowledge tool to provide the exact limits for row modifications, data size, and duration.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/awslabs/dsql/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip dsql.zip -d .agents/skills

Documentation by AWS Labs

Amazon Aurora DSQL Skill

Aurora DSQL is a serverless, PostgreSQL-compatible distributed SQL database. This skill covers direct query execution via MCP tools, schema management, migrations, multi-tenant isolation, IAM auth, and bulk data loading via aurora-dsql-loader.


Reference Files

Load these files as needed for detailed guidance:

Core:
ReferenceWhen to LoadContains
development-guide.mdALWAYS before schema changes or DB operationsBest practices, DDL rules, transaction limits, foreign key constraints
foreign-keys.mdMUST load for foreign key operations or migrationsFK syntax, actions, validation, tenant keys
language.mdMUST load for language-specific choicesDriver selection, DSQL Connectors, connection code
access-control.mdMUST load for roles, grants, or sensitive dataScoped role setup, IAM-to-database role mapping
troubleshooting.mdSHOULD load for errors or unexpected behaviorOCC and 23503, FK, connections, cluster state
limits-and-error-codes.mdSHOULD load before sizing batches, keys or indexes, or on 54000/0A000/54011Every limit, rejection and quota with SQLSTATE and exact message
dsql-examples.mdLoad for implementation examplesMulti-tenant access, batch operations, identity and sequences, connection pooling
onboarding.mdUser requests "Get started with DSQL"Interactive step-by-step guide
occ-retry-patterns.mdMUST load for OCC retry code or conflict mitigationConnectors, 40001 retry, non-retryable 23503, FK read conflicts, idempotent design
MCP:
ReferenceWhen to LoadContains
mcp-setup.mdAlways for MCP server guidanceSetup instructions, 2 configuration options
mcp-tools.mdFor MCP tool syntax and examplesTool parameters, input validation
dsql-lint.mdMUST load before running dsql_lint or processing external SQLTool reference, fix statuses, unfixable error resolution
DDL Migrations:
ReferenceWhen to LoadContains
ddl-migrations/overview.mdMUST load for ALTER TYPE, SET NOT NULL, MODIFY PRIMARY KEYDirect ALTER coverage and last-resort table recreation
ddl-migrations/column-operations.mdDROP COLUMN, ALTER TYPE, SET/DROP NOT NULL/DEFAULTColumn-level migration patterns
ddl-migrations/constraint-operations.mdADD/DROP CONSTRAINT, VALIDATE CONSTRAINT, MODIFY PRIMARY KEYConstraint and structural changes
ddl-migrations/batched-migration.mdTables exceeding 3,000 rowsBatching patterns, progress tracking
MySQL Migrations:
ReferenceWhen to LoadContains
mysql-migrations/type-mapping.mdMUST load for MySQL → DSQL migrationData type mappings, feature alternatives
mysql-migrations/ddl-operations.mdTranslating MySQL DDL to DSQLAUTO_INCREMENT, ENUM, SET, FK patterns
mysql-migrations/full-example.mdComplete MySQL table migrationEnd-to-end example with decision summary
PostgreSQL Migrations:
ReferenceWhen to LoadContains
pg-migrations/type-mapping.mdMUST load for DSQL NUMERIC or PG type questionsC collation rules, NUMERIC(p,s), JSON/JSONB
pg-migrations/index-conversion.mdMUST load for any index conversion or index support questionGIN/GiST/BRIN → btree, operator class removal, partial + expression indexes, sort order
pg-migrations/schema-objects.mdMUST load for ENUM, materialized views, extensions, multi-schema, CREATE FUNCTIONENUM → CHECK, views, role/IAM mapping, LANGUAGE sql functions
pg-migrations/multi-region.mdMulti-region, active-active, or HA questionsArchitecture, geographic partitioning
ORM Guides:
ReferenceWhen to LoadContains
orm-guides/overview.mdMigrating an ORM or using ORM locking with DSQLAdapter names, locking, and key gotchas for Django/EF Core/Hibernate/Rails/SQLAlchemy
Data Loading:
ReferenceWhen to LoadContains
data-loading.mdPlanning or running bulk loads with aurora-dsql-loaderFresh-vs-warm partitions, resume/retry, --on-conflict semantics, throughput diagnostics
System Diagnostics:
ReferenceWhen to LoadContains
system-diagnostics/workflow.mdMUST load at Workflow 12 entry — cluster performance diagnosticsPrerequisites, 5 diagnostic phases, temporal comparison, handoff
system-diagnostics/wait-events.mdALWAYS load when interpreting AAS resultsCanonical DSQL wait event descriptions and investigation guidance
system-diagnostics/promql-patterns.mdLoad when constructing PromQL queriesReusable query templates for AAS breakdown, top-SQL, temporal compare
Query Plan Explainability:
ReferenceWhen to LoadContains
query-plan/workflow.mdMUST load at Workflow 9 entry — gates all other filesTrigger criteria, context disambiguation, routing, phased workflow
query-plan/plan-interpretation.mdMUST load at Workflow 9 Phase 0DSQL node types, Node Duration math, estimation-error bands
query-plan/catalog-queries.mdMUST load at Workflow 9 Phase 0pg_class/pg_stats/pg_indexes SQL, correlated-predicate verification
query-plan/guc-experiments.mdMUST load at Workflow 9 Phase 0GUC experiment procedures, 30-second skip protocol
query-plan/report-format.mdMUST load at Workflow 9 Phase 0Required report structure, element checklist, support request template
query-plan/query-rewrites-generic.mdSHOULD load at Phase 0; sub-files on-demandIndex of 10 generic rewrite patterns
query-plan/query-rewrites-dsql-specific.mdSHOULD load at Phase 0; sub-files on-demandIndex of DSQL-specific rewrite patterns

Choosing How to Connect: MCP vs CLI/psql

The aurora-dsql MCP server binds a single cluster at startup (--cluster_endpoint), so using it for another cluster means editing .mcp.json and restarting the session.

  • Use the aurora-dsql MCP tools (readonly_query, transact, get_schema) ONLY when the server already targets the cluster you need.

  • Otherwise — unconfigured, disabled, or bound to a different cluster — do NOT reconfigure it. Use the CLI + psql path instead: scripts/psql-connect.sh <cluster-id> --region <region> --command "SELECT ..." (mints an IAM token and runs via psql).

  • If you cannot confirm which cluster the MCP targets, confirm first or use the CLI/psql path — running against the wrong cluster is worse than the check.

The doc-only MCP tools (dsql_lint, dsql_*_documentation, dsql_recommend) need no cluster. The CloudWatch MCP (Workflow 12) takes region/cluster_id per call, so one running server can query clusters in any PromQL-enabled region (pass each cluster's region on the call). Details: connectivity-tools.md.

MCP Tools Available

The aurora-dsql MCP server provides these tools:

Database Operations:

  1. readonly_query - Execute SELECT queries (returns list of dicts)

  2. transact - Execute DDL/DML statements in transaction (takes list of SQL statements)

  3. get_schema - Get table structure for a specific table

SQL Validation:

  1. dsql_lint - Validate SQL for DSQL compatibility and optionally auto-fix issues. Use before executing externally-sourced SQL.

Documentation & Knowledge:

  1. dsql_search_documentation - Search Aurora DSQL documentation

  2. dsql_read_documentation - Read specific documentation pages

  3. dsql_recommend - Get DSQL best practice recommendations

Note: There is no list_tables tool. Use readonly_query with information_schema.

See mcp-setup.md for detailed setup instructions. See mcp-tools.md for detailed usage and examples.

AWS Knowledge MCP (awsknowledge)

Consult for verifying DSQL service limits before advising users. The numeric limits below are defaults that may change — when a user's decision depends on an exact limit, verify it first:

LimitDefaultVerify query
Max row modifications per transaction3,000aurora dsql transaction limits
Max data size per transaction10 MiBaurora dsql transaction limits
Max transaction duration5 minutesaurora dsql transaction limits
Max connections per cluster10,000aurora dsql connection limits
Auth token expiry15 minutesaurora dsql authentication token
Max connection duration60 minutesaurora dsql connection limits
Max indexes per table24 incl. PKaurora dsql index limits
Max columns per index8aurora dsql index limits
IDENTITY/SEQUENCE CACHE values1 or >= 65536aurora dsql sequence cache
Supported column data typesSee docsaurora dsql supported data types

When to verify: Before recommending batch sizes, connection pool settings, or schema designs where hitting a limit would cause failures; any time the exact number can affect user decision. For the full limit set with each SQLSTATE and its exact error message, see limits-and-error-codes.md; where it marks a value observed and the docs differ, use the observed value.

Fallback: If awsknowledge is unavailable, use the defaults above and flag that limits should be verified against DSQL documentation.

CLI Scripts Available

Bash scripts in scripts/ for cluster management (create, delete, list, cluster info), psql connection, and bulk data loading from local/s3 csv/tsv/parquet files. See scripts/README.md for usage and hook configuration.


Quick Start

  1. Pick a connection path: confirm the aurora-dsql MCP targets your cluster; if not, use the CLI/psql path instead — see Choosing How to Connect. The steps below name MCP tools; the equivalent SQL runs the same way through psql-connect.sh --command "...".

  2. Explore: Use readonly_query with information_schema to list tables. Use get_schema for table structure.

  3. Query: Use readonly_query for SELECT queries. MUST include tenant_id in WHERE for multi-tenant apps. MUST build SQL with safe_query.build().

  4. Schema changes: Use transact with one DDL per transaction. MUST batch DML under 3,000 rows. MUST use CREATE INDEX ASYNC in a separate call. Use dsql_lint to validate first.

  5. Bulk load data: Use aurora-dsql-loader for CSV/TSV/Parquet. Load data-loading.md for details. Use --dry-run first.


Performance Routing

When the user reports a performance problem, use this table to select the correct workflow:

User signalRoute to
General performance complaint, "cluster is slow", "something changed", latency regression, no specific query identifiedWorkflow 12 (System Diagnostics) — observe via CloudWatch first
Specific query or query_id to investigate, "explain this plan", "why is this query slow"Workflow 9 (Query Plan Explainability) — direct EXPLAIN analysis
OCC conflicts, commit errors, retry stormsWorkflow 12 (System Diagnostics) — confirm via CW metrics before investigating
Cost optimization, "where is compute time spent"Workflow 12 (System Diagnostics) — identify top contributors first

Rule: When in doubt, start with Workflow 12. It identifies specific queries to investigate and routes to Workflow 9 with context.


Common Workflows

Workflow 1: Create Multi-Tenant Schema
  1. Create tenant-owned tables with tenant_id using separate transact calls

  2. Use composite tenant FKs for tenant-owned parents and ordinary FKs for shared parents

  3. Create tenant and query-pattern indexes with separate CREATE INDEX ASYNC calls

  4. Verify with get_schema

  • MUST issue each DDL in its own transact call: transact(["CREATE TABLE ..."])

  • MUST serialize arrays into a single-column representation — DSQL has no array column type; PREFER JSONB (operators work directly); MAY use TEXT when the column is opaque to the database; ASK the user. For JSONB arrays, expand at query time with jsonb_array_elements_text(data)

Workflow 2: Safe Data Migration

MUST validate every DDL with dsql_lint(fix=true) before executing. DML does not require linting.

  1. Validate DDL with dsql_lint(sql=..., fix=true) — handle diagnostics per dsql-lint.md

  2. Execute the reviewed fixed_sql when present, otherwise the reviewed source statement

  3. Add column in its own transact call

  4. Populate existing rows with UPDATE (batched under 3,000 rows)

  5. Verify with readonly_query COUNT

  6. Create an index if needed: validate then execute the reviewed DDL in its own transact call

  • MUST issue each ALTER TABLE in its own transact call — DSQL rejects multi-DDL transactions with multiple ddl statements not supported in a transaction

  • MUST add column with only name and type; apply DEFAULT via separate UPDATE

  • MUST batch updates under 3,000 rows in separate transact calls

Recovery: Resume failed batches by filtering WHERE new_column IS NULL.

Workflow 3: Bulk Data Loading

Use aurora-dsql-loader for CSV, TSV, or Parquet loads. MUST load data-loading.md before advising on throughput or diagnosing slow loads.

  1. Validate with --dry-run first

  2. Run with --manifest-dir on persistent storage (not /tmp — tmpfs on AL2023, lost on crash) and --header if file has a header row

  3. On failure: resume with --resume-job-id; for duplicates use --on-conflict do-nothing

  4. For large tables: create secondary indexes after load using CREATE INDEX ASYNC

Workflow 4: Foreign Key Constraints

MUST load and follow foreign-keys.md before creating, altering, dropping, or migrating foreign keys.

Workflow 5: Query with Tenant Isolation
  1. MUST authorize the caller against the tenant — format validation does not establish authorization

  2. MUST build SQL with safe_query.build() — use allow()/regex() for values (emits 'v'), ident() for table/column names (emits "v"). See input-validation.md

  3. MUST include tenant_id in the WHERE clause; reject cross-tenant access at the application layer

Workflow 6: Set Up Scoped Database Roles

MUST load access-control.md for role setup, IAM mapping, and schema permissions.

Workflow 7: Table Recreation DDL Migration

For ALTER COLUMN TYPE, SET NOT NULL, or MODIFY PRIMARY KEY, MUST load ddl-migrations/overview.md. Use a direct ALTER form when supported; otherwise, present a user-approved table-recreation plan.

Workflow 8: Validate and Migrate to DSQL

MUST load dsql-lint.md before running dsql_lint. Run dsql_lint(sql=source_sql, fix=true) to validate and auto-convert. For MySQL-origin SQL, MUST cross-check against mysql-migrations/type-mapping.md even when lint returns clean. On parse_error, fall back to manual conversion then re-lint.

Workflow 9: Query Plan Explainability

Explains why the DSQL optimizer chose a particular plan. Triggered by slow queries, high DPU, unexpected Full Scans, or plans the user doesn't understand. REQUIRES a structured Markdown diagnostic report as the deliverable.

MUST load query-plan/workflow.md at entry — it defines trigger criteria, context disambiguation, routing, and the full phased workflow (Phase 0–4). Workflow.md specifies which reference files to load at each phase.

Safety. Plan capture uses readonly_query exclusively. Rewrite DML to SELECT for plan capture. MUST NOT use transact --allow-writes for plan capture.

Workflow 10: Full PostgreSQL → DSQL Schema Migration

MUST load pg-migrations/type-mapping.md, pg-migrations/index-conversion.md, pg-migrations/schema-objects.md, and foreign-keys.md. Run dsql_lint(fix=true) first for mechanical fixes, preserve foreign-key relationships, translate unsupported source syntax or options, then apply semantic conversions from the pg-migrations references for unfixable diagnostics and patterns the linter cannot handle. Re-lint the final output before deploying.

Workflow 11: ORM Migration and Locking (Django/EF Core/Hibernate/Rails/SQLAlchemy)

Load orm-guides/overview.md for adapter names, locking guidance, and framework-specific gotchas.

Workflow 12: System Diagnostics (CloudWatch AAS)

Diagnose cluster performance by querying db.active_sessions.avg via PromQL. Detects temporal anomalies in wait event distribution, identifies regressed queries, and routes to Workflow 9 for per-query investigation.

Requires: CloudWatch MCP server (awslabs.cloudwatch-mcp-server) enabled and configured with PromQL access in the same region as the cluster — see mcp/mcp-setup.md for enabling it, region requirements, and the session restart needed for its tools to register.

MUST load system-diagnostics/workflow.md at entry — it defines prerequisites, 5 diagnostic phases, temporal baselines, and the routing to Workflow 9 for identified queries.

Error Scenarios

  • awsknowledge returns no results: Use the default limits in the table above and note that limits should be verified against DSQL documentation.

  • dsql_lint unavailable or timing out: See the Error Handling section of dsql-lint.md. Do not silently skip validation — inform the user and require explicit confirmation before proceeding with manual rules from development-guide.md.

  • OCC serialization error (40001): Retry with backoff, and keep (OC001) in the loop too — see occ-retry-patterns.md.

  • Foreign key violation (23503): Correct the relationship or referential action; MUST NOT send it through the 40001 retry loop — see troubleshooting.md.

  • Transaction exceeds limits: Split batches under 3,000 rows and 10 MiB; size is checked at COMMIT — see limits-and-error-codes.md to size them and batched-migration.md for the pattern.

  • Token expiration mid-operation: Generate a fresh IAM token — see authentication-guide.md. See troubleshooting.md for other issues.

Additional Resources

Files

references/system-diagnostics/workflow.md

DSQL System Diagnostics

Diagnose Aurora DSQL cluster performance by querying Active Average Sessions (AAS) via PromQL and detecting temporal anomalies in wait event distribution. This skill observes via CloudWatch — it identifies which queries and workloads changed, then hands them to Workflow 9 (EXPLAIN ANALYZE) for per-query root cause. It does not itself diagnose scan types, index state, or query plans.

Key capabilities:

  • Temporal trend analysis of AAS via db.active_sessions.avg metric

  • Wait event distribution shift detection

  • Top-SQL regression identification (new or growing queries)

  • Workload attribution (application and IAM role changes)

  • Commit volume vs OCC conflict analysis

  • Handoff to Workflow 9 for per-query investigation

Important principles:

  • There is no upper bound to AAS in DSQL — absolute values are not inherently problematic

  • What matters is change over time: shifts in wait event distribution, new queries appearing, or existing queries consuming disproportionately more time

  • This skill observes via CloudWatch only — it does not recommend schema changes, indexing strategies, or query rewrites. Those require live database access via Workflow 9.

  • A db.wait.event label is not an EXPLAIN node type. It reports where a session spent time, not the query plan. You MUST NOT infer a scan type ("full scan", "Seq Scan"), an index state (missing / still building / unused), or any per-query root cause from a wait event. In particular, SequentialScanRead is a storage-layer range read that accumulates AAS under high concurrency or call frequency — it is not evidence of a full table scan or a missing index. Only Workflow 9 (EXPLAIN ANALYZE) can establish scan type, index usage, or root cause. A fast, well-indexed query run by thousands of concurrent sessions produces high AAS on read wait events; this is expected, not a defect.

PromQL syntax rules:

  • Label names containing . or @ MUST be quoted in selectors: "@resource.aws.auroradsql.cluster_id"="value"

  • The get_promql_label_values tool MUST include a match parameter to return results — calls without match return empty

  • Use {__name__="db.active_sessions.avg", ...} selector form for all queries


Prerequisites

MUST have before starting:

  1. A specific cluster_id to investigate — never proceed without one. Ask the user if not provided.

  2. The CloudWatch MCP server (awslabs.cloudwatch-mcp-server) enabled and configured with PromQL access in the same region as the DSQL cluster. See mcp-setup.md for how to enable it, the region requirement, PromQL-enabled regions, and the required session restart. If its PromQL tools are unavailable, resolve that before starting rather than working around it — see Error Handling below.

  3. The aurora-dsql MCP server configured for the target cluster — not used by this workflow itself, but required for the Workflow 9 handoff (EXPLAIN ANALYZE) that per-query root cause is deferred to

If the PromQL tools are unavailable (e.g. execute_promql_range_query / get_promql_label_values are missing, or a call returns "No such tool available"): the diagnostic cannot run, and there is no substitute — AAS is only readable through these tools, so do not fall back to the AWS CLI, standard CloudWatch metrics, or fabricated numbers. The usual cause is that the CloudWatch server is disabled, misconfigured, or was enabled after this session started (its tools only register at session start). Tell the user to enable/fix it per mcp-setup.md and then restart the session, since a mid-session enable will show as "Connected" yet still expose no callable tools until restart. Report this as the blocker and the fix, rather than reporting only that data is missing.


Reference Files

Load these sibling files as needed:

wait-events.md

When: ALWAYS load when interpreting AAS results Contains: DSQL wait events with canonical descriptions and investigation guidance

promql-patterns.md

When: Load when constructing PromQL queries Contains: Reusable PromQL query templates for all diagnostic phases


Core Concept: Active Average Sessions (AAS)

The primary metric is db.active_sessions.avg — the average number of sessions actively executing or waiting at a given instant.

Normalized SQL and AAS interpretation: All SQL in the metric is normalized (parameterized). The db.query.normalized_text label groups all executions of the same query shape. A query with high AAS indicates it is executing frequently and/or concurrently across many sessions. A single slow query can only contribute at most 1 AAS — high AAS always means high concurrency or high call frequency, not a single slow execution. Neither this skill nor the dsql skill can currently distinguish frequency from per-execution cost; this will be possible in a future release that publishes per-SQL execution statistics via PromQL.

LabelPurpose
db.wait.eventWhich wait the session is in (OnCpu, ClientRead, Commit, etc.)
db.query.normalized_textSQL fingerprint — groups identical query shapes
db.query.idCorrelates with DSQL EXPLAIN Query Identifier
application.nameClient application identifier
aws.auroradsql.session.role.arnIAM role used for the connection
db.session.stateSession state (active, idle in transaction)
@resource.aws.auroradsql.cluster_idCluster identifier for filtering
@resource.cloud.resource_idFull cluster ARN

Diagnostic Procedure

MUST execute ALL phases below in order. Do not stop at the first finding — complete the full sweep before presenting results.

Phase 1: Discovery and Baseline Comparison

Goal: Establish whether the cluster's wait event distribution has changed.

Steps:

  1. Confirm you have a specific cluster_id — do not proceed without one

  2. Verify the cluster exists by calling get_promql_label_values with a match filter and an explicit start/end window covering the period you intend to analyze (see promql-patterns.md). Label-value and series lookups default to a window ending "now"; if the cluster's most recent data is older than that default (for example, a lightly-used or paused cluster), the call returns an empty list even though the cluster exists. An empty result here means "no data in that window," not "no such cluster" — widen or shift the window before concluding the cluster is missing.

  3. Query AAS by db.wait.event for the current hour in 10-minute chunks (step=60s)

  4. Query AAS by db.wait.event for the same hour yesterday (baseline 1)

  5. Query AAS by db.wait.event for the same hour last week (baseline 2)

  6. Compute the distribution (% each wait event contributes to total AAS) for each period

  7. Flag any wait event where the proportion changed by >30% vs either baseline

  8. Compare 10-minute chunks within the current hour against each other to detect recent intra-hour shifts

Critical rules:

  • MUST filter by cluster using "@resource.aws.auroradsql.cluster_id" in all queries

  • MUST quote label names that contain . or @ in PromQL selectors

  • MUST use the match parameter with get_promql_label_values — calls without match return empty. When the data you care about is not recent, also pass an explicit start/end, since these lookups default to a window ending "now" and will otherwise miss older data

  • MUST compare against temporal baselines — do NOT report absolute AAS values as inherently problematic (the >30%-share-change trigger is defined in Step 7)

Example (start/end MUST be concrete RFC 3339 timestamps — the API rejects relative expressions like NOW-1h. Compute the three windows first, e.g. with date -u -v-1H +%Y-%m-%dT%H:%M:%SZ on macOS or date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ on Linux, then substitute. The comments below show which window each call covers):

# Current hour (e.g. start=2026-07-13T15:00:00Z, end=2026-07-13T16:00:00Z)
execute_promql_range_query(
  query='sum by ("db.wait.event")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"})',
  start="CURRENT_HOUR_START", end="CURRENT_HOUR_END", step="60s"
)

# Same hour yesterday (current window minus 24h)
execute_promql_range_query(
  query='sum by ("db.wait.event")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"})',
  start="YESTERDAY_HOUR_START", end="YESTERDAY_HOUR_END", step="60s"
)

# Same hour last week (current window minus 168h)
execute_promql_range_query(
  query='sum by ("db.wait.event")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"})',
  start="LAST_WEEK_HOUR_START", end="LAST_WEEK_HOUR_END", step="60s"
)

Phase 2: Top-SQL Regression Detection

Goal: Identify SQL statements that have become more prominent. Run regardless of Phase 1 findings.

Steps:

  1. Query top-N SQL by AAS for the current period

  2. Query top-N SQL for the same period last week

  3. Identify queries that are new in the top-N or have grown significantly vs baseline

  4. For each regressed query, note which db.wait.event dominates

Critical rules:

  • MUST include db.query.id in grouping — stable identifier for Workflow 9 handoff

  • MUST compare top-N across periods — a query being #1 is only notable if it wasn't before

  • MUST NOT recommend indexing or schema changes — hand off to Workflow 9

Example:

# Top 5 SQL current
execute_promql_query(query='topk(5, sum by ("db.query.normalized_text", "db.query.id")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"}))')

# Top 5 SQL with wait event
execute_promql_query(query='topk(10, sum by ("db.query.normalized_text", "db.query.id", "db.wait.event")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"}))')

Phase 3: Workload Attribution

Goal: Identify which applications and IAM roles are driving changes. Run regardless of other findings.

Steps:

  1. Query top applications and IAM roles for current period

  2. Compare against baseline — report only changes, not static dominance

  3. For applications or roles that have grown, break down by db.wait.event

Critical rules:

  • MUST compare against baseline — an application being dominant is only noteworthy if it has changed

  • Report the delta: "application X increased from 30% to 55% of total AAS"

Example:

# Top IAM roles
execute_promql_query(query='topk(5, sum by ("aws.auroradsql.session.role.arn")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"}))')

# Top applications
execute_promql_query(query='topk(5, sum by ("application.name")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"}))')

Phase 4: Commit and OCC Analysis

Goal: Determine whether commit behavior has changed. Run regardless of other findings.

Steps:

  1. Check Commit wait event's share vs baseline (from Phase 1 data)

  2. If Commit share changed, query standard CloudWatch metrics:

    • AWS/AuroraDSQL namespace, dimension ClusterId

    • TotalTransactions — commit rate

    • OccConflicts — conflict rate

  3. Compare ratios:

    • OccConflicts growing faster than TotalTransactions → conflict problem

    • TotalTransactions growing proportionally → legitimate load

    • Commit AAS up but TotalTransactions flat → transactions taking longer

Example:

# MUST pass start_time/end_time covering the SAME window as the Phase 1 baselines being
# compared — get_metric_data defaults to only the last 3 hours, which will not line up with
# the yesterday / last-week AAS windows. Use concrete RFC 3339 timestamps (no NOW-relative form).
get_metric_data(
  namespace="AWS/AuroraDSQL",
  metric_name="TotalTransactions",
  dimensions=[{name: "ClusterId", value: "CLUSTER_ID"}],
  statistic="Sum",
  start_time="WINDOW_START", end_time="WINDOW_END"
)

get_metric_data(
  namespace="AWS/AuroraDSQL",
  metric_name="OccConflicts",
  dimensions=[{name: "ClusterId", value: "CLUSTER_ID"}],
  statistic="Sum",
  start_time="WINDOW_START", end_time="WINDOW_END"
)

Phase 5: Inflection Point Detection

Goal: Pinpoint when the change occurred. Run when Phase 1 detects a shift vs last week.

Steps:

  1. Query a 7-day range for the shifted wait event (3600s step)

  2. Identify the inflection point — when did the distribution change?

  3. Correlate with known events (deployments, traffic changes)

Critical rules:

  • SHOULD use step: 60s (< 1h), 300s (1–6h), 900s (6–24h), 3600s (> 24h)

  • MUST specify start and end in RFC 3339 format

  • MUST keep each query's range at or under 7 days — split longer investigations

Example:

# Concrete RFC 3339 timestamps; keep the span just under 7 days so it stays within the tool's
# max-range limit (which counts any lookback). Substitute a recent window for your investigation.
execute_promql_range_query(
  query='sum by ("db.wait.event")({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"})',
  start="WINDOW_START", end="WINDOW_END",
  step="3600s"
)

Presenting Results

After completing all phases, present a unified report covering:

  1. Distribution shift summary — which wait events changed and by how much

  2. Top-SQL regression — which queries are new or growing, with their dominant wait events

  3. Workload attribution — which applications/roles changed their share

  4. Commit health — volume vs conflict analysis (if CW metrics available)

  5. Timeline — when the change occurred (if a shift was detected)

  6. Queries for investigation — list of queries to hand off to Workflow 9


Per-Query Investigation

When queries are identified as newly prominent or significantly grown, describe the observed anomaly and proceed to Workflow 9:

"Query {NORMALIZED_SQL} (db.query.id: {QUERY_ID}) is using significantly more system time than it did {TIMEFRAME} ago. Its share of cluster AAS on {WAIT_EVENT} has grown from {OLD}% to {NEW}%."

The handoff MUST describe only what the metric shows — a query's share of a wait event changed vs baseline. It MUST NOT append a hypothesized cause (e.g. "because it is full-scanning", "the index is missing", "the plan regressed to a Seq Scan"). Scan type, index usage, and root cause are Workflow 9's output, not this handoff's input — stating them here pre-judges the investigation and is exactly the kind of guess this skill must not make.

Then proceed to Workflow 9 (Query Plan Explainability) for each identified query.


Idle Cluster Detection

A cluster is idle when there is no AAS data for a period. Use a range query and look for gaps (missing timestamps) in the time series.

Pattern: Sporadic workload — periods of no data interspersed with periods of AAS > 0 indicate a cluster performing scheduled or batch work.

# start/end MUST be concrete RFC 3339 timestamps (not NOW-relative). For a trailing 24h window,
# compute end = now and start = now - 24h first, then substitute.
execute_promql_range_query(
  query='sum({__name__="db.active_sessions.avg", "@resource.aws.auroradsql.cluster_id"="CLUSTER_ID"})',
  start="WINDOW_START", end="WINDOW_END", step="300s"
)

Error Handling

SituationAction
No cluster_id providedAsk the user — never proceed without a specific cluster
PromQL tools not callable (e.g. "No such tool available")The CloudWatch server is not enabled, is misconfigured, or was enabled after the session started. Enable/fix it per mcp-setup.md, then restart the session — tools are registered at startup. Do not fall back to guessing or to unrelated tools.
No series / empty label valuesConfirm the match selector, then widen or shift the start/end window — these lookups default to "now" and miss older data. Only after that, suspect a wrong cluster ID or region.
Empty result (no data)Cluster is idle for that period. Widen time window.
db.query.id missingNot all queries emit it. Filter by db.query.normalized_text instead.
PromQL timeoutReduce cardinality — fewer labels or shorter time range.
Range > 7 daysSplit into multiple 7-day range queries.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs Python, Needs Node.js

Security

What our scanner noticed· Low risk

  • Instructions that use the network
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS Labs
Publisher
AWS Labs (Official)
Source
awslabs/agent-plugins · plugins/databases-on-aws/skills/dsql · commit fbefb37
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS Labs.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download dsql.zip