The universal SQL interface.
The Vector Gateway Interface (VGI) lets DuckDB and Haybarn attach a remote process as if it were a native catalog or extension. Your data, services, models, and code stay in their own runtime; SQL users get catalogs, schemas, tables, and functions they can explore, query, and join.
For the systems, data, and code DuckDB cannot reach by itself
VGI removes the glue. Instead of writing code to bridge two systems, you write a VGI-enabled process — a worker — that exposes an API, service, library, model, or dataset. DuckDB attaches to that worker, discovers what it offers, and makes all of it queryable in SQL.
A worker can run entirely on your own machine, or be reached over HTTP. Locally, DuckDB spawns it for you and talks over pipes, a Unix socket, or shared memory — no service to deploy, and nothing on the network. Over HTTP, the worker runs wherever you deploy it, and any number of DuckDB sessions can attach to the same one. Because a worker is just an HTTP service, you can also put a pool of them behind a load balancer and scale it like any other tier — the usual shape for a shared model or inference service. Same worker, same protocol; only the transport changes.
And because DuckDB has client libraries for Node.js, Python, Go, and Rust, plus ADBC and ODBC, every VGI worker is reachable from whatever language you already work in.
In practice, that shows up as a handful of recurring patterns:
Data-as-a-Service
Wrap an API, feed, or proprietary dataset as a SQL catalog that other teams or customers attach to and query directly.
Learn more →Reach AI agents, not just SQL
The same worker that plugs into DuckDB also speaks MCP — so the data, models, and services you expose for SQL are just as reachable by an AI agent, under the same access control.
Secure down to the row and column
OAuth carries a user’s identity all the way to the worker, so access can be restricted by row and column, not just by table, with nothing allowed unless a policy says so — the control a company-wide SQL layer actually needs.
Bridge a legacy system
Put SQL in front of a system you can’t rewrite — an old file format, an internal service, anything that still works but was never built to speak SQL.
See a real example ↗Query streaming and event data
Turn a live stream of events — a queue, a topic, a webhook — into a table SQL can query directly.
Prototype fast, optimize later
Start fast in whatever language you already use. Reach for a native DuckDB extension later, only if you outgrow what a worker can deliver.
Learn more →Big picture
One extension, however you use it
Every pattern above goes through the same path: DuckDB issues a request, the VGI extension carries it as Arrow IPC over whichever transport you chose, and your worker answers.
Terminology
VGI Protocol and VGI worker
What DuckDB speaks to reach a worker
VGI is two things at once: a DuckDB extension, and the Apache Arrow-based protocol it speaks to reach a worker running outside DuckDB. That protocol carries authentication, catalog discovery, query planning, and the data itself.
The service that exposes data
A VGI worker is a process or hosted service that exposes data or compute to DuckDB. It receives each request as a remote procedure call (RPC) and returns the rows or results DuckDB asked for.
We could have faked this demo. We didn't.
Every worker below is real and hosted — the same VGI protocol you'd run locally over a
pipe, just reached over plain HTTP so it works here, live, in your browser.
ATTACH doesn't care which: no
ETL, no connector plumbing, no native rebuild, either way.
Open-Meteo is a free, open-source weather API — no key required for non-commercial use. This worker exposes its geocoding and hourly-forecast endpoints as ordinary SQL table functions.
ATTACH 'open_meteo' AS m (TYPE vgi, LOCATION 'https://vgi-open-meteo.rusty-bb6.workers.dev');
-- Geocode the place first, then LATERAL-join its coordinates straight into
-- the forecast call — one round trip per row, no separate lookup step.
SELECT w.time,
round(w.temperature_2m, 1) AS temp_f,
m.main.weather_code_emoji(w.weather_code) AS icon,
m.main.weather_code_text(w.weather_code) AS conditions
FROM m.main.geocoding('Glen Allen, VA', count := 1, country_code := 'US') AS g,
LATERAL m.main.forecast_hourly(g.latitude, g.longitude,
forecast_days := 2,
temperature_unit := 'fahrenheit') AS w
WHERE w.time >= now()
ORDER BY w.time limit 6;
| time | temp_f | icon | conditions |
|---|---|---|---|
| 2026-08-13 19:00 UTC | 89.3 | ☁️ | Overcast |
| 2026-08-13 20:00 UTC | 90.1 | ☁️ | Overcast |
| 2026-08-13 21:00 UTC | 89.9 | ☁️ | Overcast |
| 2026-08-13 22:00 UTC | 88.9 | ☁️ | Overcast |
| 2026-08-13 23:00 UTC | 87.4 | ☁️ | Overcast |
| 2026-08-14 00:00 UTC | 83.6 | ☁️ | Overcast |
Live feed from the USGS Earthquake Hazards Program — the same 30-day feed seismologists and emergency responders watch, as an ordinary table.
ATTACH 'earthquakes' AS eq (TYPE vgi, LOCATION 'https://vgi-earthquakes.rusty-bb6.workers.dev');
SELECT time, round(mag, 1) AS mag, place
FROM eq.main.recent
WHERE mag >= 5
ORDER BY mag DESC
LIMIT 8;
| time | mag | place |
|---|---|---|
| 2026-08-10 12:34 UTC | 7.4 | 5 km S of San José del Palmar, Colombia |
| 2026-07-17 14:48 UTC | 7.3 | 52 km W of Puerto Madero, Mexico |
| 2026-07-28 07:27 UTC | 6.8 | The 2026 Kumamoto Region, Japan Earthquake |
| 2026-07-17 15:20 UTC | 6.4 | 96 km SW of Puerto Madero, Mexico |
| 2026-08-05 04:14 UTC | 6.3 | 32 km SW of Sarangani, Philippines |
| 2026-08-05 07:43 UTC | 6.3 | south of the Kermadec Islands |
| 2026-07-24 21:37 UTC | 6 | 55 km W of Sola, Vanuatu |
| 2026-08-12 11:47 UTC | 6 | South Sandwich Islands region |
Live departure board from NS (Dutch Railways) — the same real-time data the platform boards at Amsterdam Centraal show, as an ordinary table.
ATTACH 'trains' AS trains (TYPE vgi, LOCATION 'https://vgi-trains-ts.rusty-bb6.workers.dev');
SELECT strftime(planned_time, '%H:%M') AS time,
destination,
category,
coalesce(actual_track, planned_track) AS track,
delay_minutes
FROM trains.main.train_departures('asd')
ORDER BY planned_time
LIMIT 10;
| time | destination | category | track | delay_minutes |
|---|---|---|---|---|
| 22:55 | Haarlem | Sprinter | 1 | 0 |
| 23:00 | Schiphol Airport | Intercity | 8a | 0 |
| 23:09 | Alkmaar | Intercity | 2a | 1 |
| 23:19 | Utrecht Centraal | Intercity | 4a | 0 |
| 23:46 | Rotterdam Centraal | Intercity | 15a | 0 |
| 00:19 | Utrecht Centraal | Intercity | 5a | 0 |
Overture’s places dataset, filtered to Charlottesville, VA and church categories, color-coded by denomination and rendered as real points on a map — 115 locations.
ATTACH 'overture' (TYPE vgi, LOCATION 'https://vgi-overture.rusty-bb6.workers.dev');
SELECT names.primary AS name,
categories.primary AS category,
(bbox.xmin + bbox.xmax) / 2 AS lon,
(bbox.ymin + bbox.ymax) / 2 AS lat
FROM overture.places.place
WHERE bbox.xmin BETWEEN -78.53 AND -78.43 AND bbox.xmax BETWEEN -78.53 AND -78.43
AND bbox.ymin BETWEEN 37.98 AND 38.08 AND bbox.ymax BETWEEN 37.98 AND 38.08
AND categories.primary IN ('church_cathedral', 'catholic_church', 'baptist_church',
'pentecostal_church', 'evangelical_church',
'episcopal_church', 'anglican_church');
A protocol, not a framework
VGI is a DuckDB extension that uses VGI-RPC — an Apache Arrow IPC-based RPC protocol — to expose an interface for building database extensions. Lightweight implementation libraries make that same protocol easy to speak in Python, TypeScript, Go, Rust, or Java, so a worker never has to hand-roll the wire format. What moves between DuckDB and a worker is Apache Arrow IPC, carried over pipes, sockets, shared memory, or HTTP.
The important part: your code runs outside DuckDB, so it's never tied to DuckDB's own extension interface — the ABI that changes across versions and forces a recompile. Any language with an Arrow library can speak VGI — in practice, that's most of them. Writing a new worker ends up feeling like writing an ordinary service, not building a database extension.
CGI, but for databases
CGI is old — a 1990s standard, from back when most web
pages were still static HTML files and the dynamic ones ran out of a folder every site
had, literally named /cgi-bin/ —
for handing a request off to an external program instead of building every feature
into the server itself. VGI does
the same for DuckDB — it launches or connects to a process outside the database rather
than compiling that logic in. And because the launch is just a command, it doesn’t
have to stay local: swap in a command that reaches over SSH, or attach an HTTP address
instead, and the worker runs somewhere else entirely.
Find a worker someone already built
Orchard is Query.Farm's marketplace and hosting platform for VGI workers — attach one and start querying. No worker to write, no code to run yourself.
Kafka
Streaming
Read and produce Kafka topics as SQL tables.
IMAP
Query mailboxes and messages over IMAP as tables.
HostQuery
Federation
Federate queries across remote database hosts.
What's live today is the leading edge — more of the catalog below is landing regularly.
Self-hosted, or let Orchard run it
Every worker in Orchard works either way. Orchard is both the marketplace where you find it and a platform that can run it for you — which one you choose depends on how much you want to manage yourself.
Run it your way
Build your own worker, or download one someone else already
wrote — either way, it runs on your own infrastructure: a laptop, your servers,
wherever your data already lives.
LOCATION
is just a shell command, so launch and distribution are up to you —
uv run
for Python,
npx
for TypeScript, a Docker/OCI image VGI pulls and runs itself, or your own private
artifact. Nothing leaves your network unless you choose to let it.
Let Orchard run it
Subscribe to a hosted version instead. Orchard runs it, keeps it current, and hands you a token — no connector infrastructure for you to manage.
See hosted pricing →Write your own VGI worker
If what you need isn't in Orchard yet, build it. It's the same protocol regardless of language — pick the SDK that matches your stack.
Not every worker needs to be public, either. Writing one just for your own systems — your database, your internal APIs, data that shouldn't leave your network — is completely supported, and it's the common case, not the exception. Most problems aren't generic enough for someone else's off-the-shelf connector to solve them.
Building something with VGI?
We help teams design, build, and ship VGI-based extensions. From a one-day spike to a long-term engagement.