Skip to content
API Reference Zilliz Cloud Milvus Attu

Advanced Features

This guide covers advanced features including connection pooling, retry mechanisms, error handling, logging, and iterator patterns.

The SDK uses connection pooling to manage gRPC connections efficiently.

const client = new MilvusClient({
address: 'localhost:19530',
pool: {
min: 2, // Minimum pool size
max: 10, // Maximum pool size
idleTimeoutMillis: 30000, // Idle timeout
},
});
  • Efficiency: Reuses connections instead of creating new ones
  • Performance: Reduces connection overhead
  • Resource management: Limits concurrent connections

Configure automatic retries for failed operations.

const client = new MilvusClient({
address: 'localhost:19530',
maxRetries: 3, // Maximum retry attempts
retryDelay: 1000, // Delay between retries (ms)
});

The SDK automatically retries on:

  • Network errors
  • Transient server errors
  • Timeout errors
import { ErrorCode } from '@zilliz/milvus2-sdk-node';
try {
await client.createCollection({ /* ... */ });
} catch (error) {
switch (error.error_code) {
case ErrorCode.CollectionNotExists:
console.error('Collection does not exist');
break;
case ErrorCode.IllegalArgument:
console.error('Invalid argument');
break;
case ErrorCode.UnexpectedError:
console.error('Unexpected error');
break;
default:
console.error('Error:', error);
}
}
  • Success: Operation succeeded
  • CollectionNotExists: Collection not found
  • IllegalArgument: Invalid parameter
  • IndexNotExist: Index not found
  • UnexpectedError: Unexpected server error
  • RateLimit: Rate limit exceeded
  • SchemaMismatch: Schema mismatch
{
error_code: 'CollectionNotExists',
reason: 'Collection my_collection does not exist',
// ... other fields
}

Configure logging levels:

const client = new MilvusClient({
address: 'localhost:19530',
logLevel: 'debug', // 'error', 'warn', 'info', 'debug'
logPrefix: 'milvus-client',
});
  • error: Only error messages
  • warn: Warnings and errors
  • info: Informational messages, warnings, and errors
  • debug: All messages including debug information

Enable trace for detailed debugging:

const client = new MilvusClient({
address: 'localhost:19530',
trace: true,
});

Track and trace individual requests using trace IDs for debugging and monitoring purposes.

The SDK automatically adds a timestamp (client-request-unixmsec) to every request. You can optionally provide a client_request_id (or client-request-id) to track specific requests across your application.

Every request automatically includes a client-request-unixmsec timestamp:

// This request will have client-request-unixmsec automatically added
await client.createCollection({
collection_name: 'my_collection',
fields: [...],
// Timestamp is added automatically, no configuration needed
});

Add a trace ID to track specific requests:

// Recommended: use client_request_id (JavaScript/TypeScript convention)
const traceId = `trace-${Date.now()}`;
await client.createCollection({
collection_name: 'my_collection',
fields: [...],
client_request_id: traceId,
});
// Alternative: use client-request-id (compatible with pymilvus)
await client.createCollection({
collection_name: 'my_collection',
fields: [...],
'client-request-id': traceId,
});

Note: If both formats are provided, client_request_id takes priority (JavaScript/TypeScript convention).

All API methods that extend GrpcTimeOut support trace IDs:

// Insert with trace ID
await client.insert({
collection_name: 'my_collection',
data: [
{ id: 1, vector: [0.1, 0.2, 0.3] },
],
client_request_id: 'insert-trace-123',
});
// Search with trace ID
await client.search({
collection_name: 'my_collection',
vector: [0.1, 0.2, 0.3],
limit: 10,
client_request_id: 'search-trace-456',
});
// Query with trace ID
await client.query({
collection_name: 'my_collection',
expr: 'id > 100',
client_request_id: 'query-trace-789',
});
// All other operations support trace IDs
await client.createIndex({
collection_name: 'my_collection',
field_name: 'vector',
index_type: 'IVF_FLAT',
client_request_id: 'index-trace-101',
});
  1. Request Tracking: Track requests across distributed systems
  2. Debugging: Identify specific requests in logs
  3. Performance Monitoring: Correlate trace IDs with performance metrics
  4. Error Investigation: Trace errors back to specific requests
  • Trace IDs are passed through gRPC metadata
  • Both client_request_id and client-request-id formats are supported
  • Trace IDs are automatically extracted from request parameters
  • The timestamp client-request-unixmsec is automatically added by the interceptor
  • No need to modify API method implementations

Iterate through large query results:

const iterator = await client.queryIterator({
collection_name: 'my_collection',
expr: 'age > 25',
output_fields: ['id', 'text'],
batch_size: 100,
});
while (true) {
const batch = await iterator.next();
if (batch.done) break;
console.log('Batch:', batch.value);
}

Iterate through large search results:

const iterator = await client.searchIterator({
collection_name: 'my_collection',
data: [[0.1, 0.2, 0.3, 0.4]],
limit: 10000,
batch_size: 100,
});
while (true) {
const batch = await iterator.next();
if (batch.done) break;
console.log('Batch:', batch.value);
}

Work with sparse vector data:

// Array format
const sparseVector = [1.0, undefined, undefined, 2.5, undefined];
// Dictionary format
const sparseVector = { '0': 1.0, '3': 2.5 };
// CSR format
const sparseVector = {
indices: [0, 3],
values: [1.0, 2.5],
};
// COO format
const sparseVector = [
{ index: 0, value: 1.0 },
{ index: 3, value: 2.5 },
];
await client.insert({
collection_name: 'my_collection',
data: [
{
sparse_vector: sparseVector,
},
],
});

Work with binary vector data:

// Binary vector: length must be dim / 8
const binaryVector = [1, 0, 1, 0, 1, 0, 1, 0]; // For dim=64
await client.insert({
collection_name: 'my_collection',
data: [
{
binary_vector: binaryVector,
},
],
});

Use transformers for Float16 and BFloat16 vectors:

import { f32ArrayToF16Bytes } from '@zilliz/milvus2-sdk-node';
await client.insert({
collection_name: 'my_collection',
data: [
{
vector: [0.1, 0.2, 0.3, 0.4], // f32 array
},
],
transformers: {
vector: (data) => f32ArrayToF16Bytes(data),
},
});

Enable dynamic fields for flexible schemas:

// Create collection with dynamic fields
await client.createCollection({
collection_name: 'my_collection',
fields: [
{
name: 'id',
data_type: DataType.Int64,
is_primary_key: true,
autoID: true,
},
{
name: 'vector',
data_type: DataType.FloatVector,
dim: 128,
},
],
enable_dynamic_field: true,
});
// Insert data with dynamic fields
await client.insert({
collection_name: 'my_collection',
data: [
{
vector: [/* ... */],
dynamic_field_1: 'value1', // Automatically added
dynamic_field_2: 123, // Automatically added
},
],
});

Get system metrics:

const metrics = await client.getMetric({
request: {
metric_type: 'system_info',
},
});
console.log('Metrics:', metrics);

Get replica information:

const replicas = await client.getReplicas({
collection_name: 'my_collection',
});
console.log('Replicas:', replicas.replicas);
  1. Connection pooling: Configure appropriate pool sizes
  2. Retry configuration: Set reasonable retry limits
  3. Error handling: Always handle errors appropriately
  4. Logging: Use appropriate log levels for your environment
  5. Iterators: Use iterators for large result sets
  6. Monitoring: Monitor metrics for performance optimization