This topic describes how to analyze your MaxCompute cost distribution by using usage records. Analyzing your bills helps you prevent unexpected costs, maximize resource utilization, and reduce your overall spending.
Background
MaxCompute (formerly known as ODPS) is an enterprise-grade SaaS intelligent cloud data warehouse developed by Alibaba Cloud. It is cost-effective, secure, and AI-driven, and supports multiple computing models. Its computing resources are available through two billing methods: subscription and pay-as-you-go. MaxCompute charges you daily based on each project, and bills are generated before 06:00 the next day. For more information about MaxCompute billable items and billing methods, see Billable items and billing methods.
MaxCompute provides insights into bill fluctuations, which are typically cost increases, that can occur during data development or before a product launch. You can analyze these fluctuations to optimize your MaxCompute project jobs. In the Alibaba Cloud Billing Management console, you can download usage records for all billable products. For more information about how to obtain and download bills, see View bill details.
Step 1: Download usage details
Go to the View Usage Details page to download detailed daily usage information and understand how your costs are generated. For example, you can see which jobs generate your daily storage and computing costs.
At the top of the page, the Export instructions section states that usage data is available after 12:00 on the second day of the following month. The usage details are for reference only and may differ from your bill details.
Click Export CSV. After the export is complete, go to the Export Record page to download the usage records file.
Parameters
Time Period: Click to select a start and end time.
If a job runs across two days, for example, starting on December 1 and ending on December 2, you must set the start time to December 1 to find the job in the downloaded usage records. However, the job's costs are included in the December 2 bill.
-
Commodity Name:
-
MaxCompute(Subscription)
-
MaxCompute(Pay-as-you-go)
-
Billable Item: Select an item based on your needs.
-
Billable Item
-
ODPSDataPlus:
This applies when you have only purchased subscription projects and no pay-as-you-go projects in a region. This option provides usage records for pay-as-you-go billable items such as storage and download within the subscription projects.
Before April 25, 2024, if you had both subscription and pay-as-you-go projects enabled in the China (Hong Kong) region or another region outside the Chinese mainland, this applies to usage records for storage and download billable items in projects that used subscription computing quotas by default. To query usage records for projects that used pay-as-you-go quotas by default in this scenario, you must select MaxCompute(Pay-as-you-go).
-
ODPS_QUOTA_USAGE: Usage details for elastically reserved resources for computing and dedicated Tunnel.
MaxCompute(Pay-as-you-go): usage records for pay-as-you-go billable items such as computing, storage, and download.
-
Time Unit: The default is Hour.
Step 2 (optional): Upload usage details to MaxCompute
If you want to analyze usage records by using MaxCompute SQL, follow this step to import the records into MaxCompute. If you only want to use a spreadsheet application like Excel, you can skip this step.
Use the MaxCompute client (odpscmd) to create the
maxcomputefeetable as shown in the following sample statement.CREATE TABLE IF NOT EXISTS maxcomputefee ( projectid STRING COMMENT 'Project ID' ,feeid STRING COMMENT 'Billing information ID' ,meteringtime STRING COMMENT 'File header (MeteringTime)' ,type STRING COMMENT 'Data type, such as Storage, ComputationSQL, or DownloadEx' ,starttime STRING COMMENT 'Start time' ,storage BIGINT COMMENT 'Storage (bytes)' ,endtime STRING COMMENT 'End time' ,computationsqlinput BIGINT COMMENT 'SQL/Interactive analysis read volume (bytes)' ,computationsqlcomplexity DOUBLE COMMENT 'SQL complexity' ,uploadex BIGINT COMMENT 'Inbound public traffic (bytes)' ,download BIGINT COMMENT 'Outbound public traffic (bytes)' ,cu_usage DOUBLE COMMENT 'MapReduce/Spark job computing (core*seconds)' ,Region STRING COMMENT 'Region' ,input_ots BIGINT COMMENT 'Data input from Tablestore (bytes)' ,input_oss BIGINT COMMENT 'Data input from OSS (bytes)' ,source_id STRING COMMENT 'DataWorks scheduled job ID' ,source_type STRING COMMENT 'Computing resource specification' ,RecycleBinStorage BIGINT COMMENT 'Backup storage (bytes)' ,JobOwner STRING COMMENT 'Job owner' ,Signature STRING COMMENT 'SQL job signature' );The following list describes the fields in the usage records.
Project ID: The list of MaxCompute projects for the current Alibaba Cloud account or the account to which the RAM user belongs.
Billing information ID: The billing ID, which is the task ID for storage and computing tasks, the InstanceID for SQL jobs, and the Tunnel SessionId for upload and download tasks.
Data type: Includes Standard Storage (Storage), SQL Computing (ComputationSql), Inbound Private Traffic (UploadIn), Outbound Private Traffic (DownloadIn), Inbound Public Traffic (UploadEx), and Outbound Public Traffic (DownloadEx). Only specific types are billable items.
Storage (bytes): The amount of storage read per hour, in bytes.
Start time or End time: Jobs are metered based on their actual execution time. Only storage usage is sampled once every hour.
SQL/Interactive analysis read volume (bytes): For SQL computing, this is the input data volume for each SQL execution, in bytes.
SQL complexity: The complexity of the SQL statement, which is a billing factor.
Inbound public traffic (bytes) or Outbound public traffic (bytes): The data volume for public uploads or downloads, respectively, in bytes.
MapReduce/Spark job computing (core*seconds): The unit for MapReduce or Spark job computation is core-seconds (
core*seconds). You need to convert this to core-hours for billing.Data input from Tablestore (bytes), Data input from OSS (bytes): The volume of data read from billable external tables, in bytes.
Backup storage (bytes): The amount of backup storage read per hour, in bytes.
Region: The region where the MaxCompute project is located.
Job owner: The user who submitted the job.
SQL job signature: This signature identifies an SQL job.
Upload data by using Tunnel.
When you upload the CSV file, ensure that the number of columns and data types in the file match those in the
maxcomputefeetable. Otherwise, the import will fail.tunnel upload ODPS_2019-01-12_2019-01-14.csv maxcomputefee -c "UTF-8" -h "true" -dfp "yyyy-M-d HH:mm";For more information about Tunnel configurations, see Tunnel commands.
You can also use the data import feature in DataWorks to perform this operation. For more information, see Use DataWorks (Batch and Real-time).
Run the following statement to verify the data.
SELECT * FROM maxcomputefee limit 10;
Step 3: Analyze billing data
Analyze SQL costs
SQL jobs are used by over 95% of MaxCompute users and typically account for a large portion of spending.
Fee for one SQL job = Input data volume × SQL complexity × Unit price (USD 0.0438/GB)
-
Method 1: Analyze with a spreadsheet
Analyze the data categorized as ComputationSql in the usage records table. Check if the cost of certain SQL jobs exceeds expectations or if there are too many SQL tasks. The cost of an SQL job is calculated by using the following formula:
SQL/Interactive Analytics Read Volume (Bytes) / 1024 / 1024 / 1024 × SQL Complexity × SQL Unit Price.For example, for a standard SQL task with a data read of
7352600872 bytes, the cost isSQL data read (7352600872 bytes / 1024 / 1024 / 1024) × SQL complexity of 1 × 0.0438 USD/(GB × complexity) = 0.292 USD.If your bill suddenly increases, first check if your subscription resource package has been depleted. After the computing quota in your resource package is exhausted, any excess usage is automatically billed on a pay-as-you-go basis (at a unit price of USD 0.0438 per GB × complexity), which can lead to a sudden cost spike.
To locate a high-cost SQL job, follow these steps:
-
In the usage details CSV, filter for records where the data category is ComputationSql and sort them in descending order by SQL/Interactive Analytics Read Volume (Bytes) (the
computationsqlinputfield) to find the record with the largest read volume. -
Record the metering information ID of the entry (that is, the
feeidfield). -
In the MaxCompute client (odpscmd) or DataWorks, run the
wait <instanceid>;command to get the Logview URL. Open the URL in your browser to view the SQL content and locate the high-cost job.
-
-
Method 2: Analyze with SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable: -- Analyze SQL consumption, ranked by sqlmoney. SELECT to_char(endtime,'yyyymmdd') as ds,feeid as instanceid ,projectid ,computationsqlcomplexity -- Complexity ,SUM((computationsqlinput / 1024 / 1024 / 1024)) as computationsqlinput -- Data input (GB) ,SUM((computationsqlinput / 1024 / 1024 / 1024)) * computationsqlcomplexity * 0.0438 AS sqlmoney FROM maxcomputefee WHERE TYPE = 'ComputationSql' AND to_char(endtime,'yyyymmdd') >= '20190112' GROUP BY to_char(endtime,'yyyymmdd'),feeid ,projectid ,computationsqlcomplexity ORDER BY sqlmoney DESC LIMIT 10000 ;
The query results can lead to the following conclusions:
For large jobs, you can reduce costs by decreasing the amount of data read and lowering the SQL complexity.
Aggregate the data by the
dsfield (by day) to analyze the trend of SQL consumption costs over a period of time. For example, you can use tools such as a local Excel file or Quick BI to plot a line chart for a more intuitive visualization of the job's trend.-
Use the results to pinpoint optimization targets:
-
Get the Logview URL of the target instance's run log by using the queried instanceid.
In the MaxCompute client (odpscmd) or DataWorks, run the
wait <instanceid>;command to view the instance's run log.wait 20xxx162741579glgfd9o7; --- Run log --- ID = 20xxx3162741579glgfd9o7 Log view: http://logview.odps.aliyun.com/logview/?h=http://service.cn.maxcompute.aliyun-inc.com/api&p=xxx&i=20220318162741579glgfd9o7&token=dW1OQXBjRW5SR1FvSUprZGZSeHYyVkFycys4PSxPRFBTX09CTzoxMzk2OTkzxxxbnQi0lt7IkFjdG1vbI16WyJvZHBzOlJlYWQiXSwlRWzmN0RjolQWxsb3ciLCJSZXNvdXJjZS16WyJhY3M6b2RwczoqOioiXX0xxx 1Y3RzL2Jpb19kb2NfdGVzdC9pbnN0YW5jZXMvMjAyMjAzMTgxNjI3NDE1NzlnbGdmZDlvNyJdfVxxx Job Queueing... Run the following command to view the detailed information of the job.
DESC instance 2016070102275442go3xxxxxx;The following result is returned:
ID 2016070102275442go3xxxxxx Owner ALIYUN$***@aliyun-inner.com StartTime 2016-07-01 10:27:54 EndTime 2016-07-01 10:28:16 Status Terminated console_query_task_1467340078684 Success Query select count(*) from src where ds='20160628';-
Open the Logview URL in a browser. On the SourceXML tab of the Logview page, get the SKYNET_NODENAME for the instance.
<?xml version="1.0" encoding="UTF-8"?> <Job> <Priority>8</Priority> <Tasks> <SQL> <Name>console_query_task_1647620861362</Name> <Config> <Property> <Name>settings</Name> <Value>{"SKYNET_BUSINESS_NAME":"-","WRAPPER_SQLSEQ":"1","WRAPPER_RETRYNUM":"1","odps.idata.useragent":"CLT(0.37.7 : 6c02e41); Linux(/)","SKYNET_DAGTYPE":"0","SKYNET_ONDUTY":"280316532466682512","SKYNET_SYSTEMID":"-","SKYNET_BIZDATE":"202xxx18","SKYNET_CYCTIME":"20220xxx0100","SKYNET_PACKAGEID":"-","SKYNET_BUSINESS_ID":"-","SKYNET_PRIORITY":"1","SKYNET_TASKID":"43293xxx99","biz_id":"1002778435_20220318_4329323699_43115527_xxx_xxx_xxx_16532466682512_428543003249281","SKYNET_TENANT_ID":"4285xxx49281","SKYNET_ID":"1002xxx35","SKYNET_JOBID":"4311xxx2","SKYNET_NODENAME":"rpxxx_xxx_xxxg","LINK_FILE_ID":"-","odps.sql.select.output.format":"HumanReadable","odps.idata.userenv":"JavaSDK Revision:013e16b,Version:0.37.10,JavaVersion:1.8.0_112,IP:unknown,MAC:unknown"}</Value> ...NoteFor more information about Logview, see Use Logview 2.0 to view job run information.
If you cannot obtain SKYNET_NODENAME or SKYNET_NODENAME has no value, you can obtain the code snippet from the SQL Script tab and then search for the snippet in DataWorks to find and optimize the target node. For more information, see DataWorks Code Search.
In DataWorks, search for the queried SKYNET_NODENAME to optimize the target node.
-
Analyze job growth trends
Typically, an increase in costs is caused by a surge in the number of jobs, often resulting from repeated executions or improperly configured scheduling properties.
Method 1: Analyze with a spreadsheet
Analyze the data where the data type is ComputationSql in your usage records. Count the number of jobs per day for each project and check whether the number of jobs for any project fluctuates significantly.
Method 2: Analyze with SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable:-- Analyze job growth trends. SELECT TO_CHAR(endtime,'yyyymmdd') AS ds ,projectid ,COUNT(*) AS tasknum FROM maxcomputefee WHERE TYPE = 'ComputationSql' AND TO_CHAR(endtime,'yyyymmdd') >= '20190112' GROUP BY TO_CHAR(endtime,'yyyymmdd') ,projectid ORDER BY tasknum DESC LIMIT 10000 ;The execution results show the fluctuation in the number of successful jobs submitted to MaxCompute from the 12th to the 14th.
Analyze storage costs
-
Analyze the reason for a USD 0.00001 storage charge by using a spreadsheet:
You activate MaxCompute for trial use and find a daily charge of USD 0.00001 even with no active business. This is typically because some data, less than 0.5 GB, remains stored in MaxCompute.
View the Storage billable item in the Data type column. For example, the
maxcompute_docproject contains 508 bytes of data. According to the storage cost billing rules, you are charged USD 0.00001 for data storage up to 512 MB. The usage details in the exported CSV file show columns for Project ID (maxcompute_doc), Billing information ID, Data type (Storage), and Storage (bytes). Each record indicates a storage amount of 508 bytes, confirming that a small amount of residual data is generating the cost. If this data is only for testing, you can resolve this issue in one of the following ways:If the table data is no longer used, execute the
Drop Tablestatement to delete the table data in the project.If the project is no longer needed, delete the project from the page in the MaxCompute console.
-
Analyze storage costs for
less than one dayby using a spreadsheet:View the Storage billable item in the Data type. Assume that 333,507,833,900 bytes of data are stored in the alian (example project name) project. Since the data was uploaded at 8:00, storage charges are metered starting from 09:07 for a total of 15 hours.
The daily metering period ends at the end of the day, so the last record is not included in the bill for April 4.
-
According to the storage billing rules, first calculate the 24-hour average storage, and then calculate the cost using the billing formula.
-- Calculate average storage. 333,507,833,900 bytes × 15 / 1024 / 1024 / 1024 / 24 = 194.127109076362103 GB -- The storage cost for one day is calculated as follows, with the result rounded to four decimal places. 194.127109076362103 GB × USD 0.0006/GB/day = USD 0.1165/day
-
Analyze the distribution of storage costs by using SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable:-- Analyze storage costs. SELECT t.ds ,t.projectid ,t.storage ,CASE WHEN t.storage < 0.5 THEN t.storage*0.0015 -- When the actual data storage of the project is greater than 0 MB and less than or equal to 512 MB, the unit price is USD 0.0015/GB/day. WHEN t.storage >= 0.5 THEN t.storage*0.0006 -- When the actual data storage of the project is greater than 512 MB, the unit price is USD 0.0006/GB/day. END storage_fee FROM ( SELECT to_char(starttime,'yyyymmdd') as ds ,projectid ,SUM(storage/1024/1024/1024)/24 AS storage FROM maxcomputefee WHERE TYPE = 'Storage' and to_char(starttime,'yyyymmdd') >= '20190112' GROUP BY to_char(starttime,'yyyymmdd') ,projectid ) t ORDER BY storage_fee DESC ;The following execution result is for demonstration only. The query returns three records sorted in descending order by
storage_fee: on 2019-01-13, the storage was approximately 8,467 GB, costing about CNY 73.31; on 2019-01-12, the storage was about 4,527 GB, costing about CNY 40.22; and on 2019-01-14, the storage was about 2,672 GB, costing about CNY 24.63. The execution results can lead to the following conclusions:Storage increased on the 12th and decreased on the 14th.
For storage optimization, we recommend setting a lifecycle for tables and deleting unused temporary tables.
-
Analyze the distribution of archive storage, infrequent access storage, archive storage access, and infrequent access storage access by using SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable:-- Analyze archive storage costs. SELECT to_char(starttime,'yyyymmdd') as ds ,projectid ,SUM(storage/1024/1024/1024)/24*0.0011 AS longTerm_storage FROM maxcomputefee WHERE TYPE = 'ColdStorage' and to_char(starttime,'yyyymmdd') >= '20190112' GROUP BY to_char(starttime,'yyyymmdd') ,projectid; -- Analyze infrequent access storage costs. SELECT to_char(starttime,'yyyymmdd') as ds ,projectid ,SUM(storage/1024/1024/1024)/24*0.0011 AS lowFre_storage FROM maxcomputefee WHERE TYPE = 'LowFreqStorage' and to_char(starttime,'yyyymmdd') >= '20190112' GROUP BY to_char(starttime,'yyyymmdd') ,projectid; -- Analyze archive storage access costs. SELECT to_char(starttime,'yyyymmdd') as ds ,projectid ,SUM(computationsqlinput/1024/1024/1024)*0.522 AS longTerm_IO FROM maxcomputefee WHERE TYPE = 'SqlLongterm' and to_char(starttime,'yyyymmdd') >= '20190112' GROUP BY to_char(starttime,'yyyymmdd') ,projectid; -- Analyze infrequent access storage access costs. SELECT to_char(starttime,'yyyymmdd') as ds ,projectid ,SUM(computationsqlinput/1024/1024/1024)*0.522 AS lowFre_IO FROM maxcomputefee WHERE TYPE = 'SqlLowFrequency' and to_char(starttime,'yyyymmdd') >= '20190112' GROUP BY to_char(starttime,'yyyymmdd') ,projectid;
Analyze download costs
For data downloads over the public internet or across regions, MaxCompute charges based on the amount of data downloaded.
Download cost = Downloaded data volume × Unit price (USD 0.1166/GB)
Method 1: Analyze with a spreadsheet
The data type DownloadEx represents the billable item for public downloads.
Based on the Download fees (pay-as-you-go) pricing, outbound public traffic of approximately 0.036 GB (38,199,736 bytes) incurs a fee of
(38,199,736 bytes/1024/1024/1024) × 0.1166 USD/GB = 0.004 USD.Example of download optimization: Check your Tunnel service settings to see if costs are being incurred due to using a public network endpoint. For more information, see Endpoints. If you are downloading large amounts of data from the China (Shanghai) region to a location outside that region's internal network (such as an on-premises server in Suzhou), you can first download the data to an ECS virtual machine (VM) within the China (Shanghai) region to leverage internal network traffic.
Method 2: Analyze with SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable:-- Analyze download consumption details. SELECT TO_CHAR(starttime,'yyyymmdd') AS ds ,projectid ,SUM((download/1024/1024/1024)*0.1166) AS download_fee FROM maxcomputefee WHERE type = 'DownloadEx' AND TO_CHAR(starttime,'yyyymmdd') >= '20190112' GROUP BY TO_CHAR(starttime,'yyyymmdd') ,projectid ORDER BY download_fee DESC ;
Analyze MapReduce job costs
Daily computing cost for a MapReduce job = Total computing hours for the day × Unit price (USD 0.0690/Hour/Task)
Method 1: Analyze with a spreadsheet
Analyze the data where the data type is MapReduce in your usage records. Calculate and sort the costs of MapReduce jobs by computing resource specification. The formula for calculating the cost of a MapReduce job is
(MapReduce/Spark job computing (core*seconds) / 3600) × Unit price (USD 0.0690).Method 2: Analyze with SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable:-- Analyze MapReduce job consumption. SELECT TO_CHAR(starttime,'yyyymmdd') AS ds ,projectid ,(cu_usage/3600)*0.0690 AS mr_fee FROM maxcomputefee WHERE type = 'MapReduce' AND TO_CHAR(starttime,'yyyymmdd') >= '20190112' GROUP BY TO_CHAR(starttime,'yyyymmdd') ,projectid ,cu_usage ORDER BY mr_fee DESC ;
Analyze external table job costs (Tablestore and OSS)
Computing cost for one SQL external table job = Input data volume × Unit price (USD 0.0044/GB)
Method 1: Analyze with a spreadsheet
Analyze the data where the data type is ComputationSqlOTS or ComputationSqlOSS in your usage records. Sort the computing costs for SQL external table jobs. The cost is calculated using the formula:
(SQL/interactive analysis read volume (bytes) / 1024 / 1024 / 1024) × Unit price (USD 0.0044).-
Method 2: Analyze with SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable:-- Analyze Tablestore external table SQL job consumption. SELECT TO_CHAR(starttime,'yyyymmdd') AS ds ,projectid ,(computationsqlinput/1024/1024/1024)*1*0.0044 AS ots_fee FROM maxcomputefee WHERE type = 'ComputationSqlOTS' AND TO_CHAR(starttime,'yyyymmdd') >= '20190112' GROUP BY TO_CHAR(starttime,'yyyymmdd') ,projectid ,computationsqlinput ORDER BY ots_fee DESC ; -- Analyze OSS external table SQL job consumption. SELECT TO_CHAR(starttime,'yyyymmdd') AS ds ,projectid ,(computationsqlinput/1024/1024/1024)*1*0.0044 AS oss_fee FROM maxcomputefee WHERE type = 'ComputationSqlOSS' AND TO_CHAR(starttime,'yyyymmdd') >= '20190112' GROUP BY TO_CHAR(starttime,'yyyymmdd') ,projectid ,computationsqlinput ORDER BY oss_fee DESC ;
Analyze Spark computing costs
Daily computing cost for a Spark job = Total computing hours for the day × Unit price (USD 0.1041/Hour/Task)
Method 1: Analyze with a spreadsheet
Analyze the data where the data type is Spark in your usage records. Sort the job costs. The cost is calculated using the formula:
(MapReduce/Spark job computing (core*seconds) / 3600) × Unit price (USD 0.1041).Method 2: Analyze with SQL
This method requires you to have completed Step 2 and generated the
maxcomputefeetable:-- Analyze Spark job consumption. SELECT TO_CHAR(starttime,'yyyymmdd') AS ds ,projectid ,(cu_usage/3600)*0.1041 AS spark_fee FROM maxcomputefee WHERE type = 'spark' AND TO_CHAR(starttime,'yyyymmdd') >= '20190112' GROUP BY TO_CHAR(starttime,'yyyymmdd') ,projectid ,cu_usage ORDER BY spark_fee DESC ;