All Products
Search
Document Center

Container Service for Kubernetes:Best practices for OSS persistent volume performance tuning

Last Updated:Jul 03, 2026

When OSS persistent volume read/write performance (such as latency or throughput) falls short of expectations, use the troubleshooting and optimization practices in this topic to systematically locate and resolve performance issues.

OSS persistent volumes suit sequential read/write workloads that need high bandwidth. For high-concurrency random writes or workloads that depend on extended file attributes (owner, mode), use NAS or CPFS persistent volumes instead.

How the client works

OSS uses a flat object structure, unlike the tree structure of a file system. The Container Storage Interface (CSI) plug-in runs a client on the application node to let containers access OSS through standard POSIX APIs (read, write, stat). Three clients are available:

Client

Best for

Documentation

ossfs 1.0

General-purpose workloads, random writes

Full POSIX support with disk caching

ossfs 2.0

Sequential read/write, high-concurrency small-file reads (recommended)

Higher performance, no random write support

strmvol

Massive small-file read-only workloads

Built-in metadata caching

The client acts as a bidirectional translator. It converts file operations (such as write) into HTTP requests to OSS (such as PUT Object), then converts the OSS response back into a file system response. This translation involves network transmission and protocol overhead. As a result, performance depends on the client type, network conditions, node resources, and application data access patterns.

Choose the right client

Use ossfs 2.0 unless your application requires random writes. ossfs 2.0 and strmvol deliver significant performance improvements over ossfs 1.0 for sequential read/write operations and high-concurrency small-file reads.

To check whether your application performs random writes, mount an ossfs 2.0 persistent volume in a test environment. If the application attempts a random write, an EINVAL error is returned.

To maximize performance, the ossfs 2.0 client does not act on chmod and chown operations (no error is returned, but they have no effect). To set permissions for files or directories under the mount target, add mount parameters to the otherOpts field of the persistent volume (PV):

For detailed guidance, see Client selection reference.

Understand performance expectations

An OSS persistent volume is a network file system. All operations go through network transmission and protocol conversion, so its latency and throughput differ from directly attached local storage. A performance issue means a significant deviation from published benchmark results, not a difference compared to a local disk.

Baseline performance by client:

Troubleshooting approach

This guide covers POSIX-based access to OSS through CSI. If your application uses the OSS SDK directly, see Best practices for OSS performance.
Important

Make sure the CSI plug-in version in your cluster is v1.33.1 or later before you begin. To upgrade, see Manage CSI components.

Follow this three-step process:

  1. Confirm the client meets expectations. Verify that the selected client and its baseline match your scenario.

  2. Check for configuration errors or external bottlenecks. These issues are usually unrelated to application logic. An operations engineer can perform this check.

  3. Optimize application read/write logic and client parameters. This step requires understanding the application's data access patterns. A developer should adjust the code or configuration.

Check for configuration errors and external bottlenecks

Internet endpoint configured on the PV

When your cluster and OSS bucket are in the same region, use an internal endpoint to significantly reduce network latency.

Diagnosis:

kubectl get pv <pv-name> -o jsonpath='{.spec.csi.volumeAttributes.url}'

Fix: If the output shows an Internet endpoint such as http://oss-<region-id>.aliyuncs.com, recreate the PV with an internal endpoint: http://oss-<region-id>-internal.aliyuncs.com.

OSS server throttling

OSS enforces limits on the total bandwidth and queries per second (QPS) for each bucket. In some regions and high-concurrency scenarios (such as workflows), bandwidth or QPS throttling can occur.

Diagnosis: In the OSS console, check the monitoring metrics for the OSS bucket. Look for bandwidth usage and request counts that approach or exceed the limits.

Fixes:

Bottleneck

Scenario

Solution

Bandwidth

Data does not need to be read repeatedly

Attach a disk to the pod for temporary storage. For temporary data, use an elastic ephemeral disk (EED). See Use a dynamically provisioned volume. For disk performance metrics, see Elastic Block Storage performance.

Bandwidth

Data is read repeatedly across replicas or batches

Use a distributed cache such as Fluid with JindoFS to prefetch data from OSS to the cluster's caching system. See Accelerate access to OSS files using JindoFS.

QPS

Frequent metadata operations (ls, stat) or frequent file open/close

Check the client configuration and application read/write method. See Optimize application read/write logic and client parameters.

Region limits

Application is in testing phase

Move to a region with higher bandwidth and QPS limits.

Node bandwidth bottleneck

The client and the application pod run on the same node and share its network resources. In serverless scenarios, they share the resources of a single ACS instance. The node's network bandwidth limit constrains the maximum OSS persistent volume performance.

Diagnosis: Check the node monitoring information or ECS instance monitoring information for a bandwidth bottleneck.

Fixes:

ossfs 1.0 disk throughput limit

The ossfs 1.0 client caches data to disk by default to support full POSIX write operations and ensure data consistency for a single client. This caching uses the /tmp directory of the ossfs pod, which maps to the node's container runtime data disk. The input/output operations per second (IOPS) and throughput caps of this disk directly limit ossfs 1.0 performance.

Diagnosis:

This method does not apply to ContainerOS nodes.
  1. Find the container runtime data disk ID on the node where the application pod runs: Example output:

    If the ID is empty, go to the ECS console - Elastic Block Storage - Disks. Locate the disk by its attached instance, then query its monitoring information.
        kubectl get node <node-name> -o yaml | grep alibabacloud.com/data-disk-serial-id
        alibabacloud.com/data-disk-serial-id: uf69tilfftjoa3qb****
  2. View the disk monitoring information to determine whether the disk has an IOPS or throughput bottleneck.

Fixes:

Scenario

Solution

Read-only or sequential write

Switch to ossfs 2.0, or implement read/write splitting. The ossfs 1.0 client cannot predict whether an open file will be randomly written to, so even read-only operations can trigger disk caching.

Random write

Random writes through a Filesystem in Userspace (FUSE) client such as ossfs 1.0 perform poorly. Modify the application to access OSS directly through the OSS SDK, or switch to a NAS persistent volume.

High disk usage for ossfs 1.0 temporary data

If the container runtime data disk for ossfs 1.0 caching stays at consistently high usage (especially in serverless scenarios), frequent eviction and rotation of temporary data further degrades performance.

Diagnosis:

  1. Identify the container runtime data disk as described in ossfs 1.0 disk throughput limit.

  2. Check disk usage through monitoring. If usage stays high but the application itself writes little data to disk, the performance issue is likely caused by ossfs 1.0 temporary data rotation.

Fixes:

  1. Check application logic. Confirm whether the application holds file descriptors for extended periods (keeps files open). While a file descriptor is held, its related temporary data cannot be released, consuming large amounts of local disk space.

  2. Increase disk capacity. If the application logic is correct and the current disk's maximum throughput meets requirements, increase the disk capacity.

Short RAM authentication TTL

When you use a Resource Access Management (RAM) role for authentication, the ossfs client (versions 1.0 and 2.0) obtains a token and records its expiration time on first access to OSS. To ensure session continuity, the client requests a new token 20 minutes before the current token expires.

The max_session_duration for the RAM role must be longer than 20 minutes.

Example: With a 30-minute session duration, the client refreshes the token after 10 minutes of use (30 - 20 = 10), which does not affect throughput. With a session duration under 20 minutes, the client treats the token as always about to expire and tries to get a new token before every OSS request. This triggers excessive RAM requests and degrades performance.

Diagnosis: The default client log level may not capture frequent token refreshes. Verify that the RAM role configuration is correct.

Fix: See Set the maximum session duration for a RAM role to check and update the maximum session duration.

Optimize application read/write logic and client parameters

Tune metadata caching

Metadata caching reduces time-consuming network requests for high-frequency operations such as ls and stat. If you disable or misconfigure it, the client frequently requests data from OSS to maintain consistency, creating a performance bottleneck.

Diagnosis:

kubectl get pv <pv-name> -o jsonpath='{.spec.csi.volumeAttributes.otherOpts}'

Fixes:

  • Remove cache-disabling options. If the output includes max_stat_cache_size=0 (ossfs 1.0) or close_to_open=true (ossfs 2.0) and your scenario does not require strong consistency, recreate the PV without these parameters.

  • Increase cache size and TTL. If your application reads data that is updated infrequently, increase the metadata cache size and expiration time:

    Client

    Configuration reference

    ossfs 1.0

    Metadata cache

    ossfs 2.0

    Reduce OSS requests and improve mount target performance

    strmvol

    All metadata under the mount target is cached by default and does not expire. No configuration needed.

Disable extended object information (ossfs 1.0 only)

File system metadata such as mode, gid, and uid are extended information for OSS objects. The ossfs 1.0 client makes extra HTTP requests to retrieve this information. Although the client caches metadata (including basic and extended properties) by default, frequent retrieval of extended properties remains a bottleneck.

Two optimization principles apply:

  1. Minimize the number of metadata retrieval operations. See Tune metadata caching.

  2. Avoid requesting high-overhead extended properties to reduce the time cost of each retrieval.

Fixes:

Scenario

Recommendation

Application does not depend on file system metadata

Set the readdir_optimize parameter to disable extended information maintenance. The behavior of chmod, chown, stat, and other operations then matches ossfs 2.0.

Application requires only global permission configuration (for example, non-root containers)

Set readdir_optimize and use gid, uid, file_mode, and dir_mode parameters to set default user and permissions globally.

Application requires fine-grained access policies

Do not use file system permissions for access control. Use OSS server-side authentication (a bucket policy or a RAM policy) to restrict subpath access. Still set readdir_optimize for performance.

Optimize write operations

OSS objects support overwrite only. When the client handles file modifications, it reads the complete object from OSS to the local machine, then uploads the entire file after the file is closed. If the application frequently opens, writes, and closes files, it repeatedly downloads and uploads the full data.

Fixes:

  • Use batch writes instead of multiple writes. Prepare content in memory and write it in a single operation. Some library functions such as Java's FileUtils.write include a complete open, write, and close flow. Calling such functions in a loop causes repeated full-file uploads.

  • Use temporary files for frequent modifications. If a file requires multiple modifications during a processing task, copy it from the OSS mount target to a temporary path in the container (such as /tmp). Perform all modifications on the local file. Copy the final version back to the OSS mount target in one operation.

  • Enable appendable objects for append-write scenarios. If your application only appends small amounts of data (such as writing logs), use ossfs 2.0 with enable_appendable_object=true. The client then uses OSS appendable objects and does not download and re-upload the entire file on each append. Limitations:

    • If the object already exists but is not an appendable object, this approach does not work.

    • enable_appendable_object is a global parameter for the entire persistent volume. All write operations on the volume use the AppendObject API. This affects the performance of overwriting large files but not reading them. Create a dedicated persistent volume for append-write workloads.

Optimize concurrent reads (model loading scenarios)

When multiple processes concurrently read different locations within a single large file, the access pattern resembles random reads. This causes the client to read data redundantly, resulting in abnormally high bandwidth usage. This commonly happens during AI model loading, where multiple concurrent processes read the same model parameter file.

If ossfs 2.0 performance in this scenario is worse than ossfs 1.0, or significantly different from the ossfs 2.0 stress testing benchmarks, this is likely the cause.

Fixes:

Data prefetching (recommended). Before the application pod starts, prefetch data by using high-bandwidth concurrent sequential reads to load model files into the node's page cache. Set the container memory limit slightly higher than the total model size to reduce the risk of the page cache being reclaimed under memory pressure.

Standalone prefetching script (reads file content to /dev/null concurrently):

#!/bin/bash
# Set the maximum concurrency.
MAX_JOBS=4

# Check if a folder is provided as an argument.
if [ -z "$1" ]; then
    echo "Usage: $0 <folder_path>"
    exit 1
fi

DIR="$1"

# Check if the folder exists.
if [ ! -d "$DIR" ]; then
    echo "Error: '$DIR' is not a valid folder."
    exit 1
fi

# Use find to locate all regular files and use xargs to concurrently run cat to /dev/null.
find "$DIR" -type f -print0 | xargs -0 -I {} -P "$MAX_JOBS" sh -c 'cat "{}" > /dev/null'

echo "Finished reading all files."

Integrate this logic into the pod's lifecycle.postStart hook:

# ...
spec:
  containers:
  - image: your-image
    env:
    # Folder path where model files are located. If not configured or the folder does not exist, prefetching is skipped.
    - name: MODEL_DIR
      value: /where/is/your/model/
    # Concurrency for the prefetching script. Default is 4.
    - name: PRELOADER_CONC
      value: "8"
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "CONC=${PRELOADER_CONC:-4}; if [ -d \"$MODEL_DIR\" ]; then find \"$MODEL_DIR\" -type f -print0 | xargs -0 -I {} -P \"$CONC\" sh -c 'cat \"{}\" > /dev/null'; fi"]
# ...

Refactor application logic. Switch from multi-process concurrent reads within a single file to concurrent reads of multiple different files. This leverages the high throughput advantage of OSS.

Production recommendations

  • Client selection: Use ossfs 2.0 unless your application requires random writes that cannot be refactored.

  • Monitoring: Routinely monitor OSS bucket bandwidth and QPS, node network bandwidth, and local disk I/O (for ossfs 1.0). This helps you locate performance issues quickly.

  • Metadata caching: Do not disable metadata caching unless your application requires strong consistency.

  • Data prefetching: For workloads that read large amounts of data (such as AI inference) and have strict startup latency requirements, consider data prefetching. This pre-occupies node resources and bandwidth.

  • Cost awareness: The OSS persistent volume feature and its CSI plug-in components are free. You are charged for the underlying OSS resources: storage capacity, API requests, and outbound traffic. The misconfigurations and access patterns described in this guide (such as disabled caching or Internet endpoints) can cause a surge in API requests and traffic, increasing your OSS costs.

FAQ

Why is an OSS persistent volume much slower than a local disk?

This is expected. An OSS persistent volume is a network file system. All operations go through network transmission and protocol conversion, so its latency and throughput differ from directly attached local storage. Evaluate performance against the published benchmarks:

Why is write performance much worse than read performance?

This is related to the overwrite-only nature of OSS objects. When the client handles file modifications, it first downloads the entire object, then uploads the entire file after modification. This round-trip has high overhead. For optimization guidance, see Optimize write operations.

How do I determine if my application performs random writes?

In a test environment, switch the mounted persistent volume type from ossfs 1.0 to ossfs 2.0. If the application encounters an EINVAL (Invalid argument) error related to file writing, it is performing random write operations that ossfs 2.0 does not support.