---
term: 'Live Queries en Tiempo Real'
seoTitle: 'Live Queries: suscripciones a consultas de base de datos en tiempo real'
headline: '¿Qué son las Live Queries en Tiempo Real?'
slug: live-queries-tiempo-real
category: api-realtime
shortDefinition: 'Una live query es una suscripción a una consulta de base de datos: el servidor envía eventos create, update y delete de los registros coincidentes al ocurrir.'
relatedTerms:
  - websockets-real-time-sync
  - event-driven-architecture
  - push-notifications-apns-fcm
  - database-triggers-beforesave-aftersave
contrastsWith:
  - websockets-real-time-sync
faq:
  - question: '¿Qué es una live query?'
    answer: 'Una suscripción permanente a una consulta de base de datos: en lugar de preguntar una vez y recibir una foto, te suscribes a la consulta y el servidor envía un evento cada vez que su conjunto de resultados cambia — un registro coincidente creado, actualizado, borrado o editado hacia dentro o hacia fuera de los resultados. Tu pantalla deja de hacer polling y empieza a escuchar.'
  - question: '¿En qué se diferencia una live query de una consulta normal?'
    answer: 'En el tiempo de vida. Una consulta normal corre, devuelve y termina — su respuesta empieza a envejecer de inmediato. Una live query queda registrada en el servidor: los resultados iniciales llegan igual, y luego eventos de cambio puntuales los mantienen al día hasta que cancelas la suscripción. El mismo lenguaje de predicados, la relación opuesta con el tiempo.'
  - question: '¿Cómo funcionan las live queries por debajo?'
    answer: 'Dos mitades unidas: una fuente de cambios y un transporte. La base de datos emite su flujo de escrituras — vía change streams, logs de replicación o triggers — y un servidor de suscripciones compara cada cambio contra los predicados de consulta registrados, enviando los eventos relevantes a los suscriptores por WebSockets. El SDK del cliente envuelve el ciclo de vida del socket para que tu código solo vea eventos tipados.'
  - question: '¿Qué son los eventos enter y leave?'
    answer: 'El par sutil que hace precisas a las suscripciones a consultas. Enter se dispara cuando un registro existente se edita y empieza a coincidir con tu predicado; leave, cuando una edición hace que deje de coincidir. Una tarea reasignada a ti entra en tu suscripción de asignadas-a-mí sin haber sido creada; reasignada a otro, sale sin haber sido borrada. Create, update y delete cubren el resto.'
  - question: '¿Por qué las live queries son mejores que el polling?'
    answer: 'De tres formas a la vez: latencia — los cambios llegan en tiempo real y no en el siguiente poll; ancho de banda — los eventos llevan solo lo que cambió en lugar de traer todo de nuevo; y carga — el servidor hace matching por cambio en lugar de correr consultas completas por cliente por intervalo. Hacer polling cada pocos segundos es una simulación; las suscripciones son la cosa real.'
  - question: '¿Qué agregan las live queries sobre WebSockets crudos?'
    answer: 'El cerebro de consultas. Un socket crudo mueve mensajes; todo lo demás — a qué clientes les importan qué cambios, qué significan los eventos, quién puede ver qué, ponerse al día tras reconectar — es código que escribes. Una capa de live queries hace el matching de predicados en el servidor, tipa los eventos, aplica permisos por suscriptor y gestiona el ciclo de vida del socket. Es la diferencia entre un transporte y una funcionalidad.'
  - question: '¿Las subscriptions de GraphQL son lo mismo que las live queries?'
    answer: 'La misma familia, distinto disparador. Las subscriptions de GraphQL se disparan con eventos nombrados que tú defines — una mutación publica, los suscriptores reciben. Las live queries se disparan con cambios en el conjunto de resultados de una consulta — sin cableado de eventos, el predicado es la suscripción. Ambas viajan por WebSockets; las live queries cambian diseño explícito de eventos por cobertura automática de cada ruta de escritura.'
  - question: '¿Cómo escalan las live queries?'
    answer: 'En dos ejes: conexiones — miles de sockets abiertos repartidos entre servidores de suscripción detrás de un backplane de pub/sub — y matching — cada escritura verificada contra los predicados registrados, y por eso importan las suscripciones selectivas sobre campos indexados. Las plataformas gestionadas operan ambos ejes por ti; la disciplina del lado del cliente es suscribirse de forma acotada y cancelar cuando las pantallas se cierran.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'LiveQuery documentation'
    url: 'https://docs.parseplatform.org/parse-server/guide/#live-queries'
  - name: 'MongoDB change streams documentation'
    url: 'https://www.mongodb.com/docs/manual/changestreams/'
  - name: 'LiveQuery protocol specification'
    url: 'https://github.com/parse-community/parse-server/wiki/Parse-LiveQuery-Protocol-Specification'
  - name: 'Back4app Live Query example'
    url: 'https://www.back4app.com/docs/platform/parse-server-live-query-example'
cta:
  title: 'Suscríbete a los datos, no a la plomería'
  text: 'Las Live Queries de Back4app convierten cualquier consulta en una suscripción: cinco eventos tipados, ACLs aplicadas por suscriptor y la flota de WebSockets gestionada por la plataforma. Funcionalidades en tiempo real en lo que tardas en escribir la consulta que ya tenías.'
  linkText: 'Empieza gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-31'
translationKey: real-time-live-queries
---

**Una live query es una suscripción a una consulta de base de datos: el servidor envía eventos create, update y delete de los registros coincidentes al ocurrir.** Es el tiempo verbal que le faltaba al acceso a datos: las consultas normales hablan en pasado ("qué coincidía cuando pregunté"), las live queries hablan en presente continuo ("qué coincide, a medida que cambia"). La pantalla deja de preguntar y empieza a mantenerse en lo correcto.

## Puntos clave

| Pregunta | Respuesta |
| --- | --- |
| Qué es | Una consulta permanente — te suscribes una vez, recibes cada cambio en sus resultados |
| Los cinco eventos | create · update · delete · **enter** · **leave** |
| Por debajo | Change stream de la base de datos → matching de predicados → push por WebSocket |
| vs. polling | Latencia en tiempo real, payloads del tamaño del delta, sin carga de consultas por intervalo |
| vs. sockets crudos | La capa de consultas: matching, eventos tipados, permisos, reconexiones |

## La suscripción, en código

El movimiento que lo define — toma la consulta que ya tenías, y suscríbete a ella:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// A live query: subscribe to a QUERY and receive its changes as events
const query = new Parse.Query('Task');
query.equalTo('assignee', currentUser);

const sub = await query.subscribe();
sub.on('create', (t) => addRow(t));       // new match appeared
sub.on('update', (t) => refreshRow(t));   // a match changed
sub.on('enter',  (t) => addRow(t));       // edited INTO the result set
sub.on('leave',  (t) => removeRow(t));    // edited OUT of the result set
sub.on('delete', (t) => removeRow(t));    // a match was deleted
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// A live query: subscribe to a QUERY and receive its changes as events
final liveQuery = LiveQuery();
final query = QueryBuilder<ParseObject>(ParseObject('Task'))
  ..whereEqualTo('assignee', currentUser);

final sub = await liveQuery.client.subscribe(query);
sub.on(LiveQueryEvent.create, (t) => addRow(t));     // new match
sub.on(LiveQueryEvent.update, (t) => refreshRow(t)); // match changed
sub.on(LiveQueryEvent.enter, (t) => addRow(t));      // edited into the set
sub.on(LiveQueryEvent.leave, (t) => removeRow(t));   // edited out of the set
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// A live query: subscribe to a QUERY and receive its changes as events
let query = Task.query("assignee" == currentUser)

let subscription = query.subscribeCallback
subscription?.handleEvent { _, event in
  switch event {
  case .created(let t):  addRow(t)        // new match appeared
  case .updated(let t):  refreshRow(t)    // a match changed
  case .entered(let t):  addRow(t)        // edited INTO the result set
  case .left(let t):     removeRow(t)     // edited OUT of the result set
  case .deleted(let t):  removeRow(t)
  }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// A live query: subscribe to a QUERY and receive its changes as events
val client = ParseLiveQueryClient.Factory.getClient()
val query = ParseQuery.getQuery<ParseObject>("Task")
query.whereEqualTo("assignee", currentUser)

val sub = client.subscribe(query)
sub.handleEvent(SubscriptionHandling.Event.CREATE) { _, t -> addRow(t) }
sub.handleEvent(SubscriptionHandling.Event.UPDATE) { _, t -> refreshRow(t) }
sub.handleEvent(SubscriptionHandling.Event.ENTER)  { _, t -> addRow(t) }
sub.handleEvent(SubscriptionHandling.Event.LEAVE)  { _, t -> removeRow(t) }
```

El vocabulario de eventos merece su tabla, porque **enter** y **leave** son lo que hace de esto una suscripción a *consultas* y no una notificación de tablas:

| Evento | Se dispara cuando… | Ejemplo (suscrito a "tareas asignadas a mí") |
| --- | --- | --- |
| create | Un registro nuevo coincide | Se crea una tarea para ti |
| update | Un registro coincidente cambia | El estado de tu tarea cambia |
| **enter** | Una edición hace coincidir un registro existente | Una tarea es *reasignada hacia* ti |
| **leave** | Una edición hace que una coincidencia deje de serlo | Tu tarea es reasignada a otro |
| delete | Un registro coincidente se borra | La tarea se elimina |

## El pipeline detrás del push

```mermaid
flowchart LR
  accTitle: Cómo funcionan las live queries de punta a punta
  accDescr: Las escrituras en la base de datos fluyen hacia un change stream; un servidor de suscripciones compara cada cambio contra los predicados de consulta registrados y hace push de eventos tipados por WebSockets a los clientes suscritos, con permisos verificados por suscriptor.
  W["Escrituras<br/>(cualquier cliente, cualquier API)"] --> DB[("Base de datos")]
  DB --> CS["Change stream<br/>(oplog / WAL / triggers)"]
  CS --> M["Servidor de suscripciones<br/>matching de predicados + chequeo de ACL"]
  M -->|"push por WebSocket"| C1["Suscriptor A"]
  M -->|"push por WebSocket"| C2["Suscriptor B"]
```

Dos mitades, limpiamente separables: la **fuente de cambios** — el propio feed de escrituras de la base de datos ([change streams](https://www.mongodb.com/docs/manual/changestreams/) en los almacenes de documentos, logs de replicación en el resto) — y la **capa de matching**, que compara cada cambio contra cada predicado registrado y hace push exactamente a los suscriptores cuyos resultados cambiaron, con permisos aplicados por suscriptor. El [protocolo abierto LiveQuery](https://github.com/parse-community/parse-server/wiki/Parse-LiveQuery-Protocol-Specification) es una implementación de referencia legible de toda esta forma.

## Live queries vs. polling vs. SSE vs. WebSockets

| Enfoque | Latencia | Payload | Costo de servidor | Tú construyes |
| --- | --- | --- | --- | --- |
| Polling | Intervalo del poll | Refetch completo cada vez | Consultas × clientes × frecuencia | Timers, diffing |
| Long polling | Casi tiempo real | Respuesta completa por evento | Solicitudes retenidas | Plomería de fallback |
| SSE | Tiempo real | Delta | Streams, un solo sentido | Diseño de eventos |
| WebSockets crudos | Tiempo real | Lo que tú definas | Conexiones + tu fan-out | **Todo** |
| **Live queries** | **Tiempo real** | **Eventos por cambio** | **Matching + conexiones (gestionado)** | **La consulta** |

La última columna es el argumento: con [sockets crudos](/glossary/es/websockets/) construyes el protocolo de mensajes, el enrutamiento, los chequeos de permisos y la puesta al día tras reconectar; con live queries el *predicado es el protocolo* y la plataforma es dueña del resto.

## Casos de uso comunes

- **Chat e inboxes** — suscríbete a los mensajes de la conversación; la llegada es un evento, no un refresh.
- **Dashboards en vivo** — pedidos, métricas, flotas: la consulta define la vista, los eventos la mantienen verdadera.
- **Apps colaborativas** — tableros de tareas y documentos compartidos donde las ediciones de cinco personas se entrelazan en segundos.
- **Presencia y estado** — quién está en línea, qué está en curso — enter/leave haciendo su trabajo de precisión.
- **Pantallas operativas** — consolas de soporte y vistas de administración que deben reflejar producción *ahora*, no el último refresh.

## ¿Poll, push o suscripción? Matriz de decisión

| Elige live queries cuando… | Herramientas más simples bastan cuando… |
| --- | --- |
| Los usuarios miran datos compartidos que cambian | Los datos cambian rara vez — poll suave o refetch al enfocar |
| Los cambios vienen de muchos escritores y rutas | Un solo escritor podría simplemente hacer push vía SSE |
| La vista es naturalmente una consulta | El mensaje no tiene forma de datos (usa sockets directamente) |
| Los permisos deben filtrar lo que cada espectador ve | Todo es difusión pública |
| Prefieres no ser dueño de la infraestructura de fan-out | Ya operas una plataforma de tiempo real |

La disciplina del lado del cliente que mantiene sanas las suscripciones, elijas lo que elijas: suscríbete de forma *acotada* (predicados selectivos sobre campos indexados) y cancela la suscripción cuando la pantalla se cierra — las consultas permanentes son estado del servidor, y las pantallas que las filtran acumulan costo de forma invisible.

## Limitaciones y trade-offs

- **El matching es una carga de trabajo real.** Cada escritura se verifica contra los predicados registrados; miles de suscripciones amplias sobre clases calientes lo multiplican — la selectividad es la palanca.
- **Las conexiones son estado.** La flota de sockets necesita afinidad, heartbeats y backplanes de fan-out — las plataformas gestionadas existen precisamente porque esto es trabajo pesado sin diferenciación.
- **Las reconexiones necesitan puesta al día.** Un cliente que estuvo offline se perdió eventos; los flujos robustos vuelven a correr la consulta base al resuscribirse en lugar de confiar en que el hueco estuvo tranquilo.
- **El orden y la entrega tienen forma de at-least-once.** Handlers de eventos idempotentes (aplica por ID de objeto, no por append) absorben con gracia el duplicado ocasional.
- **No todo quiere una suscripción.** Los datos poco vistos y poco cambiados son territorio de polling; las live queries ganan su costo donde ojos y escrituras son ambos frecuentes.

## 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. [Live Query](https://www.back4app.com/docs/platform/parse-server-live-query-example) es su capa de tiempo real, y las pestañas de código de arriba son toda la historia del cliente: el mismo constructor de consultas que ya usas, una llamada de suscripción, cinco eventos tipados — con ACLs verificadas por suscriptor para que el tiempo real nunca se salte el modelo de permisos, y con la flota de WebSockets, los change streams y el fan-out corriendo como infraestructura gestionada. Habilita Live Query en una clase desde el dashboard, suscríbete desde cualquier SDK, y el presente continuo pasa a ser una funcionalidad, no un proyecto.
