All Products
Search
Document Center

PolarDB:Performance testing report

Last Updated:Nov 25, 2025

This report presents the performance benchmark results for PolarDB for PostgreSQL across typical workloads, based on the de facto standard Yahoo! Cloud Serving Benchmark (YCSB). It provides quantitative data to assist with technology selection, application design, and capacity planning. The results demonstrate stable, high-performance read and write capabilities across various data scales. This feature performs exceptionally well in point query (Point Lookup) scenarios. With a 100 GB data volume, the peak performance can reach 109,808 Operations Per Second (OPS).

Test result summary

The following table shows the peak performance (OPS) for each test model at different data volumes.

Test scenario

1 GB data volume (OPS)

10 GB data volume (OPS)

100 GB data volume (OPS)

1 TB data volume (OPS)

100% write (Insert)

41,430

39,861

33,357

36,248

100% update (Update)

44,177

41,486

38,062

30,782

100% read (Read)

80,573

82,856

109,808

75,108

50% read + 50% update

45,010

42,962

39,805

32,021

100% range scan (Scan)

1,073

1,089

1,075

922

Note

The results above are the peak performance values obtained from tests conducted at various concurrency levels.

Test method and environment

Environment configuration

Component

Specifications and configuration

Test cluster (PolarDB)

  • Number of clusters: 1

  • Kernel version: PostgreSQL 14

  • Edition: Enterprise Edition

  • Node specifications: Dedicated, 16-core 64 GB

Stress testing client (ECS)

  • Number of clients: 1

  • Node specifications: 16-core 64 GB

  • Operating system: Alibaba Cloud Linux 3.2104 LTS 64-bit

Deployment region

Beijing, Zone K

Benchmark tool

Workload model

Five typical business scenarios are simulated by configuring the YCSB CoreWorkload. The test data model uses records that each contain 10 fields. Each field has a value with a length of 100 bytes, meaning each record is approximately 1 KB in size.

YCSB Workload

Scenario description

Core parameter configuration

workload_insert_only

100% write

insertproportion=1.0

workload_update_only

100% update

updateproportion=1.0

workload_read_only

100% point query

readproportion=1.0

workload_read_update

50% read + 50% update

readproportion=0.5, updateproportion=0.5

workload_scan_only

100% range query

scanproportion=1.0

Appendix: Test steps

This appendix details the steps to reproduce the performance tests. You can use these steps for secondary authentication or for customized testing.

1. Configure YCSB

Before you run the test, you must configure the YCSB DynamoDB client.

  1. Configure identity credentials

    Edit the dynamodb/conf/AWSCredentials.properties file. Enter the identity credentials for the dedicated DynamoDB account that you created in the PolarDB consoleCreate a dedicated DynamoDB account.

    # The account name is the AccessKey ID
    accessKey = <YOUR_ACCESS_KEY_ID>
    
    # Secret key
    secretKey = <YOUR_SECRET_ACCESS_KEY>
  2. Configure connection properties

    Edit the dynamodb/conf/dynamodb.properties file to specify the connection information for the PolarDB clusterConfigure a DynamoDB endpoint.

    # The absolute path of the authentication file
    dynamodb.awsCredentialsFile = /path/to/your/AWSCredentials.properties
    
    # Create a usertable table in the cluster in advance. This example creates a usertable table with only a partition key named pk.
    dynamodb.primaryKey = pk
    
    # The DynamoDB endpoint for PolarDB. It must include the http:// prefix.
    dynamodb.endpoint = http://<your-polardb-ddb-endpoint>:<port>
    
    # The region parameter must be set to empty.
    dynamodb.region = 
    
    # The primary key name and type for the test table. They must be consistent with the test table.
    dynamodb.primaryKey = HASH

2. Adapt the YCSB Update operation

Important

The official YCSB DynamoDB client uses the deprecated AttributeUpdates parameter to perform updates by default. To ensure compatibility with the new UpdateExpression parameter supported by PolarDB, you must modify the YCSB source code.

  • File path: dynamodb/src/main/java/site/ycsb/db/DynamoDBClient.java

  • Method to modify: update()

Original code

@Override
public Status update(String table, String key, Map<String, ByteIterator> values) {
  if (LOGGER.isDebugEnabled()) {
    LOGGER.debug("updatekey: " + key + " from table: " + table);
  }

  Map<String, AttributeValueUpdate> attributes = new HashMap<>(values.size());
  for (Entry<String, ByteIterator> val : values.entrySet()) {
    AttributeValue v = new AttributeValue(val.getValue().toString());
    attributes.put(val.getKey(), new AttributeValueUpdate().withValue(v).withAction("PUT"));
  }

  UpdateItemRequest req = new UpdateItemRequest(table, createPrimaryKey(key), attributes);

  try {
    dynamoDB.updateItem(req);
  } catch (AmazonServiceException ex) {
    LOGGER.error(ex);
    return Status.ERROR;
  } catch (AmazonClientException ex) {
    LOGGER.error(ex);
    return CLIENT_ERROR;
  }
  return Status.OK;
}

After the update (using UpdateExpression)

@Override
public Status update(String table, String key, Map<String, ByteIterator> values) {
  if (LOGGER.isDebugEnabled()) {
    LOGGER.debug("updatekey: " + key + " from table: " + table);
  }

  StringBuilder updateExp = new StringBuilder("SET ");
  Map<String, String> attrNames = new HashMap<>();
  Map<String, AttributeValue> attrValues = new HashMap<>();
  boolean first = true;
  for (Map.Entry<String, ByteIterator> entry : values.entrySet()) {
    String attr = entry.getKey();
    if (!first) {
      updateExp.append(", ");
    }
    String attrName = "#" + attr;
    String valueName = ":" + attr;
    updateExp.append(attrName).append(" = ").append(valueName);
    attrNames.put(attrName, attr);
    attrValues.put(valueName, new AttributeValue(entry.getValue().toString()));
    first = false;
  }

  UpdateItemRequest req = new UpdateItemRequest()
      .withTableName(table)
      .withKey(createPrimaryKey(key))
      .withUpdateExpression(updateExp.toString())
      .withExpressionAttributeNames(attrNames)
      .withExpressionAttributeValues(attrValues);

  try {
    dynamoDB.updateItem(req);
  } catch (AmazonServiceException ex) {
    LOGGER.error(ex);
    return Status.ERROR;
  } catch (AmazonClientException ex) {
    LOGGER.error(ex);
    return CLIENT_ERROR;
  }
  return Status.OK;
}

3. Run the test

The test is divided into two phases: load (to load the initial data) and run (to run the workload). The following example is for a test with a data volume of 1 GB (1 million records), 128 concurrent threads, and a read-only model:

Note

To test with different data volumes, you can modify the recordcount and operationcount parameters in the command.

  1. Load data (Load Phase)

    # Description:
    # -s: Displays status updates.
    # -P workloads/workload_read_only: Specifies the base workload file.
    # -P /path/to/dynamodb.properties: Specifies the database connection configuration file.
    # -p recordcount=1000000: Defines the total number of records.
    # -p operationcount=1000000: Defines the total number of operations to run.
    # -threads 128: Specifies the number of concurrent threads.
    
    nohup ./bin/ycsb load dynamodb -s \
    -P workloads/workload_read_only \
    -P /path/to/dynamodb.properties \
    -p recordcount=1000000 \
    -p operationcount=1000000 \
    -threads 128 \
    > load.log 2>&1 &
  2. Run the test (Run Phase)

    nohup ./bin/ycsb run dynamodb -s \
    -P workloads/workload_read_only \
    -P /path/to/dynamodb.properties \
    -p recordcount=1000000 \
    -p operationcount=1000000 \
    -threads 128 \
    > run.log 2>&1 &