Moondream 3.1 on Workers AI: fast vision at the edge
By Flavio Copes
Cloudflare brings the Moondream 3.1 vision model to Workers AI. Caption images, ask questions, get object coordinates and bounding boxes — in under a second.
Workers AI just got eyes.
Cloudflare partnered with Moondream to bring their latest vision language model to Workers AI. You can now send an image to a Worker and ask questions about it, caption it, or get the coordinates of objects inside it — with responses coming back in well under a second.
The model is @cf/moondream/moondream3.1-9B-A2B.
What is Moondream 3.1?
Moondream is a small, fast vision language model. Version 3.1 uses a mixture-of-experts architecture: 9B total parameters, but only 2B active per request.
That’s the trick behind the speed. You get visual reasoning close to much bigger models, with the inference cost and latency of a small one. It also has a 32K token context window, so you can ask detailed, structured questions.
The four skills
The model does four things, selected with a task parameter:
- query — ask open-ended questions about an image
- caption — generate a short, normal, or long description
- point — get the coordinates of objects matching a phrase
- detect — get bounding boxes for objects matching a phrase
The last two are what make this interesting. Most vision models describe images. Moondream can tell you where things are, which is what you need for robotics, UI automation, and image tooling.
And it’s fast: Cloudflare reports first tokens streaming back in roughly 20–30 ms, with point and detect completing in the tens-to-low-hundreds of milliseconds range for a simple image, and full captions and queries staying under a second.
Using it from a Worker
Same pattern as every Workers AI model: the AI binding and env.AI.run(). Here’s the caption task:
export default {
async fetch(request, env) {
const res = await fetch('https://cataas.com/cat')
const blob = await res.arrayBuffer()
const response = await env.AI.run('@cf/moondream/moondream3.1-9B-A2B', {
image: [...new Uint8Array(blob)],
prompt: 'Generate a caption for this image',
max_tokens: 512,
})
return Response.json(response)
},
}
The image field also accepts a public HTTPS URL or a base64 data URI, so you don’t have to fetch and convert the bytes yourself.
For object detection, switch the task:
const response = await env.AI.run('@cf/moondream/moondream3.1-9B-A2B', {
task: 'detect',
image: 'https://example.com/team-photo.jpg',
prompt: 'face',
})
You get back bounding box coordinates for every match.
What this unlocks
The combination of fast + cheap + edge changes which vision features are practical:
- moderating user uploads before they’re stored — a caption or query call as a synchronous step in the upload path
- alt text generation for images, at scale
- visual agents that look at screenshots and decide what to click
- live feeds — camera frames, robotics — where a multi-second round trip to a big model is a dealbreaker
I generate alt text for images on this site with a vision model in a batch script. At these latencies you don’t need the batch — you can do it at request time.
Pricing
Moondream 3.1 costs $0.30 per million input tokens and $1.00 per million output tokens on Workers AI.
Vision inputs tokenize images, so input tokens dominate — but a detect call that returns a few coordinates produces almost no output tokens. Point-and-detect workloads are close to free at small scale, and the Workers AI free daily allocation applies here too.
Trying it
Check it’s in the catalog and you’re on a current wrangler:
npx wrangler ai models | grep moondream
Then add the AI binding to your wrangler.jsonc and call it from any Worker:
{
"ai": {
"binding": "AI"
}
}
Small specialized models running at the edge, milliseconds from users, is exactly the direction I expected Workers AI to go. A vision model that answers “where is the button in this screenshot” in under 150 ms opens more doors than another chat model would.
Related posts about cloudflare: