Usage statistics & metrics
The Next.js SDK can optionally batch and send:
- usage statistics (feature checks + usage / views)
- metrics (measurements / counters / observations)
| Runtime | Package | Transport |
|---|---|---|
| Server (Node RSC, Server Actions, Route Handlers) | @ops-ai/nextjs-toggly-server | Optional gRPC (@grpc/grpc-js + @grpc/proto-loader) |
| Edge (Middleware / Edge Runtime) | @ops-ai/nextjs-toggly-edge | HTTPS JSON to api/usage/stats and api/metrics — no Node gRPC |
Both use metricsBaseUrl (default https://app.toggly.io/) for the telemetry gateway. That host is separate from definitions (baseUri / https://definitions.toggly.io).
With an appKey, usage and metrics default on. Opt out with config flags or TOGGLY_DISABLE_TELEMETRY=1 (authoritative on Next server and edge — wins over explicit true).
Server (optional gRPC)
Install optional gRPC peers when you want telemetry to leave the process:
npm install @grpc/grpc-js @grpc/proto-loader
Without those packages, the server still evaluates flags. If usage/metrics are enabled, it logs a warning and skips sending.
Enable / configure
import { initServerToggly } from '@ops-ai/nextjs-toggly-server'
await initServerToggly({
appKey: process.env.TOGGLY_APP_KEY!,
environment: 'Production',
// Defaults: enableUsageTracking / enableMetrics true when appKey is set
enableUsageTracking: true,
enableMetrics: true,
metricsBaseUrl: 'https://app.toggly.io/',
usageFlushInterval: 60_000, // ms; 0 disables the timer
metricsFlushInterval: 60_000,
})
| Option | Default | Notes |
|---|---|---|
enableUsageTracking | true when appKey is set | Feature check auto-record + recordServerUsage / recordServerView |
enableMetrics | true when appKey is set | measure / incrementCounter / observe |
metricsBaseUrl | https://app.toggly.io/ | gRPC target host (not definitions) |
usageFlushInterval / metricsFlushInterval | 60000 | Periodic flush; 0 disables timers |
instanceName / appVersion | optional | Reported on payloads |
Transport defaults to gRPC (telemetryTransport: 'grpc'). Process signal handlers flush on shutdown when telemetry is active.
Record usage and metrics
Feature evaluations auto-record checks when usage tracking is on. For explicit “used” / “viewed” events and business metrics:
import {
recordServerUsage,
recordServerView,
measureServerMetric,
incrementServerCounter,
observeServerMetric,
flushServerTelemetry,
closeServerToggly,
} from '@ops-ai/nextjs-toggly-server'
// After a meaningful interaction (e.g. button click handled in a Server Action)
recordServerUsage('CheckoutV2', userId)
recordServerView('PricingTable', userId)
measureServerMetric('checkout.latency_ms', 12.3, { feature: 'CheckoutV2' })
incrementServerCounter('checkout.clicks', 1, { feature: 'CheckoutV2' })
observeServerMetric('cart.items', cart.size, { feature: 'CheckoutV2' })
await flushServerTelemetry()
// On process shutdown:
await closeServerToggly()
You can also call recordUsage / recordView / measure / incrementCounter / observe / flushTelemetry on the client from useServerToggly() / getServerToggly().
Edge (HTTPS only)
Edge Middleware and the Edge Runtime cannot open Node gRPC sockets. @ops-ai/nextjs-toggly-edge posts JSON to:
{metricsBaseUrl}api/usage/stats{metricsBaseUrl}api/metrics
Default flush intervals on the edge client are 0 (no background timer). Schedule a flush with the platform waitUntil so isolates can exit without dropping batches.
import {
createFeatureMiddleware,
getEdgeToggly,
} from '@ops-ai/nextjs-toggly-edge'
import type { NextRequest } from 'next/server'
const featureMiddleware = createFeatureMiddleware({
appKey: process.env.TOGGLY_APP_KEY!,
environment: 'Production',
enableUsageTracking: true,
enableMetrics: true,
metricsBaseUrl: 'https://app.toggly.io/',
// Edge defaults: no periodic flush timers — schedule or await a flush
usageFlushInterval: 0,
metricsFlushInterval: 0,
})
export async function middleware(request: NextRequest) {
const response = await featureMiddleware(request, {
featureKey: 'beta-access',
redirectTo: '/waitlist',
})
const client = getEdgeToggly()
// Prefer scheduleFlush(platformWaitUntil) on Cloudflare / Vercel so the
// response is not blocked. Fall back to awaiting flushTelemetry().
await client?.flushTelemetry()
return response
}
Manual APIs on TogglyEdgeClient (from initEdgeToggly / getEdgeToggly):
recordUsage/recordViewmeasure/incrementCounter/observeflushTelemetry()/scheduleFlush(waitUntil)/close()
Helpers: flushEdgeTelemetry(), closeEdgeToggly().
Same pattern as the standalone Cloudflare Workers integration: HTTPS telemetry, flush via waitUntil, never block flag evaluation on a hard send failure.
Kill switch
TOGGLY_DISABLE_TELEMETRY=1
On Next server and edge, this env flag disables usage and metrics even when enableUsageTracking / enableMetrics are explicitly true. Useful in local/CI without changing app config.
See also
- Server-side usage
- Middleware & Edge
- Node.js usage & metrics (gRPC on long-lived Node)
- Cloudflare Workers (HTTPS edge telemetry)
- Go usage & metrics