Migrate from Ably to Bird
Move one live application workflow first, including its publisher, subscriber and authorization endpoint. For an order tracker, success means that the right customer sees the current order after a reconnect, and another customer cannot subscribe to it.
Inventory any Ably features the application depends on before changing credentials. Ably's channel options include behavior beyond live publication. A history, rewind, encryption, delta or integration dependency needs its own migration decision.
Map the integration
| Ably responsibility | Bird migration action |
|---|---|
| Channels | Subscribe to the mapped name and channel type. Use an authorized type for customer data. |
| Messages | Publish event and data; bind the handler to the event name. |
| Token capabilities | Check user access on your server, then sign the specific subscription. |
| Presence | Assign one member_id per person; count connections separately for a device view. |
| History and rewind | Read retained history from your application. A current snapshot cannot replace an audit log. |
| Last-value cache | Evaluate cache channels and handle a missing value; retain the underlying state. |
| Reconnection | Reauthorize, then recover the view after subscription succeeds. |
Replace Ably channels.get(name) with the browser client’s subscribe(name). Choose a public, private-, presence-, or private-encrypted- channel to match the required access and encryption. Map message name to event; subscribe with bind(event, handler). Keep application payload versions explicit.
Ably capabilities scope operations to channel resources. In Bird, private and presence subscriptions call your application authorization endpoint. Check the signed-in user's access to the requested order or room before returning auth. The default browser authorizer sends JSON with connection_id and channel_name; your server helper signs the current connection and the exact channel name. Follow channel authorization, including its refused-user case.
Ably presence membership distinguishes a clientId on different connections. Bird presence groups connections under one member_id: two tabs for the same member produce one roster entry, and the member leaves when the last connection leaves. Update device-count displays or use the separate connection count. Do not infer completed work or human availability from a socket being present.
Ably rewind supplies earlier messages on attachment. Bird cache channels supply the latest cached event, and ordinary Bird channels do not replay a disconnected client's missed events. Retain application history where the product needs it; do not replace a sequence of business events with one cache value.
Build and test the receiving path
Create a separate Bird Realtime app. Record its app ID, public key, secret and region together. The browser uses the public key and region; your publisher uses an API key and the app credentials. Keep the API key and app secret on your server.
Run the complete Express and browser order application before changing customer traffic. It includes an authorized private subscription, two-tab presence, a stored order, and recovery after a lost connection. Its local demo session must be replaced by your application's authentication when integrating it.
In the browser, bind your application event to the data your interface needs. The SDK invokes that handler with the payload. An Ably handler that reads message.data must be adapted rather than passed across unchanged. Bind bird:subscription_succeeded separately to refresh current state after initial authorization and after a reconnect.
For a minimal publisher, install @messagebird/sdk and tsx, set the environment variables from your Bird app, and save this as publish.mts. The payload is illustrative application data; changing it does not fulfill an order.
Ejemplo de código
import { BirdClient } from "@messagebird/sdk";
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}.`);
return value;
}
const bird = new BirdClient({
apiKey: required("BIRD_API_KEY"),
realtime: {
key: required("BIRD_REALTIME_KEY"),
secret: required("BIRD_REALTIME_SECRET"),
},
});
await bird.realtime.publish(required("BIRD_REALTIME_APP_ID"), {
event: "order-updated",
channels: ["private-order-42"],
data: { id: "42", version: 2 },
});
console.log("Event accepted. Check the subscribed client separately.");Run npx tsx publish.mts with an authorized client already subscribed. This command publishes a notification. In the complete order example, use the application’s advance action to change the stored order and see the refreshed result. API acceptance establishes that the edge accepted the event; it is not a receipt from each browser. Use the publish reference for the complete request and response.
The complete order example stores a version on the order. Its client ignores stale reads, and its server rejects a repeated state change with an outdated expected version. Use that pattern when duplicate notifications or a response lost during migration could otherwise perform an action twice.
| Test | Expected result |
|---|---|
| Authorized customer subscribes | The current order loads and subsequent changes appear. |
| Another customer requests the same channel | Your authorization endpoint refuses it. |
| One customer opens two tabs | One presence member remains until the last tab closes. |
| Client disconnects during an update | After re-subscription, a fresh application read shows the latest state. |
| Older read completes after a newer update | The displayed version does not move backwards. |
| Cache is empty or expired | The miss path reloads or republishes current state. |
| Same business event reaches both integrations | One stored business action; notifications remain safe to repeat. |
If your inventory includes encrypted channels, use Bird's encrypted-channel setup and test publisher-to-browser decryption before moving that channel. Preserve any historical ciphertext and keys your own retention policy requires. A replacement connection does not migrate encrypted history.
Switch traffic and reconcile
Record a channel mapping and choose a small cohort by customer or workspace. Change its publisher and subscriber routing together; a Bird subscriber cannot receive a publication sent only to the old channel.
For an observation period, the application may publish the same notification to both services. Keep the business mutation in one system and carry its event identity or record version into each notification. Do not let both streams trigger a payment, fulfillment or other action independently.
Compare authorization failures, successful subscriptions, missed-update recovery, end-user state and current usage against the original integration. Keep the original provider records and history that customers still need. Add cohorts after their complete journeys pass.
To reverse a cohort, return its client and publisher routing together, then reload authoritative application state. Reversing transport routing does not reverse a business action that already succeeded. Keep the original configuration available until recovery and retained-history access are verified.
References and next steps
- Compare Bird and Ably and Realtime pricing.
- Complete Express/browser application and first-event setup.
- Authorize channels, presence, and connection lifecycle.
- Cache channels, client events, and Realtime webhooks.
- Migration directory, Realtime resource library, and Realtime API.
- Start now or talk to sales.
Recursos relacionados
Continúa con la documentación, guías y ejemplos sobre este tema. Los recursos están en inglés.