Best Practices
These recommendations match the current Grounded SDK and the current product model.
1. Split Responsibilities Correctly
Use:
@grounded/clientfor control-plane automation@grounded/tracingfor backend traces@grounded/analyticsfor browser telemetry
2. Treat Sessions As Derived
Do not think of sessions as something your app creates directly.
Instead:
- write traces and telemetry
- let Grounded derive sessions
- read sessions back through
@grounded/client
3. Always Resolve An Agent
For direct traces:
- set
agentIdon the tracing client, or - pass
resource.agentIdon each trace
For analytics:
- always initialize with
agentId
4. Always Carry A Stitch Key
For traces, include at least one of:
sessionIdanonymousIduserIdplus non-emptycorrelationKeys
For browser + server apps, forward analytics.getContext() to the backend and reuse those values.
5. Create Or Choose A Snapshot Before Ingesting Traces
If an agent has no snapshot, the trace is stored but it will not normalize into sessions for insight or optimization workflows.
6. Use Structured Spans, Not Giant Metadata Blobs
Prefer:
llmspans for model callsretrievalspans for search and context lookuptoolspans for external APIs or DB workappspans for routing and orchestration
7. Tag Environment And Release
Set:
environmentrelease
on the tracing client so you can segment behavior across staging, production, and rollout versions.
8. Flush On Shutdown
- long-running servers should call
shutdown()on process exit - short-lived jobs should
flush()orshutdown()before returning - browser apps should
flush()before important transitions if loss would matter
9. Use jobs.wait() With A Timeout
await grounded.jobs.wait(job.id, {
timeoutMs: 15 * 60_000,
});10. Verify Instrumentation With Readback
When you first integrate:
- inspect raw traces with
grounded.traces.* - inspect derived sessions with
grounded.sessions.* - make sure the same browser action and backend trace show up under one session
11. Use Connectors For Backfill, Not As The Only Model
LangSmith and FullStory connectors are useful for:
- historical import
- recurring sync
- reconciliation
Direct instrumentation should still be your canonical write path if you control the app.