Hace unas semanas me tocó trabajar en una tarea que parecía bastante simple al principio: procesar acciones pesadas de manera asíncrona en una aplicación Laravel.
Lo típico.
Enviar emails, generar archivos, sincronizar información con APIs externas, procesar imágenes, ejecutar tareas demoradas, etc.
Mi primera reacción fue la misma que probablemente tendría cualquier desarrollador Laravel: usar queues y levantar workers.
Algo como:
php artisan queue:work
Y listo.
Pero apareció el problema real: infraestructura.
El proyecto estaba completamente montado sobre Google Cloud Platform y el equipo quería evitar mantener procesos corriendo permanentemente dentro de VMs o contenedores dedicados solamente para workers.
Y ahí fue donde descubrí que, si ya estás trabajando dentro del ecosistema de Google Cloud, probablemente no necesites administrar workers manualmente.
Google ya tiene un servicio diseñado exactamente para esto: Google Pub/Sub.
El problema real de los workers tradicionales
- Supervisord
- Docker containers dedicados
- ECS Tasks
- Kubernetes deployments
- Procesos permanentes escuchando colas
- Reinicios automáticos
- Escalado manual
- Monitoreo adicional
Todo eso solamente para ejecutar tareas en background.
Y aunque Laravel hace que trabajar con queues sea extremadamente cómodo, la realidad es que la infraestructura detrás puede complicarse bastante.
Especialmente cuando:
tenemos picos de tráfico
- necesitamos auto scaling, queremos arquitectura serverless, queremos reducir costos operativos, no queremos administrar procesos vivos permanentemente
En mi caso, el proyecto ya estaba usando:
- Cloud Run
- Cloud Functions
- servicios administrados de Google Cloud
Entonces apareció una pregunta bastante lógica:
¿Por qué seguir administrando workers si Google ya ofrece un sistema distribuido de mensajería y procesamiento asíncrono?
¿Qué es Google Pub/Sub?
Google Pub/Sub es un servicio de mensajería asíncrona completamente administrado por Google Cloud.
La idea principal es desacoplar quién genera eventos de quién los procesa.
En otras palabras:
- una aplicación publica mensajes
- otra aplicación los consume
- ambas no necesitan conocerse entre sí
- ambas pueden ejecutarse en momentos distintos
- ambas pueden escalar independientemente
Google define Pub/Sub como un sistema de comunicación asíncrona entre servicios.
Y esa palabra es clave:
Asíncrono
¿Qué significa realmente “asíncrono”?
Cuando hacemos algo síncrono, el flujo espera a que la operación termine.
Por ejemplo:
$user = User::create($data);
Mail::to($user)->send(new WelcomeEmail());
return response()->json([
'success' => true
]);
Aquí el request HTTP queda esperando:
guardar usuario, generar email, conectarse al proveedor SMTP, enviar email, recién devolver respuesta
Si el proveedor SMTP tarda 5 segundos, el usuario espera 5 segundos.
Eso es procesamiento síncrono.
Con procesamiento asíncrono cambia completamente el flujo:
$user = User::create($data);
PublishWelcomeEmailJob::dispatch($user);
return response()->json([
'success' => true
]);
Ahora:
- se guarda usuario
- se publica un mensaje
- el request termina inmediatamente
- otro proceso ejecutará el trabajo después
El usuario recibe respuesta instantánea.
Y ahí aparece Pub/Sub.
Cómo funciona Google Pub/Sub
Pub/Sub funciona con tres conceptos principales:
- Topics
- Publishers
- Subscribers
Topic
Un topic es un canal donde se publican mensajes.
Ejemplo:
user-created
O:
send-emailEs simplemente un “tema” de eventos.
Publisher
El publisher es quien envía mensajes al topic.
Por ejemplo Laravel:
$pubSub->topic('send-email')->publish([
'data' => json_encode([
'email' => $user->email
])
]);
Laravel publica un mensaje y termina.
No procesa nada.
No espera nada.
No ejecuta el trabajo pesado.
Solo envía el evento.
Subscriber
El subscriber es quien escucha el topic y procesa el mensaje.
Por ejemplo:
- Cloud Run
- Cloud Functions
- otro microservicio
- otro backend
- un worker serverless
Este subscriber recibe el mensaje y ejecuta el trabajo.
Entonces… ¿quién hace el trabajo pesado?
Depende de tu arquitectura.
Normalmente en Google Cloud se combina con:
- Cloud Run
- Cloud Functions
- GKE
- otros microservicios
Por ejemplo:
Flujo completo
1. Laravel recibe request
POST /register
2. Laravel publica mensaje
{
"user_id": 10,
"email": "test@test.com"
}
3. Pub/Sub recibe mensaje
El mensaje queda almacenado temporalmente.
4. Subscriber recibe mensaje
Cloud Run o Cloud Function lo consume.
5. Subscriber ejecuta lógica
Mail::to($email)->send(...);
6. Subscriber confirma procesamiento
Pub/Sub marca el mensaje como procesado.
¿Qué pasa si el subscriber falla?
Aquí aparece una de las mejores partes del sistema.
Pub/Sub tiene retries automáticos.
Si el consumidor falla:
- el mensaje no se pierde
- Pub/Sub vuelve a enviarlo
- puede reintentarse múltiples veces
- incluso puede enviarse a Dead Letter Queues
Todo esto sin que tengas que construir infraestructura manualmente.
¿Por qué esto puede reemplazar workers tradicionales?
Porque en muchos casos:
Ya no necesitas procesos vivos permanentemente
No necesitas:
php artisan queue:work
corriendo 24/7.
Ahora Google activa instancias automáticamente cuando llegan mensajes.
Eso significa:
- auto scaling real
- pago por uso
- cero administración de workers
- arquitectura serverless
- menos DevOps
Diferencia conceptual importante
Queue tradicional
Laravel Queue
↓
Redis
↓
Worker permanente
Pub/Sub
Laravel
↓
Pub/Sub
↓
Cloud Run / Functions
La diferencia grande es que Google administra toda la capa de mensajería y escalado.
Ventajas reales que encontré usando Pub/Sub
1. Escalado automático
Si llegan:
- 10 mensajes
- 1000 mensajes
- 1 millón de mensajes
Google escala automáticamente los consumidores.
2. Menos infraestructura
No hay:
- supervisord
- workers colgados
- memory leaks
- reinicios manuales
3. Arquitectura desacoplada
Tu API ya no conoce quién procesa.
Solo publica eventos.
Eso permite:
- microservicios
- múltiples consumidores
- sistemas distribuidos
- event-driven architecture
Una ventaja enorme: múltiples subscribers
Con queues tradicionales normalmente un job lo procesa un solo worker.
Pero con Pub/Sub:
Topic: user-created
Puede ser consumido por:
- analytics service
- email service
- billing service
- CRM sync service
Todos al mismo tiempo.
El mismo evento dispara múltiples procesos independientes.
Eso es extremadamente poderoso.
Pull vs Push subscriptions
Pub/Sub soporta dos formas de consumir mensajes.
Pull
Tu aplicación pregunta constantemente:
¿Hay mensajes?
¿Hay mensajes?
¿Hay mensajes?
Muy parecido a workers tradicionales.
Push
Pub/Sub envía automáticamente el mensaje a un endpoint HTTP.
Por ejemplo:
POST https://my-service.com/pubsub-handler
Esto encaja perfecto con:
- Cloud Run
- Cloud Functions
Y permite arquitecturas completamente serverless.
¿Es realmente rápido?
Sí.
Google menciona latencias del orden de ~100ms.
En la práctica:
- eventos
- emails
- sincronizaciones
- webhooks
- pipelines
funcionan prácticamente en tiempo real.
Casos ideales para usar Pub/Sub
Lo usaría especialmente para:
- envío de emails
- procesamiento de imágenes
- eventos de usuarios
- sincronización entre microservicios
- webhooks
- pipelines de datos
- notificaciones
- analytics
- eventos de dominio
Casos donde quizás NO usaría Pub/Sub
No todo debería resolverse con Pub/Sub.
Por ejemplo:
- tareas extremadamente secuenciales
- jobs que requieren orden estricto complejo
- procesamiento síncrono inmediato
- tareas pequeñas que no justifican infraestructura distribuida
Incluso Google diferencia Pub/Sub de Cloud Tasks dependiendo del caso de uso.
Integración con Laravel
La integración realmente es bastante simple.
Google ofrece SDK oficial para PHP.
composer require google/cloud-pubsub
Luego:
use Google\Cloud\PubSub\PubSubClient;
$pubSub = new PubSubClient([
'projectId' => env('GOOGLE_CLOUD_PROJECT'),
]);
$topic = $pubSub->topic('send-email');
$topic->publish([
'data' => json_encode([
'email' => $user->email,
]),
]);
Y listo.
Laravel publica el evento.
El resto lo maneja la infraestructura.
Acá te dejo un diagrama visual de la arquitectura: 
La parte más importante que entendí
Pub/Sub no es simplemente “otra queue”.
Es un cambio de mentalidad.
Pasas de:
"ejecutar jobs"
a:
"publicar eventos"
Y eso cambia completamente cómo diseñás sistemas distribuidos.

