Documentation Index
Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
Use this file to discover all available pages before exploring further.
Best practices for Edge Compute based on production patterns and common issues.
Configuration
Use Environment Variables for Secrets
Never hardcode secrets. Use the secrets API:
telnyx-edge secrets add --name API_KEY --value "sk-..."
Access in code:
const apiKey = process.env.API_KEY;
Set Appropriate Timeouts
Configure timeouts based on your function’s needs:
# func.toml
[edge_compute]
timeout_seconds = 30 # Default: 30, Max: 300
Use Descriptive Function Names
Function names become part of your URL. Choose wisely:
# ✅ Good
telnyx-edge new-func --name=user-api
telnyx-edge new-func --name=webhook-handler
# ❌ Bad
telnyx-edge new-func --name=func1
telnyx-edge new-func --name=test
Reuse Connections
Initialize clients once at module level, not per request:
// ✅ Good — client initialized once, reused across requests
const client = new HttpClient({ timeout: 5000 });
export async function handler(request) {
const response = await client.get('https://api.example.com/data');
return new Response(JSON.stringify(response));
}
// ❌ Bad — new client created every request
export async function handler(request) {
const client = new HttpClient({ timeout: 5000 });
const response = await client.get('https://api.example.com/data');
return new Response(JSON.stringify(response));
}
// ✅ Good — client at package level
var httpClient = &http.Client{
Timeout: 5 * time.Second,
}
func handler(w http.ResponseWriter, r *http.Request) {
resp, _ := httpClient.Get("https://api.example.com/data")
// ...
}
# ✅ Good — client initialized once
import httpx
client = httpx.AsyncClient(timeout=5.0)
async def handler(request):
response = await client.get('https://api.example.com/data')
return {"body": response.text}
Minimize Cold Starts
Cold starts happen when a new container spins up. Reduce their impact:
- Lazy-load dependencies — Only import what you need, when you need it
- Keep functions small — Smaller code = faster load
- Use lightweight frameworks — Hono over Express, FastAPI over Django
// ✅ Good — lazy load heavy dependency
let heavyLib;
function getHeavyLib() {
if (!heavyLib) {
heavyLib = require('heavy-library');
}
return heavyLib;
}
export async function handler(request) {
if (needsHeavyProcessing(request)) {
const lib = getHeavyLib();
// use lib
}
}
Cache Expensive Operations
Use KV for caching API responses and computed data:
async function getUser(userId) {
// Check cache first
const cached = await kv.get(`user:${userId}`);
if (cached) return JSON.parse(cached);
// Fetch from origin
const user = await fetchUserFromDB(userId);
// Cache for 5 minutes
await kv.put(`user:${userId}`, JSON.stringify(user), { ttl: 300 });
return user;
}
Reliability
Handle Errors Gracefully
Always return proper error responses:
export async function handler(request) {
try {
const data = await riskyOperation();
return new Response(JSON.stringify(data), {
headers: { "Content-Type": "application/json" }
});
} catch (error) {
console.error("Operation failed:", error.message);
return new Response(JSON.stringify({
error: "Internal server error",
requestId: request.headers.get("X-Request-ID")
}), {
status: 500,
headers: { "Content-Type": "application/json" }
});
}
}
Set Timeouts on External Calls
Don’t let slow external services hang your function:
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('https://api.example.com/data', {
signal: controller.signal
});
clearTimeout(timeout);
return response;
} catch (error) {
if (error.name === 'AbortError') {
return new Response('External service timeout', { status: 504 });
}
throw error;
}
Implement Retries with Backoff
For critical operations, add retry logic:
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url);
if (response.ok) return response;
// Don't retry client errors
if (response.status < 500) throw new Error(`HTTP ${response.status}`);
} catch (error) {
if (i === maxRetries - 1) throw error;
// Exponential backoff
await new Promise(r => setTimeout(r, Math.pow(2, i) * 100));
}
}
}
Security
Never trust user input:
export async function handler(request) {
const body = await request.json();
// Validate required fields
if (!body.email || typeof body.email !== 'string') {
return new Response(JSON.stringify({ error: 'Invalid email' }), {
status: 400
});
}
// Validate format
if (!isValidEmail(body.email)) {
return new Response(JSON.stringify({ error: 'Invalid email format' }), {
status: 400
});
}
// Sanitize
const email = body.email.toLowerCase().trim();
// ...
}
Use HTTPS for External Calls
Always use HTTPS when calling external services:
// ✅ Good
await fetch('https://api.example.com/data');
// ❌ Bad — insecure
await fetch('http://api.example.com/data');
Don’t Log Sensitive Data
Be careful what you log:
// ✅ Good — log request metadata
console.log(`Request: ${request.method} ${request.url}`);
// ❌ Bad — logging secrets
console.log(`API Key: ${process.env.API_KEY}`);
// ❌ Bad — logging full request body (may contain PII)
console.log(`Body: ${JSON.stringify(body)}`);
Observability
Add Request IDs
Track requests through your system:
export async function handler(request) {
const requestId = request.headers.get('X-Request-ID') || crypto.randomUUID();
console.log(`[${requestId}] Processing request`);
// Include in response
return new Response(JSON.stringify({ data }), {
headers: {
"Content-Type": "application/json",
"X-Request-ID": requestId
}
});
}
Log at Appropriate Levels
Use log levels effectively:
const logger = {
debug: (msg) => process.env.LOG_LEVEL === 'debug' && console.log(`[DEBUG] ${msg}`),
info: (msg) => console.log(`[INFO] ${msg}`),
warn: (msg) => console.warn(`[WARN] ${msg}`),
error: (msg) => console.error(`[ERROR] ${msg}`)
};
// Use appropriately
logger.debug(`Cache hit for key: ${key}`); // Verbose debugging
logger.info(`User ${userId} created`); // Normal operations
logger.warn(`Retry attempt ${i} for ${url}`); // Concerning but handled
logger.error(`Database connection failed`); // Errors requiring attention