Usertour logo

Usertour v0.9.7: Faster Onboarding Delivery, More Reliable Infrastructure

Usertour v0.9.7 speeds up onboarding delivery, handles reconnect bursts more reliably, and adds readiness checks, standard OpenTelemetry configuration, and clearer dashboard errors.

Last updated on October 30, 20266 min read
Usertour v0.9.7: Faster Onboarding Delivery, More Reliable Infrastructure

A product tour can have the right message, audience, and trigger—and still feel slow if the system delivering it spends too long waiting.

That waiting is the focus of Usertour v0.9.7. This release shortens the path from a user's action to the content that follows, keeps the server steadier when many clients reconnect, and gives self-hosted teams better deployment and monitoring controls.

It also makes everyday dashboard problems easier to understand, from a rejected input to a project list that failed to load.

The delivery improvements are server-side. There is no SDK bundle change in this release, so existing installations benefit without replacing the script in their application.

Onboarding content reaches the page sooner#

When a user finishes an experience or triggers an evaluation, Usertour checks what should happen next. v0.9.7 removes three sources of delay from that process.

Less event history to process#

Previously, an evaluation fetched the user's event history for the relevant content and searched it in application memory. The database now selects the latest events that the evaluation actually needs.

In a staging test on an account with 12 pieces of content and approximately 3,700 events:

  • EndBatch processing fell from 1,120 ms to 387 ms.
  • EndContent processing fell from 1,965 ms to 713 ms.

These are measurements of two server operations in a specific staging workload, not a guarantee of page load time or the same improvement in every application. They show the benefit of avoiding unnecessary history processing as event data accumulates.

Other tabs no longer hold up the active tab#

A user may have your application open in several tabs. Those tabs need to stay in sync when an onboarding session starts or is cancelled.

Previously, the initiating connection waited for the user's other connections across the cluster to acknowledge the change. One unresponsive tab could delay the response to the tab the user was actually using.

Other connections now synchronize through their own queues. The initiating connection receives its response once its own state is updated, while the remaining tabs follow asynchronously.

Content pushes no longer wait for empty receipts#

The server previously waited for an acknowledgement after every content push. That acknowledgement arrived before the SDK processed the message, so it did not confirm that the content had rendered. It did, however, add a network round trip to each push.

v0.9.7 removes that wait. When one evaluation activates several eligible pieces of content, the server can send them together instead of holding each one until the previous receipt returns. Existing SDK builds already support this delivery behavior.

More predictable recovery after a deployment#

v0.9.6 introduced automatic SDK reconnection. v0.9.7 improves how the server handles the other side of that recovery.

After a deployment or replica restart, many clients can reconnect at once. Letting all that work reach the database immediately can turn a brief restart into a longer period of congestion.

The server now limits how much WebSocket work each replica processes concurrently. By default, 16 handshakes or client messages can run at a time. Additional work waits for up to 15 seconds, and new handshakes are paced at 50 per second. When capacity is unavailable, clients receive a retryable rejection that works with the SDK's backoff behavior.

Two additional changes reduce pressure during these bursts:

  • A Debian-based server image reduces query-engine CPU use in the measured burst workload. The release investigation observed approximately 2.8 CPU cores on Alpine versus 0.4 on Debian. These figures describe that workload, rather than an expected reduction for every deployment.
  • Repeated identity updates do less database work. User, company, and membership changes are planned before taking a row lock, and writes that change nothing avoid opening a transaction. Concurrent identical updates spend less time competing for the same row.

The release also fixes a session-resume loop involving hidden content on a superseded version, which could otherwise consume a replica's memory.

Clearer feedback in the dashboard and builder#

An error message should help you decide what to do next. Several dashboard changes make that easier:

  • Invalid inputs receive specific validation feedback in the dashboard's language.
  • System Admin errors explain the relevant license, ownership, or administrator constraint.
  • A project list that fails to load offers a retry, instead of treating the failure as an empty account.
  • Content-type icons now share consistent sizing and visual weight.

The builder also handles saving and navigation more reliably. This release fixes conflicting actions during Save & Leave, unnecessary unsaved-work prompts while a save is pending, and condition validation that ran before the available segments or content had finished loading.

Another fix restores normal mouse interaction after closing a select inside a dialog. Pressing Escape inside the select now closes that select without also closing the surrounding dialog.

Better health checks and observability for self-hosting#

Check readiness before routing traffic#

A running process is not necessarily ready to serve users. v0.9.7 provides separate endpoints for those two questions:

  • GET /api/health checks liveness without depending on the database or Redis.
  • GET /api/health/ready checks whether this process can reach both dependencies. It returns 200 when they respond and 503 with failure details when they do not.

Using the readiness endpoint for deployment health checks lets a platform wait until a new replica can serve requests before directing traffic to it.

Configure tracing with standard OpenTelemetry variables#

Tracing now uses the standard OTEL_* configuration, including OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_TRACES_EXPORTER, and OTEL_TRACES_SAMPLER.

Instrumentation starts before the application framework loads, and each WebSocket message gets a span named for its message kind. If no OpenTelemetry configuration is supplied, the telemetry SDK is not initialized. That also removes the previous attempts to export to a local collector when none was configured.

Logs become easier to work with as well: severity levels use readable names, repetitive evaluation warnings are removed, and end-user identifiers, attributes, and payloads are no longer included in log output.

What to check when upgrading#

Usertour Cloud was already running v0.9.7 when the release was published. For self-hosted installations, review these changes before upgrading:

  1. Check the database migration. The release tightens required fields on content, steps, themes, and segments. Rows with NULL in Content.environmentId or Step.type must be resolved before the migration can complete. The full release notes list the affected columns.
  2. Update the deployment health check after deploying. Use /api/health/ready. If you roll back to an older image, restore the previous health-check path. The liveness response also changes shape, so check any monitoring that parses its body.
  3. Migrate tracing configuration. OTLP_TRACES_ENDPOINT and OTLP_METRICS_ENDPOINT are no longer read; use the standard OTEL_* variables documented in the release's .env.example.
  4. Allow for the new container image. The Debian-based image runs Node 22.23 and is approximately 200 MB larger. Its nginx workers run as www-data.
  5. Reload existing dashboard tabs. Tabs opened before deployment may fail validation on changed GraphQL operations until refreshed. REST API v2 and MCP are unchanged.

The WebSocket rate limit now applies correctly at 30 messages per second or 300 per minute per connection. Integrations that drive the connection directly should handle refused messages. The admission limits are configurable per replica; the release notes document their environment variables and defaults.

The SDK bundle remains at 0.8.1, and the usertour.js npm package remains at 0.0.26. No SDK upload or script replacement is required for this release.

Keep the next step responsive#

This release helps onboarding respond more promptly when users take action, keeps a stalled tab from delaying another, and gives deployments a more controlled recovery path. The dashboard improvements support the same goal: fewer interruptions between deciding what to build and getting it in front of users.

Read the complete v0.9.7 release notes for all fixes and upgrade details, explore the Usertour documentation, or start building with Usertour Cloud.

Put this into practice

Build your first product tour with Usertour in minutes — free plan, no credit card, open source.

Related reading

More ideas from the Usertour blog.