All Products
Search
Document Center

MaxCompute:Storage resources - Tiered storage

Last Updated:Jun 20, 2026

MaxCompute tiered storage supports Standard, IA storage class, and long-term storage. By default, tables use Standard storage. You can set the storage class of specific tables or partitions to IA storage class or long-term storage based on data access frequency. This enables automatic storage tiering of hot and cold data to reduce storage fees.

Tiered storage classes

Storage class

Description

Standard

The default storage class. Use this for data that is frequently accessed and requires frequent read/write operations.

IA storage class

Use this for data that does not require frequent access. It effectively reduces storage fees.

Note
  • Data stored in IA storage class or long-term storage cannot be directly accessed by Hologres. When Hologres reads MaxCompute data directly, MaxCompute tables or partitions do not update their last_access_time. Therefore, if you configure a lifecycle rule using the last_access_time condition, tables or partitions that are only continuously read by Hologres might still match the rule.

  • If you access large volumes of data or access data too frequently, your costs may exceed those of Standard storage. For example:

    • Accessing an entire table or partition stored in IA storage class once per month incurs the same cost as Standard storage.

    • Accessing an entire table or partition stored in long-term storage once every six months incurs the same cost as Standard storage.

Long-term storage

Tiered storage billing

  • For details about storage billing, see Storage fee.

  • When you set a table or partition to IA storage class or long-term storage, monitor your data access volume and frequency. If you access large volumes of data or access data too frequently, your costs may exceed those of Standard storage.

    • Accessing an entire table or partition stored in IA storage class once per month incurs the same cost as Standard storage.

    • Accessing an entire table or partition stored in long-term storage once every six months incurs the same cost as Standard storage.

  • Log on to Expenses and Costs. On the Bill > Bill Details page, you can view fees for different storage classes. The billing items for Standard, IA storage class, and long-term storage are named Storage, Tiered Storage - IA, and Long-term Storage, respectively. For more information, see View bill details.

Scope

  • Region restrictions: China (Hangzhou), China (Shanghai), China (Beijing), China (Zhangjiakou), China (Ulanqab), China (Shenzhen), China (Chengdu), China (Hong Kong), China (Shanghai) Finance Cloud, China (Beijing) Finance Cloud, China (Shenzhen) Finance Cloud, Singapore, Malaysia (Kuala Lumpur), Indonesia (Jakarta), Japan (Tokyo), Germany (Frankfurt), US (Silicon Valley).

  • Data stored in IA storage class or long-term storage cannot be directly accessed by Hologres. When Hologres reads MaxCompute data directly, MaxCompute tables or partitions do not update their last_access_time. Therefore, if you configure a lifecycle rule using the last_access_time condition, tables or partitions that are only continuously read by Hologres might still match the rule.

Set storage class

You can convert between storage classes. Changing the storage class does not affect data access.

The following table describes storage class conversions:

Conversion

Description

Standard → IA storage class

Supports manual and automatic conversion. No I/O access fees apply. The LastModifiedTime and LastAccessTime of the table or partition are not updated.

Standard → Long-term storage

Infrequent Access > Long-term Storage

Supports manual and automatic conversion. Manual switchover incurs I/O access fees. Automatic switchover does not. The LastModifiedTime and LastAccessTime of the table or partition are not updated.

IA storage class → Standard

Supports manual conversion only. I/O access fees apply. The LastModifiedTime and LastAccessTime of the table or partition are updated.

Long-term storage → IA storage class

Long-term storage → Standard

Manual custom settings

For non-partitioned tables or partitions, manually set the storage class to IA storage class or long-term storage. The change takes effect immediately.

Syntax

ALTER TABLE <TABLE_NAME> [PARTITION(<PARTITION_SPEC>)]
        SET <TBLPROPERTIES|PARTITIONPROPERTIES>("storagetier"="standard|lowfrequency|longterm");

Parameter description

  • TABLE_NAME: Required. The name of the table whose storage class you want to modify.

  • PARTITION_SPEC: Required when modifying the storage class of a partition.

  • TBLPROPERTIES | PARTITIONPROPERTIES: Modify the storage class of a table or partition. Description of values:

    • TBLPROPERTIES: Modifies the storage class of a table.

    • PARTITIONPROPERTIES: Modifies the storage class of a partition.

  • storagetier: Required. The tiered storage class. Valid values:

    • standard: Standard storage. Only storage fees apply.

    • lowfrequency: IA storage class. Storage fees and IA storage class data access fees apply.

    • longterm: Long-term storage. Storage fees and long-term storage data access fees apply.

Note

You can set tiered storage only for partitions in partitioned tables. You cannot set tiered storage for the entire partitioned table.

Examples

  • Example 1: Set the storage class of a non-partitioned table to IA storage class.

    ALTER TABLE tablename
            SET TBLPROPERTIES("storagetier"="lowfrequency");

    To verify the current storage class, check the StorageTier field in the table properties.

    -- View table properties
    DESC extended tablename;  
    --- Sample output
    +-------------------------------------------------------------------+
    | Owner:                    ALIYUN$mofan_****@test.aliyunid.com      |
    | Project:                  mf_mc_****                                |
    | TableComment:                                                     |
    +-------------------------------------------------------------------+
    | CreateTime:               2021-11-18 15:14:00                     |
    | LastDDLTime:              2023-09-11 14:34:55                     |
    | LastModifiedTime:         2023-09-13 15:02:28                     |
    | LastAccessTime:           2023-09-14 10:50:57                     |
    +-------------------------------------------------------------------+
    | InternalTable: YES      | Size: 1923683131                        |
    +-------------------------------------------------------------------+
    | Native Columns:                                                   |
    +-------------------------------------------------------------------+
    | Field| Type| Label |ExtendedLabel| Nullable| DefaultValue|Comment |
    +-------------------------------------------------------------------+
    | empno    | bigint |       |               | true     | NULL  |    |
    | ename    | string |       |               | true     | NULL  |    |
    | job      | string |       |               | true     | NULL  |    |
    | mgr      | bigint |       |               | true     | NULL  |    |
    | hiredate | datetime |     |               | true     | NULL  |    |
    | sal      | bigint |       |               | true     | NULL  |    |
    | comm     | bigint |       |               | true     | NULL  |    |
    | deptno   | bigint |       |               | true     | NULL  |    |
    +-------------------------------------------------------------------+
    | Extended Info:                                                    |
    +-------------------------------------------------------------------+
    | TableID:                  8e0cc78c81ab4ad7af30bff7a8e****         |
    | IsArchived:               false                                   |
    | PhysicalSize:             5771049393                              |
    | FileNum:                  3                                       |
    | StoredAs:                 AliOrc                                  |
    | CompressionStrategy:      normal                                  |
    | odps.timemachine.retention.days: 1                                |
    | ColdStorageStatus:        N/A                                     |
    | encryption_enable:        false                                   |
    | StorageTier:              lowfrequency                            |
    | StorageTierLastModifiedTime:  2023-09-11 14:34:55                 |
    +-------------------------------------------------------------------+
  • Example 2: Set the storage class of a partition in the partitioned table bank_data_pt to IA storage class.

    ALTER TABLE bank_data_pt  PARTITION (credit='yes') SET PARTITIONPROPERTIES ("storagetier" = 'lowfrequency');

    To verify the current storage class, check the StorageTier field in the partition properties.

    -- View partition properties
    DESC extended bank_data_pt PARTITION(credit='yes');  
    -- Sample output
    +------------------------------------------------------------------------------------+
    | PartitionSize: 0                                                                   |
    +------------------------------------------------------------------------------------+
    | CreateTime:               2024-05-10 10:28:16                                      |
    | LastDDLTime:              2024-05-10 10:31:01                                      |
    | LastModifiedTime:         2024-05-10 10:28:16                                      |
    +------------------------------------------------------------------------------------+
    | IsExstore:                false                                                    |
    | IsArchived:               false                                                    |
    | PhysicalSize:             0                                                        |
    | FileNum:                  0                                                        |
    | ColdStorageStatus:        N/A                                                      |
    | StorageTier:              LowFrequency                                             |
    | StorageTierLastModifiedTime:  2024-05-10 10:31:01                                  |
    +------------------------------------------------------------------------------------+

Automatic configuration using lifecycle rules

You can configure tiered storage lifecycle rules at the project or partitioned table level. These rules automatically convert storage classes based on specified conditions:

  • Project-level rules:

    After you set a project-level rule, it becomes the default rule for all non-partitioned tables in the project and for all partitions in partitioned tables that do not have their own rules. These tables and partitions automatically convert to the specified storage class.

  • Settings at the partitioned table level:

    After you set a rule for a specific partitioned table, it takes precedence over the project-level rule. All partitions in the table that meet the rule conditions automatically convert to the specified storage class.

Important limitations

You cannot configure rules at a finer granularity:

  • You cannot set an independent rule for a single non-partitioned table (it inherits the project rule).

  • You cannot set an independent rule for a specific partition in a partitioned table (it inherits the table rule).

Rule execution

  • When the lifecycle of a table or partition satisfies both the long-term storage (longterm) rule and the low-frequency storage (lowfrequency) rule, it is preferentially converted to longterm.

  • If a table or partition first meets the lowfrequency rule, it is converted to lowfrequency. If it later meets the longterm rule, it is converted again to longterm. This conversion from lowfrequency to longterm does not incur lowfrequency access fees. For billing details, see Tiered storage billing.

  • The platform scans rules twice daily. Therefore, there might be a delay between when a table or partition meets the conditions and when the storage class is updated.

Syntax

  • Set a lifecycle rule at the project level

    SETPROJECT odps.table.lifecycle.config=<lifecycle_config_json_string>;

    You can also configure this in the MaxCompute console:

    1. Log in to the MaxCompute console and select a region in the upper-left corner.

    2. In the left-side navigation pane, choose Manage Configurations > Projects.

    3. On the Projects page, click Manage in the Actions column for the target project.

    4. On the Project Settings page, click the Parameter Configuration tab.

    5. In the Lifecycle Configuration section, click Edit.

    6. Configure the Last Access Configuration Policy and Last Modified Configuration Policy parameters.

      • Last Access Configuration Policy: Corresponds to the DaysAfterLastAccessGreaterThan parameter.

      • Last Modified Configuration Policy: Corresponds to the DaysAfterLastModificationGreaterThan parameter.

  • Set a lifecycle rule for a partitioned table

    • Set during table creation:

      CREATE [EXTERNAL] TABLE [IF NOT EXISTS] <table_name>
       [PRIMARY KEY (<pk_col_name>, <pk_col_name2>),(<col_name> <data_type> [NOT NULL] [DEFAULT <default_value>] [comment <col_comment>], ...)]
       PARTITIONED BY (<col_name> <data_type> [comment <col_comment>], ...)
      tblproperties ('lifecycle_config' = '<lifecycle_config_json_string>')
      ;
    • Partitioned table modification settings:

      ALTER TABLE <TABLE_NAME> SET TBLPROPERTIES ('lifecycle_config' = '<lifecycle_config_json_string>');
  • View the tiered storage lifecycle configuration of a partitioned table

    SHOW CREATE TABLE <table_name>;

Parameter description

The following describes key parameters. For other parameters, see General parameters.

lifecycle_config_json_string:

  • For project-level lifecycle rules, define as follows:

    {
      "TierToLowFrequency": {
        "DaysAfterLastModificationGreaterThan": <days>, // Days since last modification
        "DaysAfterLastAccessGreaterThan": <days>, // Days since last access
      },
      "TierToLongterm": {
        "DaysAfterLastModificationGreaterThan": <days>,
        "DaysAfterLastAccessGreaterThan": <days>
      }
      // Each condition is optional. Multiple conditions use OR logic.
    }
  • For partitioned table lifecycle rules, define as follows:

    {
      \"TierToLowFrequency\": {
        \"DaysAfterLastModificationGreaterThan\": <days>, // Days since last modification
        \"DaysAfterLastAccessGreaterThan\": <days>, // Days since last access
      },
      \"TierToLongterm\": {
        \"DaysAfterLastModificationGreaterThan\": <days>,
        \"DaysAfterLastAccessGreaterThan\": <days>
      }
      // Each condition is optional. Multiple conditions use OR logic.
    }
  • TierToLowFrequency: Identifier for IA storage class.

  • TierToLongterm: Identifier for long-term storage.

  • DaysAfterLastModificationGreaterThan: Specifies the number of days after which the setting is automatically applied, based on the LastModifiedTime of the table or partition.

  • DaysAfterLastAccessGreaterThan: Specifies the number of days after which the storage class is automatically set based on the LastAccessTime of the table or partition. If LastAccessTime is empty:

    • For tables or partitions created before October 1, 2023, the system uses UTC+0 time 2023-10-01 00:00:00 as the default.

    • For tables or partitions created on or after October 1, 2023, if the data has never been accessed, the system uses the CreateTime.

Examples

  • Example 1: Set a lifecycle rule at the project level.

    setproject odps.table.lifecycle.config={"TierToLongterm":{"DaysAfterLastAccessGreaterThan":180},"TierToLowFrequency":{"DaysAfterLastAccessGreaterThan":120}};
  • Example 2: Remove the project-level lifecycle configuration.

    setproject odps.table.lifecycle.config=;
  • Example 3: Set a lifecycle rule for a partitioned table.

    -- Set during table creation
    CREATE TABLE lifecycle_part_t (key string) 
    PARTITIONED BY (ds  STRING)
    tblproperties ('lifecycle_config' = '{\"TierToLowFrequency\": {\"DaysAfterLastModificationGreaterThan\": 2,\"DaysAfterLastAccessGreaterThan\": 2},\"TierToLongterm\": {\"DaysAfterLastModificationGreaterThan\": 4,\"DaysAfterLastAccessGreaterThan\": 7}}')
    ;
    -- Modify an existing table
    ALTER TABLE lifecycle_part_t SET tblproperties ('lifecycle_config'='{\"TierToLowFrequency\": {\"DaysAfterLastModificationGreaterThan\": 90,\"DaysAfterLastAccessGreaterThan\": 30},\"TierToLongterm\": {\"DaysAfterLastModificationGreaterThan\": 180,\"DaysAfterLastAccessGreaterThan\": 7}}');
  • Example 4: Remove the tiered storage lifecycle configuration from a partitioned table.

    ALTER TABLE lifecycle_part_t SET tblproperties ('lifecycle_config'='{}');

Set data access permissions for tiered storage

Accessing data stored in IA storage class or long-term storage incurs access fees. You can control access to this data by combining row-level access control with the GET_PARTITION_META function.

GET_PARTITION_META

Note

GET_PARTITION_META is a special function. You can only use it with row-level permissions. Do not use it in regular SQL queries.

Syntax

struct GET_PARTITION_META(<tableName>, <pt_col1>, <pt_col2>, ..., <pt_col_n>);

Parameter description

Parameter Name

Description

tableName

The name of a partitioned table. Must be a String. Supports formats project.table or project.schema.table.

pt_col

Each parameter from pt_col1 to pt_col_n corresponds to a partition level in the partitioned table. Each parameter must be a column reference.

Return value

Returns a Struct of type struct<storagetier:string>. The Struct contains one String field that describes the storage class of the corresponding partition.

Notes

  • When adding a row-level rule to a table, consider access patterns of users other than those being controlled. If other users have already accessed the table, set explicit rules for them to avoid unexpected data filtering due to unintended access restrictions. For more information, see Row-level access control.

  • By default, MaxCompute tables can be accessed through SQL and external engines (such as Spark and Flink). However, only the MaxCompute SQL engine supports the GET_PARTITION_META function. If you use GET_PARTITION_META in row-level access control, the table can only be read by the MaxCompute SQL engine. Other engines cannot access the table.

  • To access data under row-level permissions, you must also have SELECT permission on the data.

  • Partition pruning behavior varies depending on the filter conditions used with GET_PARTITION_META.

    • If the filter condition involves only partition fields—for example, allowing access to Standard storage where the first-level partition value is 2024:

      GET_PARTITION_META('storage_table', pt1, pt2).storagetier == 'standard') AND pt1='2024'

      When you access storage_table using SQL and the WHERE clause does not contain partition conditions, the system natively supports partition pruning to avoid a full table scan and allows read-only access only to the partitions in storage_table that meet the requirements.

    • If the filter condition includes a non-partition field combined with an AND operator—for example, allowing access to Standard storage where a>100:

      GET_PARTITION_META('storage_table', pt1, pt2).storagetier == 'standard') AND a > 100

      When you query storage_table without a partition condition in the WHERE clause, partition pruning still applies. Only partitions stored as standard are accessed.

    • If the filter condition includes a non-partition field combined with an OR operator—for example, allowing access to Standard storage or where a>100:

      get_partition_meta('storage_table', pt1, pt2).storagetier == 'standard') OR a > 100

      When you query storage_table, two scenarios apply:

      • If the WHERE clause has no partition condition, all partitions are scanned to find data where a>100.

      • If the WHERE clause includes a partition condition, only the specified partitions are scanned for data matching standard or a>100.

Examples

Create the partitioned table storage_table.

CREATE TABLE storage_table(a BIGINT, b BIGINT) PARTITIONED BY (pt1 STRING, pt2 STRING);
  • Example 1:

    Create a policy named policy01 for the DEFAULT user group. This policy allows access only to Standard storage data in storage_table. All users (including the Project Owner) are denied access to IA storage class or long-term storage data and receive empty results.

    CREATE ROW ACCESS POLICY policy01 
    ON storage_table 
    TO DEFAULT 
    FILTER USING (get_partition_meta('storage_table', pt1, pt2).storagetier == 'standard');

    If the Logview Summary shows the following keyword, row-level filtering is triggered:

    WARNING:[1,15] row access policy is enabled on table yyy_hp_storagetier.storage_table01. This indicates that the row access policy was applied during the query.

  • Example 2:

    Grant user user_x permission policy02 to access IA storage class and long-term storage data in storage_table.

    CREATE ROW ACCESS POLICY policy02 
    ON storage_table 
    TO USER (user_x)  -- You can also grant to a role using TO role rolename, then assign the role to user_x.
    FILTER USING (get_partition_meta('storage_table', pt1, pt2).storagetier IN ('lowfrequency','longterm'));

    Two scenarios apply:

    • If the table has the policy01 permission configured, all users (except user_x) can access the standard storage data of storage_table, but cannot access infrequent-access or long-term storage data, and any attempt to do so returns empty values. For user_x, access to the infrequent-access and long-term storage data of storage_table is allowed, but access to standard storage data is not permitted and returns empty values.

    • If policy01 is not set, all users (except user_x) cannot access any data in storage_table (empty results). Only user_x can access IA storage class and long-term storage data but cannot access Standard storage data (empty results).

  • Example 3:

    Grant user user_y permission policy03 to access all data in storage_table.

    CREATE ROW ACCESS POLICY policy03 
    ON storage_table 
    TO USER (user_y)  -- You can also grant to a role using TO role rolename, then assign the role to user_y.
    FILTER USING (true);  -- Constant true allows access to all data in the table.

    Two scenarios apply:

    • If the table has been set with the policy01 permission, all users (except user_y) can access the Standard storage data of storage_table, but cannot access infrequent access or long-term storage, and any such requests return empty values. The user user_y can access data of all storage classes in storage_table.

    • If the table has not been assigned the policy01 permission, all users (except user_y) cannot access any data stored in storage_table, and such requests return empty values. Only user_y can access data of all storage classes in storage_table.