FeatureDB is a distributed KV database for online feature storage in PAI-FeatureStore. It delivers millisecond-latency reads and writes for search, recommendation, and advertising workloads.
What is FeatureDB
FeatureDB stores features in KV and KKV formats with native Array and Map support. Unlike serialized string storage, structured storage improves read, write, and inference performance. FeatureDB handles offline features, real-time features, and behavior sequences within a single system.
FeatureDB shards data within each feature view and adjusts shard count based on your Estimated Order of Magnitude:
| Data volume | Shard count |
|---|---|
| Less than 10 million (default) | 5 |
| 10 million–100 million | 10 |
| More than 100 million | 20 |
Replicas are supported for data stability. Shard count scales up as performance needs grow.

Activate FeatureDB
Activate FeatureDB when creating a FeatureDB data store by following the interface prompts.
Capabilities
FeatureDB provides:
Read and write KV and KKV features
Read and write MaxCompute complex types (Array and Map)
Pull all feature data in a feature view
Millisecond polling for real-time feature updates
Second-level TTL (time-to-live) with automatic expired data cleanup
Pay-as-you-go billing based on actual operations
Advantages
Lower costs
Reduces storage expenses, particularly for smaller feature sets.
High-frequency updates
Real-time statistical features update every few seconds across multiple EasyRec Processor instances.
Native complex types
Search and advertising workloads commonly use Array, Map, behavior sequences, and SideInfo. String serialization degrades performance at scale. FeatureDB stores these types natively and synchronizes MaxCompute 2.0 complex data, enabling high-performance reads without deserialization overhead.
Elastic scaling
Increase shards per feature view to scale read and write throughput for larger deployments.
Comprehensive monitoring
Monitor read/write QPS, RT, data update latency, and storage at feature view granularity. This eliminates blind spots when integrating third-party data sources.
Low latency
With VPC direct connection configured and your online service deployed in a recommended zone, single-key reads achieve an average latency of 0.89 ms and TP99 of 1.45 ms (260-column feature table, 17.7M rows, tested with FeatureStore Go SDK on a 4-core/8 GiB machine). See Performance benchmarks for full results.
How it works
The FeatureStore storage service has three components: Feature Service (access layer), MSMQ (DataHub), and FeatureDB.
Write path: Write real-time features to FeatureDB via FeatureStore Java SDK or Flink Connector. Data also synchronizes to your MaxCompute table for feature export and model training.
Read path: Read features via FeatureStore Java/Go SDK, or use EasyRec Processor to pull all features into local cache for higher throughput. Real-time features are available within milliseconds of being written.
Set up VPC direct connection
FeatureDB uses PrivateLink to provide VPC (Virtual Private Cloud) direct connection. After configuration, access FeatureDB from your VPC via FeatureStore SDK through a private connection, improving throughput and reducing latency.
Method 1: No existing FeatureDB data store
On the Store tab, click Create Source.
Under VPC Direct Connection Configurations, set VPC, Zone and vSwitch, and Security Group Name.
For details, see Online data store: FeatureDB.
Method 2: Existing FeatureDB data source
On the Store tab, click feature_db.
Click VPC Direct Connection Configurations.
Specify VPC, Zone and vSwitch, and Security Group Name, then click OK.
Configuration notes
VPC is immutable after initial configuration. Set it to the VPC where your online service using FeatureStore resides.
Zone and vSwitch: Select a vSwitch in the zone where your online service instance runs. Select vSwitches in at least two zones for high availability.
After confirmation, configurations are immutable except for adding vSwitches in other zones.
Deploy your service in a recommended zone to minimize network latency:
| Area | Region | Recommended zone |
|---|---|---|
| Asia Pacific | China (Hangzhou) | Zone G |
| Asia Pacific | China (Shanghai) | Zone L |
| Asia Pacific | China (Beijing) | Zone F |
| Asia Pacific | China (Shenzhen) | Zone F |
| Asia Pacific | China (Hong Kong) | Zone B |
| Asia Pacific | Singapore | Zone C |
| Europe and Americas | Germany (Frankfurt) | Zone A |
| Europe and Americas | United States (Silicon Valley) | Zone B |
Write data
Offline features: Use FeatureStore Python SDK to run scheduled tasks through DataWorks, synchronizing data from MaxCompute to FeatureDB.
For real-time features, write feature data directly using Java SDK.
// Initialize configuration with region, credentials, and project
Configuration configuration = new Configuration("cn-beijing",
Constants.accessId, Constants.accessKey,"fs_demo_featuredb" );
// Set FeatureDB credentials
configuration.setUsername(Constants.username);
configuration.setPassword(Constants.password);
// For public network access, set domain (omit for VPC)
//configuration.setDomain(Constants.host);
ApiClient client = new ApiClient(configuration);
// For public network, set usePublicAddress = true (omit for VPC)
// FeatureStoreClient featureStoreClient = new FeatureStoreClient(client, Constants.usePublicAddress);
FeatureStoreClient featureStoreClient = new FeatureStoreClient(client );
// Get project and feature view
Project project = featureStoreClient.getProject("fs_demo_featuredb");
if (null == project) {
throw new RuntimeException("project not found");
}
FeatureView featureView = project.getFeatureView("user_test_2");
if (null == featureView) {
throw new RuntimeException("featureview not found");
}
// Prepare sample data
List<Map<String, Object>> writeData = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Map<String, Object> data = new HashMap<>();
data.put("user_id", i);
data.put("string_field", String.format("test_%d", i));
data.put("int32_field", i);
data.put("int64_field", Long.valueOf(i));
data.put("float_field", Float.valueOf(i));
data.put("double_field", Double.valueOf(i));
data.put("boolean_field", i % 2 == 0);
writeData.add(data);
}
// Write data in batches
for (int i = 0; i < 100;i++) {
featureView.writeFeatures(writeData);
}
// Flush all writes (call once after all writes complete)
featureView.writeFlush();
Real-time features: Write directly using the Java SDK.
// Initialize configuration with region, credentials, and project
Configuration configuration = new Configuration("cn-beijing",
Constants.accessId, Constants.accessKey, "fs_demo_featuredb");
// Set FeatureDB credentials
configuration.setUsername(Constants.username);
configuration.setPassword(Constants.password);
// For public network access, set domain (omit for VPC)
//configuration.setDomain(Constants.host);
ApiClient client = new ApiClient(configuration);
// For public network, set usePublicAddress = true (omit for VPC)
// FeatureStoreClient featureStoreClient = new FeatureStoreClient(client, Constants.usePublicAddress);
FeatureStoreClient featureStoreClient = new FeatureStoreClient(client);
// Get project and feature view
Project project = featureStoreClient.getProject("fs_demo_featuredb");
if (null == project) {
throw new RuntimeException("project not found");
}
FeatureView featureView = project.getFeatureView("user_test_2");
if (null == featureView) {
throw new RuntimeException("featureview not found");
}
// Prepare sample data
List<Map<String, Object>> writeData = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Map<String, Object> data = new HashMap<>();
data.put("user_id", i);
data.put("string_field", String.format("test_%d", i));
data.put("int32_field", i);
data.put("int64_field", Long.valueOf(i));
data.put("float_field", Float.valueOf(i));
data.put("double_field", Double.valueOf(i));
data.put("boolean_field", i % 2 == 0);
writeData.add(data);
}
// Write data in batches
for (int i = 0; i < 100; i++) {
featureView.writeFeatures(writeData);
}
// Flush all writes (call once after all writes complete)
featureView.writeFlush();By default, each write overwrites the entire row—unwritten fields are cleared. To update only specific fields while preserving others, use partial field write mode:
Java SDK: Pass
InsertMode.PartialFieldWritetowriteFeatures.for (int i = 0; i < 100; i++) { featureView.writeFeatures(writeData, InsertMode.PartialFieldWrite); }Flink Connector: Set
insert_modetopartial_field_write.
Read data
Read features using FeatureStore SDK (Go or Java) or EasyRec Processor.
| Client | Query type | Details |
|---|---|---|
| FeatureStore Go/Java SDK | KV point queries | Specify JoinID (primary key) and feature name. Returns results in milliseconds. |
| FeatureStore Go/Java SDK | KKV queries (behavior sequences) | Specify UserID to retrieve assembled behavior sequences. |
| EasyRec Processor | Full feature pull | Integrates FeatureStore C++ SDK. Pulls all features from FeatureDB into local memory with millisecond polling for real-time updates. Achieves higher read throughput than per-key queries. |
Monitor metrics
After creating a feature view with FeatureDB as the online data source, click Data Monitoring on the right side of the target view to see read/write QPS and RT per feature view.

Manage feature lifecycle
Specify Feature Lifecycle when creating a real-time feature view. Rows that reach the lifecycle threshold expire and are automatically deleted within seconds.

Survival time is calculated using one of two methods:
Method 1: No Event Time field
Survival time starts from the actual data write time.
Method 2: Event Time field enabled (unit: milliseconds)
Let event_time be the Event Time value, time_now be the current time, and time_ttl = time_now - TTL be the expiration threshold.
| Condition | Behavior |
|---|---|
event_time > time_now + 15 min | Data is not written. The 15-minute buffer prevents timestamp skew between systems. |
time_ttl < event_time <= time_now + 15 min | Written normally. Survival time starts from event_time; data expires after the lifecycle period. |
0 < event_time < time_ttl | Written, but expires immediately after write. |
event_time <= 0 | Survival time starts from actual write time. |
| Invalid value (cannot convert to integer) | Data is not written. |
| Event Time field registered, but no value passed | Written normally. Survival time starts from actual write time. |
| No Event Time field | Written normally. Survival time starts from actual write time. |
Additional rules:
In PartialFieldWrite mode, survival time always uses the actual write time, regardless of
event_time.event_timebecomes the row timestamp (ts) in FeatureDB. To update an existing key, the newevent_timemust equal or exceed the previous value—otherwise the update is dropped.Event Time unit is milliseconds. If your field stores seconds, writes will fail silently.
Performance benchmarks
The following results use FeatureStore Go SDK to read a feature table with 17,689,586 rows of user-side recommendation data and 260 feature columns. Test machine: 4 cores, 8 GiB memory. Results are for reference only.
VPC direct connection, recommended zone
| Keys read | Average latency | TP95 | TP99 |
|---|---|---|---|
| 1 | 0.89 ms | 1.20 ms | 1.45 ms |
| 10 | 1.17 ms | 1.52 ms | 1.87 ms |
| 50 | 1.91 ms | 2.56 ms | 2.92 ms |
| 100 | 2.87 ms | 3.58 ms | 3.93 ms |
| 200 | 4.43 ms | 5.25 ms | 5.80 ms |
VPC direct connection, non-recommended zone
| Keys read | Average latency | TP95 | TP99 |
|---|---|---|---|
| 1 | 2.54 ms | 2.86 ms | 3.15 ms |
| 10 | 2.75 ms | 3.12 ms | 3.56 ms |
| 50 | 3.95 ms | 4.75 ms | 5.19 ms |
| 100 | 4.82 ms | 5.66 ms | 6.21 ms |
| 200 | 6.84 ms | 7.75 ms | 8.25 ms |
No VPC direct connection
| Keys read | Average latency | TP95 | TP99 |
|---|---|---|---|
| 1 | 3.62 ms | 3.83 ms | 4.27 ms |
| 10 | 3.82 ms | 4.11 ms | 4.61 ms |
| 50 | 4.54 ms | 5.19 ms | 5.60 ms |
| 100 | 5.40 ms | 6.13 ms | 6.56 ms |
| 200 | 7.15 ms | 7.93 ms | 8.47 ms |
Billing
For billing details, see Billing of FeatureStore. FeatureDB uses pay-as-you-go pricing based on actual operations.