Querying Edge SQL
Connect to Edge SQL from your functions and run low-latency queries against the nearest read replica. This guide covers setup, the query client, and common patterns for data fetching at the edge.
Prerequisites
Overview
Edge SQL is a fully managed, globally replicated relational database built on SQLite. Diverse read replicas ensure data is always close to your users. Write operations are forwarded to a single primary node and propagated to all replicas within milliseconds.
You interact with Edge SQL through the lightweight Vertex query client — a thin wrapper available in JavaScript and TypeScript. It auto-connects to the nearest replica for reads and routes writes to the primary node transparently.
When to use Edge SQL
- Structured relational data that needs global low-latency reads
- User profiles, preferences, and session data
- Content that changes infrequently but is read at high volume
- Multi-region apps where consistent schema matters more than write throughput
Edge SQL vs Vertex KV
Use Edge SQL when you need relational queries, joins, or structured schema. Use Vertex KV for simple key-value lookups that require the absolute lowest latency and highest write throughput.
Instruction
Step 1 — Create a database
Create a new Edge SQL database from the dashboard under Storage → Edge SQL → New Database, or via the CLI:
# Create a new database
vertex sql create my-database
# List all databases in the project
vertex sql listEach database gets a unique connection string scoped to your project. You can create multiple databases per project — for example, separating production and staging data.
Step 2 — Install the query client
Install the Vertex query client in your project. It's a lightweight package with no native dependencies — compatible with the Edge Runtime.
npm install @vertex/sqlEdge Runtime compatible: The query client uses the standard fetch API internally and has zero native dependencies, making it fully compatible with the Vertex Edge Runtime and other edge environments.
Step 3 — Connect and run your first query
Import the client and initialize it with your database URL from the environment. Then run queries using the execute or query methods:
import { createClient } from "@vertex/sql";
const db = createClient({
url: process.env.DATABASE_URL,
});
// Simple query — returns an array of rows
const result = await db.query(
"SELECT * FROM users WHERE active = ?",
[true]
);
console.log(result.rows);The client automatically connects to the closest read replica. For write operations, use db.execute() — these are routed to the primary node.
Step 4 — Run migrations
Edge SQL supports schema migrations via the CLI. Create a migrations/ folder in your project root and add numbered SQL files:
migrations/
001_create_users.sql
002_add_profile_fields.sql
003_create_sessions.sqlMigration safety: Migrations are applied transactionally. If any statement in a migration file fails, the entire migration is rolled back and the database remains in its previous state.
Troubleshooting
Connection timeout errors
If your function times out while connecting to the database, check the following:
- Verify that
DATABASE_URLis set correctly in your project's environment variables - Make sure Edge SQL is enabled for your project in the dashboard under Storage → Edge SQL
- Check your function's maximum execution time — database queries count toward the total execution budget
- Run
vertex sql statusto verify the database is active and reachable
Migration fails with syntax error
Edge SQL uses SQLite syntax. Common issues when migrating from PostgreSQL or MySQL:
- Use
INTEGER PRIMARY KEY AUTO INCREMENTinstead ofSERIAL - Use
TEXTinstead ofVARCHAR(n)— SQLite ignores length constraints - Boolean values are stored as
0/1integers, notTRUE/FALSE ALTER TABLEonly supportsADD COLUMN— renaming or dropping columns requires a table rebuild
Stale reads from replica
Read replicas are eventually consistent. Writes propagate to all replicas within milliseconds, but if you write and immediately read in the same request, you may get stale data. To force a read from the primary node, pass the primary: true option:
const result = await db.query(
"SELECT * FROM users WHERE id = ?",
[userId],
{ primary: true }
);Use this option sparingly — reads from the primary node have higher latency than replica reads and consume more of your write throughput budget.