This example demonstrates how to deploy a VoltAgent AI agent to Cloudflare Workers using in-memory storage adapters for edge-compatible, serverless deployment.
- 🚀 Edge Deployment: Runs on Cloudflare's global network for low-latency responses
- 💾 In-Memory Storage: Uses lightweight in-memory adapters perfect for serverless
- 🤖 OpenAI Integration: Powered by GPT-4 models via OpenAI API
- 🔍 Vector Search: In-memory vector search for semantic queries
- 🛠️ Built-in Tools: Example weather tool to demonstrate capabilities
- 📊 Health Monitoring: Health check and info endpoints
- 🌍 Global Scale: Deploy to 300+ cities worldwide
- Node.js 20+ installed
- Cloudflare account (free tier available)
- OpenAI API key
- Wrangler CLI (installed via npm)
npm installCopy the example environment file and add your OpenAI API key:
cp .env.example .dev.varsEdit .dev.vars and add your OpenAI API key:
OPENAI_API_KEY=sk-your-openai-api-key-here
If you plan to connect to VoltOps while developing locally, you can also add:
VOLTAGENT_PUBLIC_KEY=pub-...
VOLTAGENT_SECRET_KEY=sec-...
Start the development server locally:
npm run devYour agent will be available at http://localhost:8787
Test the agent:
# Health check
curl http://localhost:8787/health
# Get agent info
curl http://localhost:8787/info
# List available agents
curl http://localhost:8787/agents
# Chat with the agent
curl -X POST http://localhost:8787/agents/agent/invoke \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "What is the weather in Paris, France?"}]
}'- Login to Cloudflare:
npx wrangler login- Set your OpenAI API key as a secret:
npx wrangler secret put OPENAI_API_KEY
# Paste your API key when promptedOptional (only if you are connecting to VoltOps):
npx wrangler secret put VOLTAGENT_PUBLIC_KEY
npx wrangler secret put VOLTAGENT_SECRET_KEYDeploy to development environment:
npm run deployDeploy to production:
npm run deploy:productionYour agent will be deployed to a URL like: https://voltagent-cloudflare.your-subdomain.workers.dev
with-cloudflare-deployment/
├── src/
│ └── index.ts # Main agent configuration and Cloudflare export
├── wrangler.toml # Cloudflare Workers configuration
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── .dev.vars # Local development secrets (not committed)
├── .env.example # Example environment variables
└── README.md # This file
The wrangler.toml file configures your Cloudflare Worker:
- name: Your worker's name (used in the URL)
- compatibility_date: Ensures consistent runtime behavior
- secrets: Managed via
wrangler secret put(see deployment steps)
This example uses in-memory storage adapters:
const memory = new Memory({
storage: new InMemoryStorageAdapter(),
embedding: "openai/text-embedding-3-small",
vector: new InMemoryVectorAdapter(),
});Note: In-memory storage is reset when the worker restarts. For persistent storage, consider:
- Cloudflare KV for key-value storage
- Cloudflare D1 for SQL database
- Cloudflare Durable Objects for stateful storage
To add Cloudflare KV for persistence:
- Create a KV namespace:
npx wrangler kv:namespace create "CONVERSATION_STORE"- Add to
wrangler.toml:
[[kv_namespaces]]
binding = "CONVERSATION_STORE"
id = "your-namespace-id"- Update your code to use KV storage adapter
Add custom tools to your agent:
const customTool = {
name: "toolName",
description: "Tool description",
parameters: z.object({
param: z.string(),
}),
execute: async ({ param }) => {
// Tool logic here
return result;
},
};
const agent = new Agent({
// ...
tools: [weatherTool, customTool],
});The example includes basic rate limiting configuration. Adjust in wrangler.toml:
[[unsafe.bindings]]
name = "RATE_LIMITER"
type = "ratelimit"
namespace_id = "1"
simple = { limit = 100, period = 60 } # 100 requests per minutenpm run tailMonitor your worker's performance in the Cloudflare Dashboard:
- Request metrics
- CPU time usage
- Error tracking
- Geographic distribution
See .github/workflows/deploy.yml for automated deployment setup.
- Add your Cloudflare API token as a GitHub secret:
CLOUDFLARE_API_TOKEN - Push to main branch to trigger automatic deployment
-
"Script startup exceeded CPU time limit"
- Optimize initialization code
- Move heavy operations to request handlers
-
"Cannot find module"
- Ensure all dependencies are bundled
- Check
nodejs_compatflag in wrangler.toml
-
"Memory limit exceeded"
- Reduce in-memory storage limits
- Consider using external storage (KV, D1)
-
CORS Issues
- CORS is handled by Hono automatically
- For custom headers, modify the server configuration
Enable detailed logging in development:
const logger = createPinoLogger({
name: "cloudflare-agent",
level: "debug", // Change to "debug"
});- Cold Starts: Minimize dependencies and initialization code
- Memory Usage: Keep in-memory storage limits reasonable
- CPU Time: Optimize tool execution and avoid blocking operations
- Bundling: Wrangler automatically bundles and tree-shakes code
Cloudflare Workers Free Tier includes:
- 100,000 requests/day
- 10ms CPU time per invocation
For production usage, consider the Paid plan.
MIT