Skip to content
API Reference Zilliz Cloud Milvus Attu

Deploying to Cloudflare Workers

This guide covers deploying the Milvus Node.js SDK to Cloudflare Workers using the HTTP client.

Cloudflare Workers only support HTTP/HTTPS protocols and do not support raw TCP connections required by gRPC. Therefore, you must use the HttpClient when deploying to Cloudflare Workers.

  • A Cloudflare account
  • Wrangler CLI installed: npm install -g wrangler
  • A Milvus instance (self-hosted or Zilliz Cloud)

Install the SDK in your Cloudflare Workers project:

Terminal window
npm install @zilliz/milvus2-sdk-node
# or
yarn add @zilliz/milvus2-sdk-node

Create src/index.js (or worker.js):

import { HttpClient } from '@zilliz/milvus2-sdk-node';
export default {
async fetch(request, env, ctx) {
const client = new HttpClient({
baseURL: env.MILVUS_ENDPOINT,
token: env.MILVUS_TOKEN,
timeout: 25000, // Cloudflare Workers free tier: 30s, paid: up to 15min
});
try {
const url = new URL(request.url);
const path = url.pathname;
// Handle different endpoints
if (path === '/search' && request.method === 'POST') {
const body = await request.json();
const results = await client.search({
collection_name: body.collection_name || 'my_collection',
data: body.vectors,
limit: body.limit || 10,
output_fields: body.output_fields || [],
});
return new Response(JSON.stringify({ results }), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
});
}
if (path === '/insert' && request.method === 'POST') {
const body = await request.json();
const result = await client.insert({
collection_name: body.collection_name || 'my_collection',
data: body.data,
});
return new Response(JSON.stringify({ result }), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
});
}
return new Response('Not Found', { status: 404 });
} catch (error) {
console.error('Milvus error:', error);
return new Response(
JSON.stringify({
error: error.message,
status: error.status || 500,
}),
{
status: error.status || 500,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
}
},
};

Create wrangler.toml:

name = "milvus-worker"
main = "src/index.js"
compatibility_date = "2024-01-01"
# Environment variables (use secrets for production)
[vars]
# MILVUS_ENDPOINT = "https://your-instance.zillizcloud.com"
# MILVUS_TOKEN = "your-token"
# For production, use secrets instead:
# wrangler secret put MILVUS_ENDPOINT
# wrangler secret put MILVUS_TOKEN
# Worker limits
[limits]
cpu_ms = 50 # CPU time limit in milliseconds

For production, use Wrangler secrets instead of environment variables:

Terminal window
wrangler secret put MILVUS_ENDPOINT
# Enter: https://your-instance.zillizcloud.com
wrangler secret put MILVUS_TOKEN
# Enter: your-api-token

For better performance, reuse the client instance within the same request context:

import { HttpClient } from '@zilliz/milvus2-sdk-node';
let clientCache = null;
function getClient(env) {
if (!clientCache) {
clientCache = new HttpClient({
baseURL: env.MILVUS_ENDPOINT,
token: env.MILVUS_TOKEN,
timeout: 25000,
});
}
return clientCache;
}
export default {
async fetch(request, env, ctx) {
const client = getClient(env);
// ... rest of your code
},
};

Here’s a complete example for a vector search API:

import { HttpClient } from '@zilliz/milvus2-sdk-node';
export default {
async fetch(request, env) {
// Handle CORS preflight
if (request.method === 'OPTIONS') {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
}
const client = new HttpClient({
baseURL: env.MILVUS_ENDPOINT,
token: env.MILVUS_TOKEN,
timeout: 25000,
});
try {
const url = new URL(request.url);
if (url.pathname === '/api/search' && request.method === 'POST') {
const body = await request.json();
if (!body.vector || !body.collection_name) {
return new Response(
JSON.stringify({ error: 'Missing required fields' }),
{
status: 400,
headers: { 'Content-Type': 'application/json' },
}
);
}
const results = await client.search({
collection_name: body.collection_name,
data: [body.vector],
limit: body.limit || 10,
output_fields: body.output_fields || [],
search_params: body.search_params || {},
});
return new Response(JSON.stringify({ results }), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
});
}
return new Response('Not Found', { status: 404 });
} catch (error) {
console.error('Error:', error);
return new Response(
JSON.stringify({
error: error.message,
status: error.status || 500,
}),
{
status: error.status || 500,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
}
},
};
Terminal window
# Login to Cloudflare
wrangler login
# Deploy
wrangler deploy
# Deploy to a specific environment
wrangler deploy --env production
Terminal window
# Start local development server
wrangler dev
# Test with curl
curl -X POST http://localhost:8787/api/search \
-H "Content-Type: application/json" \
-d '{
"collection_name": "my_collection",
"vector": [0.1, 0.2, 0.3],
"limit": 5
}'
  • Free tier: 30 seconds CPU time, 30 seconds wall-clock time
  • Paid tier: Up to 15 minutes CPU time, 30 seconds wall-clock time (can be extended)

Set your timeout accordingly:

const client = new HttpClient({
baseURL: env.MILVUS_ENDPOINT,
token: env.MILVUS_TOKEN,
timeout: 25000, // Leave buffer for Worker overhead
});
  1. Use HTTP Client: Cloudflare Workers only support HTTP/HTTPS, not gRPC
  2. Set appropriate timeouts: Account for Worker execution limits
  3. Handle errors gracefully: Return proper HTTP status codes
  4. Use secrets for credentials: Never commit tokens to your repository
  5. Enable CORS: If calling from browser, set appropriate CORS headers
  6. Client reuse: Reuse client instances within the same request context
  7. Monitor performance: Use Cloudflare Analytics to track execution times

Solution: Use HttpClient instead of MilvusClient.

Solution:

  • Reduce timeout value to leave buffer for Worker overhead
  • Optimize your Milvus queries
  • Consider upgrading to paid tier for longer execution times

Solution: Ensure @zilliz/milvus2-sdk-node is installed and listed in package.json.