Skip to content
Free shipping on orders over $2,000.

Limits and constraints

The honest list: no acoustic barge-in, exact sample rates, at-most-once command delivery, session resumption, context cost, and how the device plane must be deployed. Read it before you flash a fleet.

9 min read

Every item here is a real, current constraint. Several have direct consequences for how you design your server, and all of them are better discovered on this page than in a customer's building. If one of them blocks your deployment, raise it before you flash a fleet — several are small pieces of work we would rather do once, properly, than have every integrator work around separately.

Audio and conversation

No acoustic barge-in

Without echo cancellation on the device, a person cannot interrupt by speaking — the button is the only interruption. Every sentence your agent speaks is a sentence the customer is trapped in, so write short replies and put the confirmation first.

Server-side echo cancellation was evaluated and rejected: it needs a tightly-known delay between the reference and microphone signals, and over Wi-Fi with device buffering that delay wanders by tens of milliseconds. Device-side cancellation is what would remove this.

Sample rate must be exact, not nominal

A device clocked at 15 980 Hz while claiming 16 000 accumulates roughly 1.2 seconds of drift per hour, which eventually starves or overflows every buffer downstream. Measure this over a ten-minute soak — drift is invisible in a thirty-second test. If a clock cannot be exact, resample properly server-side rather than naively on the device: naive resampling destroys the frequencies sibilants occupy, and the failure mode is the recogniser mishearing words rather than any audible defect.

No jitter buffer or loss concealment on the full-duplex path

WebSocket runs over TCP, so packets are not lost or reordered, but a congested link produces delay rather than loss and nothing smooths it. Poor Wi-Fi presents as the agent's speech arriving late or in uneven bursts. Your playback buffer is the only jitter absorption in the system.

Full-duplex sessions do not resume

A reconnect is a fresh conversation with a new greeting; any in-progress, unconfirmed transaction is lost. A brief Wi-Fi glitch therefore costs the customer their order and restarts from the greeting. If your transaction is long or valuable, persist partial state server-side keyed on the device rather than holding it in the session.

Cost and capacity

Context size is the largest cost lever

The reference restaurant profile renders the full menu into the prompt on every turn, measured at roughly 84:1 prompt-to-completion tokens. A large catalogue multiplies that directly. If your use case has a big domain vocabulary, design for retrieval rather than a fat prompt from the start — it is far harder to retrofit once the prompt is load-bearing.

Context is fetched once per connection

In the reference implementation the agent's context is cached for the life of the session, so an item marked unavailable mid-conversation is invisible to the agent. The backend re-validates at confirmation and rejects the whole order if any line became unavailable — a harsh outcome, chosen because silently serving a subset of what someone confirmed is worse. If you build this yourself, decide deliberately which of those two you prefer.

One event loop, shared

Any blocking call in any handler stalls every session on that process simultaneously; the symptom is a site-wide stutter, not one bad device. Keep the audio path strictly non-blocking and push anything synchronous — a database write, a third-party call, a PDF render — onto a worker.

Delivery guarantees

Command delivery is at-most-once

The polling GET marks every returned command as sent before the device has acted on it. A device that dies in between never sees that command again. Acknowledge early, persist on receipt, and for anything destructive acknowledge first and act second.

Notifications are delivered once

The downlink GET pops the item from the queue. A device that fetches and then fails to play has lost it. If a message must not be lost, do not treat the fetch as delivery — hold it until playback has actually started.

A print job that is never acknowledged blocks the queue

Tickets are served oldest-first and the queue only advances on acknowledgement. This is the single most common integration bug in the print path, and it presents as a kitchen printing the same ticket forever.

Deployment and security

If you are building the server, this is the place to do better than the reference implementation: mint a per-device secret at provisioning, require it on every device-facing call, and treat the MAC as a routing key rather than a credential. The protocol has room for it — the handshake and the fleet plane both carry headers you control — and nothing in the firmware contract depends on the MAC being the only identifier.

  • Terminate TLS in front of every HTTPS and WebSocket route. Validate certificates on the device; pin a CA if you pin anything, never a leaf.
  • Treat 400, 403, 404 and 422 as your bug or your provisioning, never as something to retry. Retrying them in a loop turns one broken device into load against the backend every other device shares.
  • Scope every read by tenant on the server. A device asserting a property_id it does not own must be a 403, not a successful cross-tenant read.
  • Presigned URLs for audio should be short-lived. Recorded speech is personal data in most jurisdictions you will deploy in.

Not yet built

GapWork around it by
No outbound webhooks in the reference implementationBuilding your own — you own the server, so this is a design choice rather than a limitation
Full-duplex mode is English-only in the reference agentMultilingual works end-to-end on the push-to-talk path; the constraint is the agent, not the device
Capacity per process is not load-testedSizing large full-duplex fleets empirically, and keeping the session state machine tight

Something wrong or missing on this page? Tell us.