Skip to Content
AdvancedCloudflare Workers

Deploying to Cloudflare Workers

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

Why HTTP Client for Cloudflare Workers?

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.

Prerequisites

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

Installation

Install the SDK in your Cloudflare Workers project:

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

Basic Setup

1. Create Worker File

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': '*', }, } ); } }, };

2. Configure Wrangler

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

3. Set Secrets (Production)

For production, use Wrangler secrets instead of environment variables:

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

Advanced Example: Client Reuse

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 }, };

Complete Example: Vector Search API

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': '*', }, } ); } }, };

Deployment

Deploy to Cloudflare Workers

# Login to Cloudflare wrangler login # Deploy wrangler deploy # Deploy to a specific environment wrangler deploy --env production

Test Locally

# 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 }'

Timeout Limits

  • 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 });

Best Practices

  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

Troubleshooting

Error: “gRPC is not supported”

Solution: Use HttpClient instead of MilvusClient.

Error: “Request timeout”

Solution:

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

Error: “Module not found”

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

Next Steps

Last updated on