SDK Connection Lifecycle (connect / use / signin / close)
SDK Connection Lifecycle (connect / use / signin / close)
Level 10 — SDKs, Deployment & Production The standard initialization and shutdown sequence for SurrealDB client SDKs: connecting, setting namespace/database boundaries, authenticating credentials, and releasing network resources.
1. Prerequisites
- JavaScript / TypeScript SDK — The
surrealdbclient package. - Connection Credentials (
USE NS ... DB ...) — Namespace and database scope concepts.
2. Term Category
Integration / Ecosystem (SDK connection lifecycle management): - SDK & Lifecycle
3. Explanation
(1) Design Motivation — "Why did we design this?"
To query a SurrealDB instance reliably, a client application must progress through a deterministic sequence of state transitions:
connect(url): Opens the underlying WebSocket or HTTP network socket to the server.use({ namespace, database }): Sets the target namespace and database scope for all subsequent queries.signin(credentials)(orauthenticate(token)): Authenticates as a System User (root/db) or Record Access User, binding$authto the connection session.close(): Cleanly closes network sockets, terminates active live queries, and releases client resources.
Following this standard lifecycle ensures application code does not suffer from unauthenticated query errors, scope mismatches, or hanging socket connections.
(2) Reality Metaphor
Think of logging into a corporate workstation:
connect: Turning on the computer monitor and connecting to the office local network.use: Selecting your regional office branch and department folder.signin: Typing your corporate username and password.close: Logging out and turning off the workstation at the end of the day.
(3) Code Examples
Short Snippet
import { Surreal } from 'surrealdb';
const db = new Surreal();
await db.connect('ws://localhost:8000/rpc');
await db.use({ namespace: 'production', database: 'main' });
await db.signin({ user: 'root', pass: 'root' });
// Ready to execute queries...
await db.close();
Fuller Example
import { Surreal } from 'surrealdb';
class DatabaseClient {
private db = new Surreal();
async init() {
// Step 1: Connect over WebSocket
await this.db.connect('wss://db.example.com/rpc');
// Step 2: Set Namespace and Database context
await this.db.use({
namespace: process.env.SURREAL_NS || 'app',
database: process.env.SURREAL_DB || 'prod'
});
// Step 3: Sign in with service credentials
await this.db.signin({
user: process.env.SURREAL_USER,
pass: process.env.SURREAL_PASS
});
console.log('SurrealDB client successfully initialized.');
}
get client() {
return this.db;
}
async teardown() {
// Step 4: Gracefully disconnect
await this.db.close();
console.log('SurrealDB connection closed.');
}
}
4. Common Mistakes & Pitfalls
Mistake 1: Creating a New Surreal Client Instance on Every API Route Handler
The mistake: Calling new Surreal() and .connect() inside every single HTTP route handler or serverless function invocation without reusing client connections.
Why it's wrong: Opening and closing network sockets repeatedly causes socket exhaustion, high latency, and unnecessary server connection overhead.
Incorrect:
// Express Route Handler
app.get('/users', async (req, res) => {
const db = new Surreal(); // Creates new socket every request!
await db.connect('ws://localhost:8000/rpc');
await db.use({ namespace: 'ns', database: 'db' });
const users = await db.select('user');
res.json(users);
});
Fix:
// Initialize singleton DB instance once at app startup
const db = new Surreal();
await db.connect('ws://localhost:8000/rpc');
await db.use({ namespace: 'ns', database: 'db' });
app.get('/users', async (req, res) => {
const users = await db.select('user'); // Reuse existing connection
res.json(users);
});
Mistake 2: Using http:// Connection Endpoints for Real-Time db.live() Subscriptions
The mistake: Connecting SDK to http:// endpoint when using db.live() listeners.
Why it's wrong: HTTP protocol is stateless and does NOT support real-time WebSocket live query push events. Connect via ws:// or wss://.
Incorrect:
await db.connect("http://127.0.0.1:8000/rpc");
await db.live("user"); // ❌ Live queries unsupported over HTTP!
Fix:
await db.connect("ws://127.0.0.1:8000/rpc");
await db.live("user"); // WebSocket connection enables live queries
Mistake 3: Omitting Connection Closing in Ephemeral Node.js Scripts
The mistake: Running batch CLI scripts using JS SDK without calling await db.close() before script exit.
Why it's wrong: Un-closed WebSocket connections keep Node.js event loops active, preventing CLI scripts from exiting cleanly.
Incorrect:
// Script finishes without closing connection
await db.select("user"); // ❌ Node process hangs!
Fix:
await db.select("user");
await db.close(); // Closes WebSocket connection cleanly
5. Practice Exercises
Exercise 1: Connection Lifecycle Management
Scenario:
Manage an SDK connection lifecycle: connect over WebSockets, target namespace/database using db.use(), and disconnect on exit.
Requirements:
- Call
db.connect(). - Call
db.use({ ns: "prod", db: "main" }). - Call
db.close().
Answer
Implementation
import Surreal from "@surrealdb/surrealdb";
const db = new Surreal();
await db.connect("ws://localhost:8000/rpc");
await db.use({ ns: "prod", db: "main" });
// Perform operations...
await db.close();
Technical Explanation
db.connect()initializes binary WebSocket protocol connections.db.use({ ns, db })updates active session namespace and database targets.db.close()terminates the connection cleanly.
Exercise 2: Managing Connection State Status
Scenario:
Inspect connection status flags (db.status) to verify whether the SDK is actively connected before running queries.
Requirements:
- Check connection status before executing queries.
Answer
Implementation
if (db.status === "connected") {
const result = await db.select("product");
} else {
console.error("SDK is not connected!");
}
Technical Explanation
db.statusexposes connection state ("disconnected","connecting","connected").- Prevents executing queries on uninitialized WebSocket connections.
- Simplifies connection state handling in UI frameworks (React/Vue).
Exercise 3: Automatic Connection Reconnection
Scenario: Configure SDK connection options to enable automatic reconnection if the network drops temporarily.
Requirements:
- Describe built-in SDK WebSocket auto-reconnect capabilities.
Answer
Implementation
// SDK automatically attempts WebSocket reconnection on network drop
await db.connect("wss://db.example.com/rpc");
Technical Explanation
- The SurrealDB JavaScript SDK includes built-in exponential backoff auto-reconnection logic.
- Re-establishes WebSocket channels automatically when network connectivity recovers.
- Re-authenticates active session tokens on successful reconnection.
6. Related Terms
- JavaScript / TypeScript SDK — SurrealDB npm package overview.
- Connection Credentials (
USE NS ... DB ...) — Scope selection. - WebSocket vs HTTP Connection — Transport choices.
7. Key Takeaways
- The standard connection sequence is
.connect()→.use()→.signin()→.close(). - Reuse a single connected client instance across requests rather than instantiating new clients per query.
- Always invoke
.close()during application teardown to free server sockets.