This chapter covers DynamoDB PartiQL, a SQL-compatible query language that allows you to interact with DynamoDB tables using familiar SQL syntax. For the SAA-C03 exam, PartiQL appears in questions about query flexibility, migration from relational databases, and cost vs. performance trade-offs. Approximately 5-10% of DynamoDB-related questions may involve PartiQL, often as a distractor or in scenarios requiring SQL compatibility. Understanding PartiQL's capabilities and limitations is essential to choose the right access pattern for your application.
Jump to a section
Imagine a large warehouse where items are stored in thousands of bins, each bin labeled with a unique bin ID (partition key) and a shelf location (sort key). The warehouse manager, traditionally, only speaks a special bin-picking language: 'Get item from bin A123, shelf B456'. This is fast but requires knowing exact bin IDs. Now, the company hires a universal translator (PartiQL) who can speak standard English (SQL). You can say, 'Find all items where the bin aisle is 'A' and the weight is less than 10 kg'. The translator converts this into the warehouse's native language: it first looks up which bins are in aisle 'A' (scanning a secondary index), then for each such bin, it issues a native 'GetItem' command, checks the weight, and returns results. The translator does not move items or change how bins work; it just provides a familiar interface. However, because it may need to talk to many bins to answer a single query, it can be slower than speaking the native language directly. Also, some complex SQL operations (like full table joins) are impossible because the warehouse has no concept of joining bins—the translator will error out. The key is that the translator is an overlay, not a replacement for the native system.
What is DynamoDB PartiQL?
DynamoDB PartiQL is a SQL-compatible query language that provides a familiar interface for accessing data in DynamoDB. It is not a separate service or a database engine—it is a query layer that translates SQL statements into native DynamoDB operations (GetItem, PutItem, Query, Scan, etc.). PartiQL was originally developed by Amazon for internal use and later released as an open-source standard. In DynamoDB, it is available via the AWS Management Console, AWS CLI, AWS SDKs, and the DynamoDB API.
Why PartiQL Exists
DynamoDB's native API is powerful but requires understanding of its data model: tables, items, attributes, partition keys, sort keys, and secondary indexes. Developers familiar with SQL often struggle with this paradigm. PartiQL bridges the gap by allowing SQL-based access, reducing the learning curve and enabling reuse of SQL skills. It also simplifies migration from relational databases (RDS, Aurora) by allowing teams to run similar queries on DynamoDB during transition.
How PartiQL Works Internally
PartiQL does not execute SQL in a relational engine. Instead, it parses the SQL statement and translates it into one or more DynamoDB API calls. For example:
SELECT * FROM Orders WHERE OrderID = '123'This translates to a GetItem call with key OrderID = '123'. The response is then formatted as a SQL result set.
SELECT * FROM Orders WHERE Status = 'Shipped'This translates to a Scan operation (if Status is not a key or indexed attribute) or a Query operation (if Status is a key of a Global Secondary Index). PartiQL automatically determines the most efficient underlying operation based on the table schema and indexes.
Key Components and Defaults
PartiQL statements: SELECT, INSERT, UPDATE, DELETE (but not CREATE TABLE, ALTER, JOIN across tables).
Data types: PartiQL supports DynamoDB types (String, Number, Binary, Boolean, Null, List, Map, Set). SQL types like VARCHAR are mapped to String.
Consistency: PartiQL supports EVENTUAL (default) and STRONG consistency via the SETTING clause.
SELECT * FROM Orders WHERE OrderID = '123' SETTING CONSISTENT_READ = TRUEReturn values: For INSERT and UPDATE, you can request ALL_OLD, ALL_NEW, UPDATED_OLD, UPDATED_NEW using RETURNING *.
Pagination: PartiQL returns up to 1 MB of data per call. Use NextToken for pagination (similar to native ExclusiveStartKey).
Transaction support: PartiQL supports transactional INSERT, UPDATE, DELETE across up to 10 items or 4 MB of data using BEGIN TRANSACTION ... COMMIT. This translates to TransactWriteItems or TransactGetItems.
Configuration and Verification
PartiQL is enabled by default for all DynamoDB tables. No additional setup is required. You can run PartiQL statements via:
AWS CLI: Use aws dynamodb execute-statement or aws dynamodb execute-transaction.
aws dynamodb execute-statement --statement "SELECT * FROM Orders WHERE OrderID = '123'"AWS SDKs: Use the ExecuteStatement or ExecuteTransaction API.
Console: Navigate to the DynamoDB table, click 'PartiQL editor' tab.
To verify the underlying operations, enable AWS CloudTrail logs—you will see the native DynamoDB API calls (e.g., GetItem, Query, Scan) in the logs.
Interaction with Related Technologies
DynamoDB Streams: PartiQL INSERT, UPDATE, DELETE operations are recorded in streams just like native operations.
DAX: PartiQL queries can be directed to a DAX cluster endpoint for caching. However, not all PartiQL statements are eligible for caching (e.g., transactions are not cached).
IAM: Permissions are based on the underlying DynamoDB actions. To allow PartiQL, you must grant dynamodb:ExecuteStatement and dynamodb:ExecuteTransaction, plus the specific data plane actions (e.g., dynamodb:GetItem, dynamodb:PutItem) that the statement will translate to.
CloudWatch: PartiQL metrics are not separate; they appear as DynamoDB metrics (e.g., ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits).
Limitations and Performance Considerations
No cross-table joins: PartiQL cannot join data from multiple tables. This is a fundamental limitation of DynamoDB's NoSQL model.
No `GROUP BY` or `ORDER BY`: These SQL operations are not supported. Sorting must be done client-side or via sort keys.
No aggregate functions like SUM, COUNT (except COUNT(*) on a SELECT without conditions, which triggers a full table scan).
Performance: PartiQL is often slower than native API because the translation overhead and the fact that SQL queries may trigger full scans. For production workloads, prefer native Query and GetItem for predictable performance.
Read capacity consumption: PartiQL SELECT without a key condition will consume read capacity for the entire table (full scan). Always use WHERE clauses on keys or indexes when possible.
Use Cases on the Exam
The SAA-C03 exam tests PartiQL in the context of:
Migrating from RDS to DynamoDB: PartiQL eases the transition by allowing SQL queries during migration.
Ad-hoc querying for analytics or debugging: PartiQL is convenient for quick data exploration.
Reducing developer learning curve: Teams familiar with SQL can use PartiQL instead of learning DynamoDB's API.
Transactional operations: PartiQL can perform multi-item transactions with familiar SQL syntax.
However, the exam will also test when NOT to use PartiQL: high-traffic production systems, complex queries requiring joins or aggregations, or scenarios where fine-grained control over consumed capacity is needed.
Parse SQL Statement
When a PartiQL statement is submitted, DynamoDB first parses the SQL string. It identifies the operation type (SELECT, INSERT, UPDATE, DELETE), the table name, columns, conditions, and any modifiers (e.g., RETURNING, SETTING). The parser validates syntax and checks table existence. If the statement is invalid, an error is returned immediately. This step is lightweight and adds minimal latency (sub-millisecond).
Determine Optimal API Operation
Based on the parsed statement and the table schema (including indexes), PartiQL decides which DynamoDB API operation to use. For a SELECT with an equality condition on the primary key (partition key and optionally sort key), it uses GetItem. For a condition on a sort key or a GSI key, it uses Query. For conditions on non-key attributes, it uses Scan. For INSERT, it uses PutItem. For UPDATE, it uses UpdateItem. For DELETE, it uses DeleteItem. If a transaction is requested, it uses TransactWriteItems or TransactGetItems.
Translate to Native API Call
PartiQL constructs the native DynamoDB request. For example, the SQL 'SELECT * FROM Orders WHERE OrderID = '123'' becomes a GetItem request with Key={'OrderID': {'S': '123'}}. The SQL condition is converted into DynamoDB's expression syntax (KeyConditionExpression, FilterExpression, etc.). Any RETURNING clause is mapped to ReturnValues parameter. The CONSISTENT_READ setting is mapped to ConsistentRead parameter. This translation is deterministic and does not involve optimization beyond choosing the correct operation.
Execute Native Call and Return Results
DynamoDB executes the native API call against the storage layer. The result (item or items) is returned to PartiQL, which formats it as a SQL result set (list of rows with column names). If the statement is an INSERT/UPDATE/DELETE with RETURNING, the returned attributes are included. If the operation consumes more than 1 MB of data, PartiQL returns a NextToken for client-side pagination. The client must handle pagination manually or use a loop. The entire execution is atomic for single-item operations; for transactions, all operations succeed or fail together.
Charge Read/Write Capacity
PartiQL operations consume DynamoDB capacity units exactly as the underlying native operations would. A GetItem for a 1 KB item consumes 1 read capacity unit (RCU) for eventually consistent reads or 2 RCUs for strongly consistent. A Scan consumes RCUs equal to the total size of data scanned. Write operations consume write capacity units (WCUs) based on item size. PartiQL does not add any extra capacity consumption; the cost is identical to using the native API. However, because PartiQL may choose a Scan instead of a Query, it can lead to higher consumption than necessary if the SQL is not optimized.
Enterprise Scenario 1: Migrating from SQL Server to DynamoDB
A retail company is migrating its order management system from SQL Server to DynamoDB to handle high-velocity write traffic. The development team is proficient in SQL but new to NoSQL. They use PartiQL during the migration phase to run existing SQL queries against DynamoDB tables with minimal code changes. For example, they can run 'SELECT * FROM Orders WHERE CustomerID = 123' without rewriting to DynamoDB's Query API. This accelerates migration but introduces performance issues in production: the PartiQL queries often perform full scans because CustomerID is not a key or index attribute. The team mitigates this by creating a Global Secondary Index on CustomerID, after which PartiQL automatically uses the index and performs Query operations. In production, they eventually replace PartiQL with native SDK calls for latency-sensitive endpoints, but keep PartiQL for internal reporting tools.
Enterprise Scenario 2: Ad-hoc Analytics for a Gaming Company
A mobile gaming company uses DynamoDB to store player profiles and game state. The data science team needs to run occasional queries like 'SELECT AVG(score) FROM Players WHERE level > 10'. PartiQL does not support AVG, so they retrieve all matching rows and compute the average client-side. This works for small datasets but becomes slow for millions of players. They learn that PartiQL's COUNT(*) without a WHERE clause triggers a full table scan costing thousands of RCUs. They switch to using DynamoDB's native Scan with pagination and compute aggregates in Lambda functions. PartiQL remains useful for quick data exploration on small subsets (e.g., checking a specific player's attributes).
Enterprise Scenario 3: Multi-item Transactions in a Banking Application
A fintech startup uses DynamoDB to manage account balances and transaction history. They need to transfer funds between accounts atomically. Using PartiQL, they can write:
BEGIN TRANSACTION
UPDATE Accounts SET balance = balance - 100 WHERE account_id = 'A';
UPDATE Accounts SET balance = balance + 100 WHERE account_id = 'B';
COMMITThis translates to a TransactWriteItems call. The startup finds PartiQL convenient for prototyping but later migrates to native TransactWriteItems for fine-grained error handling and to reduce overhead. They also discover that PartiQL transactions have a 4 MB limit and can include up to 10 items, which is sufficient for their use case. Misconfiguration: Initially, they forgot to grant dynamodb:ExecuteTransaction permission, causing 'AccessDeniedException'. They also hit transaction conflicts under high concurrency, which they resolved by implementing retry logic with exponential backoff.
What SAA-C03 Tests on PartiQL (Objective 3.6)
The exam focuses on PartiQL's role as a SQL-compatible interface for DynamoDB, its limitations, and appropriate use cases. You will not be asked to write PartiQL syntax but to evaluate scenarios where PartiQL is or isn't suitable.
Common Wrong Answers and Why
'PartiQL supports joins across tables' – Many candidates assume that because it is SQL, it supports JOINs. Reality: PartiQL only works on a single table. Cross-table joins are not possible.
'PartiQL is faster than native API' – Candidates think a SQL layer is optimized. Reality: PartiQL adds translation overhead and often uses Scan, making it slower. Native API is faster for production.
'PartiQL can create tables' – DDL statements are not supported. PartiQL is only for data manipulation (DML).
'PartiQL transactions are free' – No, they consume the same capacity and have the same limits as native transactions.
Specific Numbers and Terms on the Exam
Transaction limits: up to 10 items or 4 MB total.
Consistency: SETTING CONSISTENT_READ = TRUE for strong consistency.
Return values: RETURNING ALL_OLD * etc.
Pagination: NextToken (not ExclusiveStartKey).
Permissions: dynamodb:ExecuteStatement and dynamodb:ExecuteTransaction.
Edge Cases and Exceptions
PartiQL does not support LIMIT clause. To limit results, you must use native API or client-side filtering.
PartiQL SELECT * without WHERE will scan the entire table, consuming massive RCUs.
PartiQL cannot query DynamoDB Streams or Time to Live (TTL) data.
PartiQL does not support conditional expressions like IF NOT EXISTS directly; you must use SETTING or native API.
How to Eliminate Wrong Answers
If a question asks for a low-latency, high-throughput solution for production, eliminate PartiQL. If it asks for ad-hoc SQL queries or migration from RDS, PartiQL is likely correct. If the question mentions joins or aggregations, PartiQL is wrong. Always check whether the query uses key conditions; if not, PartiQL may cause a full scan.
PartiQL is a SQL-compatible query language for DynamoDB, not a separate database.
PartiQL translates SQL statements into native DynamoDB API calls (GetItem, PutItem, Query, Scan, etc.).
PartiQL does NOT support JOINs, GROUP BY, aggregate functions, or DDL statements.
PartiQL transactions support up to 10 items or 4 MB total data.
PartiQL queries can trigger full table scans if WHERE clauses do not use keys or indexes.
PartiQL is best suited for ad-hoc queries, migration from relational databases, and reducing developer learning curve.
For production, high-traffic systems, prefer native DynamoDB API for better performance and control.
IAM permissions required: dynamodb:ExecuteStatement and dynamodb:ExecuteTransaction, plus underlying data plane actions.
PartiQL supports consistent reads via 'SETTING CONSISTENT_READ = TRUE'.
PartiQL does not support LIMIT; pagination is done via NextToken.
These come up on the exam all the time. Here's how to tell them apart.
DynamoDB PartiQL
SQL-compatible syntax, familiar to developers
Easier for ad-hoc queries and quick debugging
Slower due to translation overhead and potential full scans
Cannot perform joins or aggregations
Limited to DML operations (no DDL)
DynamoDB Native API
Requires knowledge of DynamoDB data model and API
More verbose for simple queries
Faster and more predictable performance
Allows fine-grained control over operations and capacity
Supports all DynamoDB features including conditional writes, TTL, streams
DynamoDB PartiQL Transactions
Uses familiar SQL BEGIN/COMMIT syntax
Supports up to 10 items or 4 MB
Returns errors in SQL format
Limited ability to handle complex error scenarios
Suitable for prototyping and simple transactions
DynamoDB Native TransactWriteItems/TransactGetItems
More verbose JSON syntax
Same limits (10 items or 4 MB)
Returns detailed error information (e.g., which item caused conflict)
Allows custom retry logic and idempotency tokens
Preferred for production transactional workloads
Mistake
PartiQL is a separate database service from DynamoDB.
Correct
PartiQL is a query language and interface that runs on top of DynamoDB. It is not a separate service; it translates SQL into native DynamoDB API calls.
Mistake
PartiQL supports all SQL features including JOINs, GROUP BY, and aggregate functions.
Correct
PartiQL supports only basic DML (SELECT, INSERT, UPDATE, DELETE) and transactions. It does not support JOINs, GROUP BY, or aggregate functions like SUM, AVG, COUNT (except COUNT(*)).
Mistake
PartiQL queries are always faster than using the DynamoDB native API because they are optimized.
Correct
PartiQL queries are often slower because they add translation overhead and may trigger full table scans. Native API calls (GetItem, Query) are more efficient for production workloads.
Mistake
PartiQL can create, alter, or delete DynamoDB tables.
Correct
PartiQL is data manipulation language (DML) only. It cannot perform data definition operations (DDL) like CREATE TABLE, ALTER TABLE, or DROP TABLE.
Mistake
PartiQL transactions are free and have no limits.
Correct
PartiQL transactions consume read/write capacity units and have the same limits as native DynamoDB transactions: up to 10 items or 4 MB total.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
No, PartiQL does not support cross-table queries or joins. Each statement operates on a single table. If you need to query multiple tables, you must issue separate PartiQL statements or use the native API with application-level logic.
Yes, PartiQL supports multi-item transactions using BEGIN TRANSACTION and COMMIT. Transactions can include up to 10 items or 4 MB of data. They are translated into DynamoDB's TransactWriteItems or TransactGetItems operations.
No, PartiQL is generally slower because it adds translation overhead and may not use the most efficient operation (e.g., Scan instead of Query). For latency-sensitive applications, use the native API.
No, PartiQL is a data manipulation language (DML) only. You cannot create, alter, or delete tables (DDL). Use the AWS Management Console, AWS CLI, or SDKs for table management.
You need dynamodb:ExecuteStatement and dynamodb:ExecuteTransaction (for transactions). Additionally, the underlying data plane actions (e.g., GetItem, PutItem, Query, Scan) must be allowed for the tables you access.
Yes, PartiQL returns a NextToken when the result set exceeds 1 MB. You must include this token in subsequent requests to retrieve the next page. This is similar to ExclusiveStartKey in the native API.
Yes, you can direct PartiQL statements to a DAX cluster endpoint. However, transactional statements and some write operations may not be cached. For read-heavy workloads, DAX can improve performance.
You've just covered DynamoDB PartiQL — now see how well it sticks with free SAA-C03 practice questions. Full explanations included, no account needed.
Done with this chapter?