[Update] Amazon Redshift's SUPER Data Type Can Now Store Strings of Up to 16,000,000 Bytes, So I Tried It Out

[Update] Amazon Redshift's SUPER Data Type Can Now Store Strings of Up to 16,000,000 Bytes, So I Tried It Out

Amazon Redshift's SUPER type now stores strings up to 16,000,000 bytes, so JSON with strings over 65,535 bytes loads without splitting. I enabled the parameter on Redshift Serverless and tested limits with COPY, LISTAGG and Japanese text.
2026.11.07

This page has been translated by machine translation. View original

I'm Ishikawa from the Cloud Business Division. Amazon Redshift's SUPER data type can now store individual strings of up to 16,000,000 bytes, so I tried it out on Amazon Redshift Serverless using the sample data from the AWS blog.

https://aws.amazon.com/jp/about-aws/whats-new/2026/11/amazon-redshift-expands-super-to-16-million-bytes/

Amazon Redshift's SUPER data type can now store individual strings of up to 16,000,000 bytes. The previous limit was 65,535 bytes.

When you opt in with a database parameter, this limit applies to ingestion from JSON, PARQUET, TEXT, and CSV source files, as well as to transformations in ELT processing. You can now load JSON containing strings that exceed 65,535 bytes, such as contracts or long logs, without splitting or truncating them, and reference them with SQL. JSON_PARSE, CONCAT, and LISTAGG can also accept and output strings of up to 16,000,000 bytes.

It is available in all AWS Regions where Amazon Redshift is available, including the AWS GovCloud (US) Regions.

In this article, I enabled the parameter on a dedicated Amazon Redshift Serverless workgroup for testing, followed the steps in the AWS blog (loading JSON, string functions, and LISTAGG), and checked the limit with Japanese strings.

https://aws.amazon.com/blogs/big-data/store-and-process-large-strings-in-amazon-redshift-super-columns/

What is large string support in the SUPER data type

The SUPER data type is an Amazon Redshift data type that stores semi-structured data such as JSON without requiring a schema definition. It can hold arrays and nested structures as a single value, and elements within arrays and structures are referenced using PartiQL syntax. According to the documentation, each individual SUPER object supports up to 16 MB of data. What has been raised this time is the limit for each individual string contained in a SUPER value.

https://docs.aws.amazon.com/redshift/latest/dg/r_SUPER_type.html

Large string support must be enabled with the parameter enable_large_strings_opt_in. The value can be Yes, No, or unset (the default); when unset, the existing behavior is maintained. The behavior for each value is as follows.

Item Yes No
Limit for individual strings in SUPER 16,000,000 bytes 65,535 bytes
VARCHAR length that string functions can process Up to 16,000,000 bytes Up to 65,535 bytes
COPY / INSERT of more than 65,535 bytes into a SUPER column Possible Not possible (existing strings can still be read as SUPER)
CAST to VARCHAR(MAX) Treated as VARCHAR(16000000) Truncated to 65,535 bytes
Column specified as VARCHAR(MAX) in CREATE TABLE VARCHAR(65535) VARCHAR(65535)

The AWS blog lists Amazon Redshift Patch 206 or later (current maintenance track) as a prerequisite. For provisioned clusters, you set enable_large_strings_opt_in to Yes in a parameter group, attach it to the cluster, and reboot the cluster. Because Amazon Redshift Serverless does not use parameter groups, you specify the parameter in the workgroup settings. You can check the current state with SELECT is_large_string_enabled();.

The documentation and the AWS blog describe the following points to note.

  • Once set to Yes or No, it cannot be returned to the default (unset). Even if you reset with ResetClusterParameterGroup, the configured value is retained
  • When the parameter is enabled, VARCHAR(MAX) is treated as VARCHAR(16000000) within expressions such as CAST and views, but table columns are not affected. Even if you specify VARCHAR(MAX) in CREATE TABLE, a VARCHAR(65535) column is created, so if you want to store in a table a string over 65,535 bytes extracted from a SUPER column, or the result of LISTAGG or similar, store it in a SUPER column

One point that needs attention is that this parameter changes not only SUPER columns but also the upper limit of the VARCHAR length handled by string functions and casts. However, the limit is raised only for values handled within expressions; VARCHAR columns in tables are not affected.

  • Views, UDFs, and stored procedures created before the parameter was enabled remain limited to 65,535 bytes until they are recreated
  • If other views or objects depend on a view that uses VARCHAR(MAX), CREATE OR REPLACE VIEW fails with the error "cannot change data type of view column". Drop the dependent objects, drop and recreate the view, and then recreate the dependent objects
  • If you use data sharing, make the settings consistent between the producer and consumer data warehouses
  • If you restore a snapshot that contains strings over 65,535 bytes in a SUPER column to a cluster where this parameter is No, ingestion of the long strings may fail

Trying it out

Prerequisites

  • Region: Tokyo Region
  • Amazon Redshift Serverless: Patch 206 (current track, workgroup version 1.0.535482), base capacity 4 RPU
  • AWS CLI 2.39.5
  • Sample data: orders.json distributed in the AWS blog

Because enable_large_strings_opt_in cannot be returned to unset once configured, I did not use an existing workgroup and instead created a dedicated namespace and workgroup for this test. The flow of the test is as follows.

Creating the test environment

I built Redshift Serverless in the Tokyo Region with the following configuration.

Resource Name Details
VPC and subnets super16m-vpc, super16m-subnet-1 to 3 Subnets in three Availability Zones. No internet gateway or NAT gateway
Security group super16m-sg No inbound rules
S3 bucket super16m-<account ID>-ap-northeast-1 Holds the test data for COPY
IAM role super16m-copy-role Allows read access to the test data bucket only. Set as the namespace's default IAM role
Namespace super16m-ns Database dev. The admin password is managed by Redshift in Secrets Manager
Workgroup super16m-wg Base capacity and max capacity both 4 RPU, no public access. Created without specifying enable_large_strings_opt_in

The patch version and parameter of the created workgroup are as follows.

% aws redshift-serverless get-workgroup \
  --workgroup-name super16m-wg \
  --query "workgroup.{status:status,patchVersion:patchVersion,trackName:trackName,workgroupVersion:workgroupVersion,baseCapacity:baseCapacity,configParameters:configParameters[?parameterKey==\`enable_large_strings_opt_in\`]}"
{
    "status": "AVAILABLE",
    "patchVersion": "206",
    "trackName": "current",
    "workgroupVersion": "1.0.535482",
    "baseCapacity": 4,
    "configParameters": [
        {
            "parameterKey": "enable_large_strings_opt_in",
            "parameterValue": ""
        }
    ]
}

The patch version was 206, and the value of enable_large_strings_opt_in was an empty string (unset).

You can also confirm Patch 206 and Track Current on the workgroup screen in the Management Console.

Note that on the console's workgroup screen, I could not find any item to view or set enable_large_strings_opt_in in either the actions menu (delete workgroup, edit track, manage usage limits, etc.) or the six tabs (Query and database monitoring, Data access, Limits, Performance, Tags, Autonomics). For this reason, I changed and checked the parameter with the AWS CLI.

Enabling large string support

In Amazon Redshift Serverless, you change the parameter (enable_large_strings_opt_in) with --config-parameters of update-workgroup.

% aws redshift-serverless update-workgroup \
  --workgroup-name super16m-wg \
  --config-parameters parameterKey=enable_large_strings_opt_in,parameterValue=Yes \
  --query "workgroup.{status:status,configParameters:configParameters[?parameterKey==\`enable_large_strings_opt_in\`]}"
{
    "status": "MODIFYING",
    "configParameters": [
        {
            "parameterKey": "enable_large_strings_opt_in",
            "parameterValue": "Yes"
        }
    ]
}

The status changed to MODIFYING, and when I checked at 10-second intervals, it returned to AVAILABLE after about 1 minute 45 seconds.

% aws redshift-serverless get-workgroup \
  --workgroup-name super16m-wg \
  --query "workgroup.{status:status,configParameters:configParameters[?parameterKey==\`enable_large_strings_opt_in\`]}"
{
    "status": "AVAILABLE",
    "configParameters": [
        {
            "parameterKey": "enable_large_strings_opt_in",
            "parameterValue": "Yes"
        }
    ]
}

Comparing the entire configParameters before and after the change, only enable_large_strings_opt_in had changed; the other parameters (auto_mv, datestyle, require_ssl, max_query_execution_time, etc.) retained their previous values.

How the SQL was run

First, check the state of large string support.

SELECT is_large_string_enabled();
% aws redshift-data get-statement-result --id aebe60e7-2a69-4e80-bb08-139b7d5e7568
{
    "Records": [
        [
            {
                "booleanValue": true
            }
        ]
    ],
    "ColumnMetadata": [
        {
            "isCaseSensitive": false,
            "isCurrency": false,
            "isSigned": false,
            "label": "is_large_string_enabled",
            "name": "is_large_string_enabled",
            "nullable": 1,
            "precision": 1,
            "scale": 0,
            "schemaName": "",
            "tableName": "",
            "typeName": "bool",
            "length": 0
        }
    ],
    "TotalNumRows": 1
}

is_large_string_enabled() returned true. From here on, I present the SQL that was run and the results of get-statement-result summarized in tables. If an error occurred, I present the contents of Error from describe-statement.

Loading JSON containing large strings

I use the sample orders.json distributed in the AWS blog.

https://d2908q01vomqb2.cloudfront.net/artifacts/DBSBlogs/BDB-5835/orders.json

The file size is 3,203,661 bytes, and it contains 5 order records (JSON objects). In each order, detailedDescription is a string of 242,400 bytes and transactionLogs is a string of 397,600 bytes (both ASCII characters only), and both exceed 65,535 bytes. I upload this file to S3.

% aws s3 cp orders.json s3://super16m-123456789012-ap-northeast-1/testdata/orders.json --no-progress
upload: ./orders.json to s3://super16m-123456789012-ap-northeast-1/testdata/orders.json

As in the AWS blog's example, I create a table with a single SUPER column and COPY with FORMAT JSON 'noshred'.

CREATE TABLE orders (data SUPER);

COPY orders
FROM 's3://super16m-123456789012-ap-northeast-1/testdata/orders.json'
IAM_ROLE 'arn:aws:iam::123456789012:role/super16m-copy-role'
FORMAT JSON 'noshred';

The COPY completed without errors. I check the load result in SYS_LOAD_HISTORY.

SELECT query_id, status, TRIM(table_name) AS table_name, file_format,
       loaded_rows, loaded_bytes, source_file_count, error_count
FROM sys_load_history
WHERE table_name = 'orders'
ORDER BY start_time DESC LIMIT 1;
query_id status table_name file_format loaded_rows loaded_bytes source_file_count error_count
203099 completed orders JSON 5 3203661 1 0

5 rows were loaded. I check the contents of the loaded data. Because the JSON attribute names are camelCase, I set enable_case_sensitive_super_attribute to true before referencing them.

SET enable_case_sensitive_super_attribute TO true;

SELECT data.orderId::VARCHAR                     AS order_id,
       data.customerId::VARCHAR                  AS customer_id,
       data.status::VARCHAR                      AS status,
       data.shippingAddress.state::VARCHAR       AS shipping_state,
       LENGTH(data.detailedDescription::VARCHAR) AS description_length,
       LENGTH(data.transactionLogs::VARCHAR)     AS logs_length
FROM orders
ORDER BY 1;
order_id customer_id status shipping_state description_length logs_length
ORD-2024-001 CUST-12346 processing NY 242400 397600
ORD-2024-002 CUST-12347 processing CA 242400 397600
ORD-2024-003 CUST-12348 processing IL 242400 397600
ORD-2024-004 CUST-12349 processing TX 242400 397600
ORD-2024-005 CUST-12350 processing AZ 242400 397600

The strings of 242,400 and 397,600 characters, which exceed 65,535 bytes, were stored without being truncated.

Use string functions after casting to VARCHAR

The AWS blog presents an example where applying a string function directly to a SUPER column value causes an error, and an example where it is applied after casting to VARCHAR. First, I try applying lower directly to a SUPER value.

SET enable_case_sensitive_super_attribute TO true;

SELECT lower(data.customerId) AS customer_id FROM orders;
ERROR: function lower(super) does not exist
  Hint: No function matches the given name and argument types. You may need to add explicit type casts.

It resulted in an error because the lower function has no definition that accepts a SUPER-type argument. Since customerId is a 10-byte string, this error occurs regardless of string length. I apply it after casting to VARCHAR.

SET enable_case_sensitive_super_attribute TO true;

SELECT lower(data.customerId::VARCHAR) AS customer_id FROM orders ORDER BY 1;
customer_id
cust-12346
cust-12347
cust-12348
cust-12349
cust-12350

After casting, the values converted to lowercase were returned. I also try applying string functions, after casting, to detailedDescription and transactionLogs, which exceed 65,535 bytes.

SET enable_case_sensitive_super_attribute TO true;

SELECT data.orderId::VARCHAR AS order_id,
       LENGTH(lower(data.detailedDescription::VARCHAR)) AS lower_desc_length,
       LENGTH(upper(data.transactionLogs::VARCHAR))     AS upper_logs_length,
       RIGHT(upper(data.transactionLogs::VARCHAR), 30)  AS upper_logs_tail
FROM orders
ORDER BY 1;
order_id lower_desc_length upper_logs_length upper_logs_tail
ORD-2024-001 242400 397600 Z - DELIVERY DATE CALCULATED.
ORD-2024-002 242400 397600 Z - DELIVERY DATE CALCULATED.
ORD-2024-003 242400 397600 Z - DELIVERY DATE CALCULATED.
ORD-2024-004 242400 397600 Z - DELIVERY DATE CALCULATED.
ORD-2024-005 242400 397600 Z - DELIVERY DATE CALCULATED.

The lengths of the lower and upper results were the same as the original strings, 242,400 and 397,600 characters, and the last 30 characters were returned converted to uppercase. Strings exceeding 65,535 bytes were also processed without being truncated.

Storing the string concatenated with LISTAGG in a SUPER column

Using the same query as the AWS blog, I concatenate the 5 detailedDescription values with LISTAGG and check the number of characters in the result.

SET enable_case_sensitive_super_attribute TO true;

SELECT LEN(LISTAGG(data.detailedDescription::VARCHAR, ', ')
           WITHIN GROUP (ORDER BY data.orderId::VARCHAR)) AS description_length
FROM orders
WHERE data.status::VARCHAR = 'processing';
description_length
1212008

As stated in the AWS blog, the result was 1,212,008 characters (242,400 characters × 5 items, plus the 2-character delimiter , × 4 places).

The AWS blog explains that when the result of LISTAGG exceeds the 65,535-byte limit of a VARCHAR column, it can be stored in a SUPER column. I create tables with a SUPER column and a VARCHAR(MAX) column, and try storing the LISTAGG result in each.

CREATE TABLE order_desc_super (descriptions SUPER);
CREATE TABLE order_desc_varchar (descriptions VARCHAR(MAX));

SET enable_case_sensitive_super_attribute TO true;

-- Store in a SUPER column
INSERT INTO order_desc_super
SELECT LISTAGG(data.detailedDescription::VARCHAR, ', ') WITHIN GROUP (ORDER BY data.orderId::VARCHAR)
FROM orders WHERE data.status::VARCHAR = 'processing';

-- Store in a VARCHAR(MAX) column
INSERT INTO order_desc_varchar
SELECT LISTAGG(data.detailedDescription::VARCHAR, ', ') WITHIN GROUP (ORDER BY data.orderId::VARCHAR)
FROM orders WHERE data.status::VARCHAR = 'processing';

The INSERT into the SUPER column succeeded, and the INSERT into the VARCHAR(MAX) column resulted in the following error.

ERROR: Value too long for character type
  Detail:
  -----------------------------------------------
  error:  Value too long for character type
  code:      8001
  context:   Value too long for type character varying(65535)
...

I check the value stored in the SUPER column and the definition of the VARCHAR(MAX) column.

SELECT JSON_TYPEOF(descriptions) AS type,
       LEN(descriptions::VARCHAR) AS chars,
       OCTET_LENGTH(descriptions::VARCHAR) AS bytes
FROM order_desc_super;
type chars bytes
string 1212008 1212008
SELECT table_name, column_name, data_type, character_maximum_length
FROM svv_columns
WHERE table_schema = 'public' AND table_name = 'order_desc_varchar';
table_name column_name data_type character_maximum_length
order_desc_varchar descriptions character varying 65535

In the SUPER column, it was stored as a string of 1,212,008 bytes. The column created with VARCHAR(MAX) after enabling the parameter was character varying(65535), and values exceeding 65,535 bytes could not be stored.

Checking with Japanese strings

I check whether the limit is judged by character count or byte count, using a Japanese hiragana character that takes 3 bytes in UTF-8. Since 16,000,000 ÷ 3 = 5,333,333 remainder 1, adding one ASCII a to 5,333,333 of those hiragana characters gives 16,000,000 bytes.

I create a table for verification.

CREATE TABLE t_super (id INT, label VARCHAR(50), doc SUPER);

I check the character count and byte count of the strings to be stored.

SELECT LEN(REPEAT('あ', 5333333) || 'a') AS chars_a,
       OCTET_LENGTH(REPEAT('あ', 5333333) || 'a') AS bytes_a,
       LEN(REPEAT('あ', 5333334)) AS chars_b,
       OCTET_LENGTH(REPEAT('あ', 5333334)) AS bytes_b;
chars_a bytes_a chars_b bytes_b
5333334 16000000 5333334 16000002

Both are 5,333,334 characters, and only the byte counts differ. I try storing each with JSON_PARSE.

INSERT INTO t_super VALUES (20, 'ja-16000000', JSON_PARSE('{"body":"' || REPEAT('あ', 5333333) || 'a' || '"}'));

INSERT INTO t_super VALUES (21, 'ja-16000002', JSON_PARSE('{"body":"' || REPEAT('あ', 5333334) || '"}'));

id=20 at 16,000,000 bytes succeeded, and id=21 at 16,000,002 bytes resulted in the following error.

ERROR: Invalid input
  Detail:
  -----------------------------------------------
  error:  Invalid input
  code:      8001
  context:   JSON_PARSE() error: String value exceeds the max size of 16000000 bytes: (16000000 bytes skipped)            "}
...

I check the stored value.

SELECT id, label, LEN(doc.body::VARCHAR) AS chars, OCTET_LENGTH(doc.body::VARCHAR) AS bytes,
       SUBSTRING(doc.body::VARCHAR, 1, 5) AS head5
FROM t_super WHERE id >= 20 ORDER BY id;
id label chars bytes head5
20 ja-16000000 5333334 16000000 (five hiragana characters)

The limit is judged by byte count. For a string consisting only of Japanese (3-byte characters), the limit is about 5.33 million characters.

Checking in Query Editor v2

I also checked is_large_string_enabled() and the LISTAGG result in Query Editor v2 in the Management Console (connected as a federated user).

SET enable_case_sensitive_super_attribute TO true;

SELECT is_large_string_enabled() AS large_string_enabled,
COUNT(*) AS orders,
LEN(LISTAGG(data.detailedDescription::VARCHAR, ', ')
WITHIN GROUP (ORDER BY data.orderId::VARCHAR)) AS description_length
FROM orders
WHERE data.status::VARCHAR = 'processing';

large_string_enabled was true, orders was 5, and description_length was 1,212,008, the same as with the Data API.

Discussion

The results confirmed in this verification are summarized below.

What was checked Result
Parameter change (Serverless) About 1 minute 45 seconds with update-workgroup. Other parameters kept their previous values
is_large_string_enabled() true
COPY of orders.json (FORMAT JSON 'noshred') Loaded 5 rows containing strings of 242,400 bytes and 397,600 bytes
Applying lower directly to a SUPER value function lower(super) does not exist error
Applying lower / upper after casting to ::VARCHAR Processed at 242,400 and 397,600 characters as is
LISTAGG result 1,212,008 characters (same as the AWS blog)
Storing the LISTAGG result Succeeded for the SUPER column, error for the VARCHAR(MAX) column (character varying(65535))
Japanese strings (JSON_PARSE) 16,000,000 bytes (5,333,334 characters) succeeded, 16,000,002 bytes (5,333,334 characters) errored

Based on these results, I think the following points need attention.

  • In Amazon Redshift Serverless, setting and checking the parameter is done via the CLI or similar. The workgroup screen in the console that I checked had no item to view or set enable_large_strings_opt_in. You can check the value after setting it with configParameters of get-workgroup, or with SELECT is_large_string_enabled();
  • When applying string functions to SUPER values, cast to ::VARCHAR. The error without a cast is due to the function's argument type, and occurred even for short strings. With the cast, the result length was the same as the original string even for strings over 65,535 bytes
  • To save values over 65,535 bytes in a table, use a SUPER column. Even after enabling the parameter, a column specified as VARCHAR(MAX) in CREATE TABLE is character varying(65535), and the LISTAGG result (1,212,008 bytes) could not be stored
  • The limit is in bytes, not characters. For a string consisting only of Japanese characters at 3 bytes each in UTF-8, the limit is about 5.33 million characters. When estimating the length of data that includes Japanese, you need to check the byte count with OCTET_LENGTH rather than the character count
  • Because the parameter cannot be returned to unset, I recommend trying it first in a dedicated test environment before using an existing environment. In this Amazon Redshift Serverless test, creating the test environment took about 1 minute 50 seconds and changing the parameter took about 1 minute 45 seconds

This verification did not cover provisioned clusters (parameter groups and cluster reboot), behavior before enabling the parameter, behavior when set to No, recreation of existing views, UDFs, and stored procedures, data sharing, snapshot restore, or COPY from PARQUET, TEXT, and CSV.

Conclusion

Amazon Redshift's SUPER data type can now store individual strings of up to 16,000,000 bytes. By setting enable_large_strings_opt_in to Yes in Amazon Redshift Serverless, I confirmed that the AWS blog's sample orders.json (JSON containing strings of 242,400 bytes and 397,600 bytes) can be loaded as is into a SUPER column with COPY, and that string functions applied after casting to VARCHAR, as well as LISTAGG, handle strings over 65,535 bytes without truncation.

On the other hand, VARCHAR(MAX) columns in tables remain at 65,535 bytes, and the limit is judged in bytes. There are also points to check before enabling, such as the fact that once set it cannot be returned to the default, and that existing views, UDFs, and stored procedures need to be recreated. If you are currently splitting or truncating JSON to fit the 65,535-byte limit, why not consider adopting this after enabling the parameter in a dedicated test environment and checking the impact on your existing load processes and objects?

Share this article

AWSのお困り事はクラスメソッドへ