---
term: 'Notificaciones Push vs. Live Queries'
seoTitle: 'Notificaciones Push vs. Live Queries: ¿Qué Canal de Tiempo Real?'
headline: 'Notificaciones push vs. live queries: ¿cuál necesitas?'
slug: push-vs-live-queries
category: api-realtime
shortDefinition: 'Una notificación push es una alerta que entrega el sistema operativo y alcanza apps cerradas; una live query transmite cambios con la app abierta.'
relatedTerms:
  - push-notifications-apns-fcm
  - real-time-live-queries
  - websockets-real-time-sync
  - sse-vs-websockets-vs-polling
contrastsWith:
  - real-time-live-queries
aboutTerms:
  - 'Notificaciones Push'
  - 'Suscripciones de Live Query'
faq:
  - question: '¿Cuál es la diferencia entre notificaciones push y live queries?'
    answer: 'La ruta de entrega y el estado de la app que cada una atiende. Una notificación push viaja por el gateway de push del sistema operativo y llega al dispositivo incluso con tu app cerrada — pero lleva un payload pequeño y opaco, con garantías de mejor esfuerzo. Una live query es una suscripción por WebSocket que tu app en ejecución mantiene abierta: objetos completos, en tiempo real, con permisos verificados — y muerta en el instante en que la app lo está.'
  - question: '¿Las live queries funcionan con la app cerrada?'
    answer: 'No, y ninguna astucia del lado del cliente lo cambia. Una live query es estado dentro de tu proceso en ejecución — un WebSocket que la app mantiene abierto. Cuando el sistema operativo suspende o mata la app, el socket muere con ella, y las plataformas móviles suspenden agresivamente las apps en segundo plano para ahorrar batería. Alcanzar una app cerrada es exactamente el trabajo que el SO reserva para su propio gateway de push.'
  - question: '¿Una app de chat debería usar notificaciones push o live queries?'
    answer: 'Ambas, divididas por el estado de la app. La conversación abierta se suscribe a una live query — los mensajes se renderizan al instante con datos completos, indicadores de escritura y confirmaciones de lectura incluidos. La app cerrada depende del push para alertar al destinatario, cargando apenas lo suficiente para renderizar el banner. El toque abre la app, que se resuscribe y reconsulta para ponerse al día. Todo mensajero popular funciona así.'
  - question: '¿La llegada de las notificaciones push está garantizada?'
    answer: 'No — la entrega es de mejor esfuerzo por diseño. Los gateways del SO agrupan, limitan y descartan mensajes bajo presión de batería, los usuarios desactivan los permisos por completo y los dispositivos se quedan sin señal. Los push silenciosos en segundo plano se limitan aún más que los visibles. Trata el push como un toque en el hombro para despertar a alguien, nunca como un contrato de transporte de datos; la app debe reconciliar el estado consultando después de abrir.'
  - question: '¿Qué tan grande puede ser el payload de una notificación push?'
    answer: 'Kilobytes, no datos. Los gateways del SO limitan el payload a unos 4 KB, y ese payload es opaco al modelo de permisos de tu backend — lo que pongas ahí queda en el pipeline de notificaciones, fuera de tus ACLs. El patrón robusto envía solo identificadores y strings para mostrar, y deja que la app abierta busque los objetos reales por la API normal, con permisos verificados.'
  - question: '¿Qué es una notificación push silenciosa?'
    answer: 'Un push sin alerta visible que le pide al SO despertar tu app brevemente en segundo plano — típicamente para precargar datos y que la próxima apertura se sienta instantánea. Es el recurso más racionado del sistema de push: el SO presupuesta los despertares por app por día e ignora el exceso, así que el push silencioso funciona como capa de optimización, nunca como canal confiable de sync.'
  - question: '¿Necesito notificaciones push y live queries a la vez?'
    answer: 'Si a tus usuarios les importan los eventos que ocurren con la app cerrada — mensajes, pedidos, alertas —, sí, casi inevitablemente. Los dos canales cubren estados disjuntos de la app: las live queries son dueñas de la experiencia con la app abierta, el push es dueño del reenganche desde el estado cerrado. Los backends que traen ambos integrados dejan que una sola escritura en la base de datos se propague a cada canal, así que necesitar ambos deja de implicar construir dos veces.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'RFC 8030 — Generic Event Delivery Using HTTP Push'
    url: 'https://datatracker.ietf.org/doc/html/rfc8030'
  - name: 'Push API — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/API/Push_API'
  - name: 'Push technology (Wikipedia)'
    url: 'https://en.wikipedia.org/wiki/Push_technology'
  - name: 'Live Queries — Parse Server guide'
    url: 'https://docs.parseplatform.org/parse-server/guide/#live-queries'
cta:
  title: 'Un backend, ambos canales'
  text: 'Back4app entrega notificaciones push y Live Queries sobre los mismos datos: una escritura en la base de datos se propaga a los gateways de push del sistema operativo y a cada WebSocket suscrito. Cablea el trigger afterSave una vez y cubre todos los estados de la app.'
  linkText: 'Empieza gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-09-04'
translationKey: push-notifications-vs-live-queries
---

**Una notificación push es una alerta que entrega el sistema operativo y alcanza apps cerradas; una live query transmite cambios con la app abierta.** Plantearlas como rivales es el error clásico — cubren *estados disjuntos de la app*, y la verdadera pregunta de diseño no es "cuál de las dos" sino "¿dónde está el usuario ahora mismo?". La mayoría de las apps que se sienten realmente en tiempo real corren ambas y enrutan según esa respuesta.

## Puntos clave

| Pregunta | Respuesta |
| --- | --- |
| Notificaciones push | Entrega por el gateway del SO (APNs, FCM) — alcanza apps cerradas, payload opaco de ~4 KB, mejor esfuerzo |
| Live queries | Suscripción por WebSocket — objetos completos con permisos verificados, tiempo real, la app debe estar abierta |
| La rivalidad | Falsa — atienden estados disjuntos de la app y se componen, no compiten |
| La regla de enrutamiento | App abierta → live query · app cerrada → push · toque en el push → abre, resuscribe, ponte al día |
| El modo de falla | Usar el push como canal de datos, o esperar que los sockets sobrevivan al proceso |

## Ambos canales, en código

El patrón al que converge casi toda app de mensajería, pedidos y alertas:

**JavaScript:**

```javascript
// JavaScript — Back4app JS SDK: one channel per app state
// While the app is OPEN — the live query delivers the data itself
const messages = new Parse.Query('Message');
messages.equalTo('conversation', conversationId);
const sub = await messages.subscribe();
sub.on('create', (m) => appendBubble(m));   // full object, real time

// While it is CLOSED — push owns delivery: register this device
const installation = await Parse.Installation.currentInstallation();
installation.set('channels', [`user-${currentUser.id}`]);
await installation.save();
// A Cloud Code afterSave trigger sends the push to this channel —
// the OS shows the alert; the tap opens the app, which re-subscribes.
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK: one channel per app state
// While the app is OPEN — the live query delivers the data itself
final liveQuery = LiveQuery();
final messages = QueryBuilder<ParseObject>(ParseObject('Message'))
  ..whereEqualTo('conversation', conversationId);

final sub = await liveQuery.client.subscribe(messages);
sub.on(LiveQueryEvent.create, (m) => appendBubble(m)); // full object

// While it is CLOSED — push owns delivery: register this device
final installation = await ParseInstallation.currentInstallation();
installation.set('channels', ['user-$userId']);
await installation.save();
// A Cloud Code afterSave trigger sends the push to this channel —
// the OS shows the alert; the tap opens the app, which re-subscribes.
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK: one channel per app state
// While the app is OPEN — the live query delivers the data itself
let messages = Message.query("conversation" == conversationId)
let subscription = messages.subscribeCallback
subscription?.handleEvent { _, event in
  if case .created(let m) = event { appendBubble(m) }  // full object
}

// While it is CLOSED — push owns delivery: register this device
var installation = Installation.current
installation?.channels = ["user-\(userId)"]
installation?.save { _ in }
// A Cloud Code afterSave trigger sends the push to this channel —
// the OS shows the alert; the tap opens the app, which re-subscribes.
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK: one channel per app state
// While the app is OPEN — the live query delivers the data itself
val client = ParseLiveQueryClient.Factory.getClient()
val messages = ParseQuery.getQuery<ParseObject>("Message")
messages.whereEqualTo("conversation", conversationId)

val sub = client.subscribe(messages)
sub.handleEvent(SubscriptionHandling.Event.CREATE) { _, m ->
    appendBubble(m)                                  // full object
}

// While it is CLOSED — push owns delivery: register this device
val installation = ParseInstallation.getCurrentInstallation()
installation.put("channels", listOf("user-$userId"))
installation.saveInBackground()
// A Cloud Code afterSave trigger sends the push to this channel.
```

Fíjate en lo que resuelve cada mitad: la suscripción entrega *datos* — objetos enteros, eventos tipados, en tiempo real. El registro de la instalación reserva *atención* — el derecho a interrumpir al usuario más tarde, por un pipeline que tu app no controla.

## Dos entregas, dos dueños

Las rutas difícilmente podrían ser más distintas, y cada propiedad de la tabla comparativa se desprende de quién es dueño del último kilómetro.

Una **notificación push** sale de tu backend como una solicitud a un gateway operado por el sistema operativo — los gateways de push de iOS y Android (APNs, FCM), o un servicio de push del navegador hablando [RFC 8030](https://datatracker.ietf.org/doc/html/rfc8030) en la web. El gateway es dueño de la entrega: guarda mensajes para dispositivos offline, agrupa y limita bajo presión de batería, y despierta tu app o renderiza el banner. Ese poder prestado es todo el punto — *solo* el SO puede alcanzar un proceso que no está corriendo — y también toda la restricción: payloads limitados a unos 4 KB, entrega de mejor esfuerzo, despertares silenciosos racionados por día y un payload fuera del modelo de permisos de tu backend.

Una **live query** nunca sale de tu perímetro de confianza: la app mantiene un [WebSocket](/glossary/es/websockets/) con el servidor de suscripciones del backend, que compara cada escritura en la base de datos con la consulta suscrita y hace push de eventos tipados — create, update, enter, leave, delete — con [ACLs aplicadas por suscriptor](/glossary/es/live-queries-tiempo-real/). Objetos completos, latencia de tiempo real, sin techo de payload que valga la pena nombrar. La dependencia es brutal a cambio: la suscripción es estado dentro de tu proceso, y cuando el SO suspende la app — cosa que las plataformas móviles hacen agresivamente — el socket, y el canal, desaparecen.

```mermaid
flowchart TB
  accTitle: Enrutando la entrega en tiempo real según el estado de la app
  accDescr: Una escritura en la base de datos dispara la lógica del backend. Si la app del destinatario está abierta, una live query envía el objeto completo por WebSocket. Si la app está cerrada, el backend envía un payload pequeño por el gateway de push del sistema operativo, que muestra una notificación; al tocarla, la app abre, se resuscribe y se pone al día consultando.
  W["Escritura en la base de datos<br/>(mensaje, pedido, alerta)"] --> T["Trigger en el backend<br/>(afterSave)"]
  T -->|"app abierta"| LQ["Push por live query<br/>objeto completo · WebSocket"]
  T -->|"app cerrada"| GW["Gateway de push del SO<br/>(APNs, FCM)"]
  GW --> N["Banner de notificación<br/>payload de ~4 KB"]
  N -->|"toque"| O["La app abre →<br/>resuscripción + consulta de actualización"]
  LQ --> UI["La pantalla se actualiza en el lugar"]
  O --> UI
```

## Notificaciones push vs. live queries

| | Notificaciones push | Suscripciones de live query |
| --- | --- | --- |
| Alcanza una app cerrada | **Sí — el poder que la define** | No — la suscripción muere con el proceso |
| Payload | ~4 KB, opaco a tus ACLs | Objetos completos, con permisos verificados por suscriptor |
| Garantía de entrega | Mejor esfuerzo; agrupable, limitable, descartable | Confiable mientras hay conexión; requiere ponerse al día tras los huecos |
| Latencia | Del orden de segundos, depende del gateway | Tiempo real (~RTT) |
| Dueño del transporte | El SO y su gateway | La flota de WebSockets de tu backend |
| Consentimiento del usuario | Prompt de permiso; el usuario puede revocarlo | Ninguno — son los datos de tu propia app |
| Costo del mal uso | Fatiga de notificaciones, desinstalaciones | Carga de batería y de sockets si te suscribes de más |
| Hecha para | Atención y reenganche | Datos y estado dentro de la app |

Las filas se componen limpiamente porque los dos canales responden preguntas distintas: el push responde *"¿cómo alcanzo al usuario?"*, las live queries responden *"¿cómo se mantiene fiel la pantalla?"* — y por eso la [comparación a nivel de transporte](/glossary/es/sse-vs-websockets-vs-polling/) entre SSE, WebSockets y polling vive por completo dentro de la segunda pregunta.

## La costura: donde las apps realmente se rompen

Los bugs viven en la unión entre canales. Un usuario toca un push sobre un mensaje que *también* llegó por live query antes de que la app se suspendiera — deduplica por ID de objeto, no por canal. Llega un push sobre datos a los que el usuario ya no puede acceder — busca por la API normal al abrir y deja que las ACLs respondan, nunca confíes en el payload. La app estuvo cerrada tres días — la app reabierta no puede reproducir el hueco desde el push (las notificaciones no son un diario), así que la transición es siempre *resuscribirse y luego reejecutar la consulta base* para reconstruir la verdad, manteniendo el [registro del token de push](/glossary/es/notificaciones-push/) fresco en segundo plano. Diseña la costura una vez y ambos canales se vuelven aburridos — que es la meta.

## Casos de uso comunes

- **Chat y mensajería** — la live query renderiza la conversación abierta; el push lleva el "mensaje nuevo" por el estado cerrado. La app canónica de dos canales.
- **Seguimiento de pedidos y entregas** — la pantalla de seguimiento abierta se suscribe; los cambios a "entregado" con la app cerrada llegan como push.
- **Alertas operativas** — las consolas de guardia se suscriben para el tablero; la ruta del pager es push, porque nadie deja la app abierta a las 3 de la mañana.
- **Subastas y lanzamientos** — movimiento de precio en vivo dentro de la app; que te superen la oferta mientras no estás es un push, con deep link de vuelta a la pantalla en vivo.
- **Engagement social** — likes y respuestas llegan como push de reenganche; el feed abierto se vuelve vivo vía suscripción.

## ¿Qué canal deberías usar? Matriz de decisión

| Tu situación | Usa |
| --- | --- |
| La pantalla está abierta y debe mantenerse al día | Live query |
| El evento ocurre con la app cerrada y el usuario debe enterarse | Notificación push |
| El payload es sensible o está restringido por permisos | Live query — o push solo con identificadores, buscando al abrir |
| Necesitas entrega garantizada y ordenada de datos | Ninguno solo — actualización por consulta al abrir, canales como aceleradores |
| Actualizar un badge o contador dentro de la app en tiempo real | Live query |
| Reenganchar a usuarios que llevan días sin abrir la app | Push — es el único canal capaz |
| Kiosco o tablero de pared que nunca duerme | Solo live query; el push no aporta nada |

## Limitaciones y trade-offs

- **El push no es un canal de datos.** El techo de payload, el enrutamiento opaco fuera de tus ACLs y el agrupamiento lo hacen estructuralmente incorrecto para cargar estado — envía punteros, busca la verdad al abrir.
- **La entrega del push es una probabilidad, no una promesa.** Los optimizadores de batería, los permisos revocados y el throttling del gateway descartan mensajes en silencio; todo lo que no puede perderse necesita una ruta de reconciliación basada en consultas.
- **Las live queries se detienen en la frontera del proceso.** Ningún socket sobrevive a la suspensión; tratar una suscripción como canal siempre encendido es la premisa falsa detrás de la mayoría de los bugs de "perdimos eventos".
- **Ambos canales le cobran al cliente.** Las suscripciones demasiado amplias queman batería y matching en el servidor; el push demasiado ansioso quema buena voluntad — la desinstalación es el rate limiting del usuario.
- **La costura es responsabilidad tuya.** La deduplicación, las consultas de actualización y la renovación de tokens son lógica de aplicación; ninguno de los dos canales las regala.

## Push y live queries en Back4app

Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. Ambos canales vienen integrados y comparten una sola ruta de escritura: un trigger `afterSave` de Cloud Code sobre la misma escritura en la base de datos puede enviar el push — por las integraciones de la plataforma con los gateways, con segmentación por dispositivo y por canal — mientras [Live Query](/glossary/es/live-queries-tiempo-real/) propaga el objeto completo a cada cliente suscrito y con permisos verificados, automáticamente. El diagrama de enrutamiento de arriba colapsa en un trigger y una llamada de subscribe, y la lógica de la costura — consultas de actualización, registro del token vía la clase Installation — corre por los mismos SDKs que muestran las pestañas de código.
