Imagina que necesitas registrar logs, enviar métricas o limpiar archivos temporales después de procesar una petición. Normalmente esto retrasa la respuesta al usuario. Con defer() ejecutas ese código después de enviar el response.
Compatibilidad
Laravel: 11+
PHP: 8.2+
¿Qué hace defer()?
defer() registra un callback que se ejecutará una vez que la respuesta HTTP haya sido enviada al cliente. El usuario recibe su respuesta inmediatamente, y el código diferido se ejecuta después.
<?php
use function Illuminate\Support\defer;
Route::post('/pedidos', function (Request $request) {
$order = Order::create($request->validated());
// Esto se ejecuta DESPUÉS de enviar la respuesta
defer(fn () => Metrics::track('order_created', $order->id));
return response()->json($order); // El usuario recibe esto inmediatamente
});Casos de uso ideales
Logging y métricas
<?php
use function Illuminate\Support\defer;
class PaymentController extends Controller
{
public function store(PaymentRequest $request): JsonResponse
{
$payment = $this->paymentService->process($request->validated());
defer(function () use ($payment) {
Log::channel('payments')->info('Pago procesado', [
'payment_id' => $payment->id,
'amount' => $payment->amount,
]);
Metrics::increment('payments.processed');
});
return response()->json(['status' => 'success']);
}
}Limpieza de archivos temporales
<?php
use function Illuminate\Support\defer;
class ExportController extends Controller
{
public function download(string $reportId): BinaryFileResponse
{
$tempPath = $this->generateReport($reportId);
// Eliminar archivo después de enviarlo
defer(fn () => Storage::delete($tempPath));
return response()->download(storage_path($tempPath));
}
}Sincronización con servicios externos
<?php
use function Illuminate\Support\defer;
class ProductController extends Controller
{
public function update(Product $product, ProductRequest $request): JsonResponse
{
$product->update($request->validated());
// Sincronizar con CRM sin bloquear al usuario
defer(fn () => CrmService::sync($product));
return response()->json($product);
}
}Cache warming
<?php
use function Illuminate\Support\defer;
class CategoryController extends Controller
{
public function store(CategoryRequest $request): JsonResponse
{
$category = Category::create($request->validated());
// Precalentar caché de categorías
defer(fn () => Cache::forget('categories.tree'));
defer(fn () => app(CategoryService::class)->warmCache());
return response()->json($category, 201);
}
}Múltiples defers
Puedes registrar varios defer(). Se ejecutan en orden FIFO (primero en entrar, primero en salir):
<?php
use function Illuminate\Support\defer;
defer(fn () => logger('Primero'));
defer(fn () => logger('Segundo'));
defer(fn () => logger('Tercero'));
// Log: Primero, Segundo, TerceroCancelar un defer
Puedes nombrar un defer y cancelarlo antes de que se ejecute:
<?php
use function Illuminate\Support\defer;
defer(fn () => Metrics::track('page_view'), 'tracking');
if ($user->hasOptedOut()) {
defer()->forget('tracking');
}defer() vs Queues
Aspecto | defer() | Queues |
|---|---|---|
Ejecución | Mismo proceso, después del response | Proceso separado (worker) |
Infraestructura | Ninguna | Redis, database, etc. |
Reintentos | No | Sí |
Tareas largas | No recomendado | Ideal |
Latencia | Milisegundos | Depende del worker |
Usa defer() para:
Tareas rápidas (< 1 segundo)
Logging y métricas
Limpieza menor
Cuando no necesitas reintentos
Usa Queues para:
Envío de emails
Procesamiento de imágenes
Llamadas API lentas
Cualquier cosa que pueda fallar y necesite reintento
Consideraciones importantes
No uses defer para tareas críticas
Si el servidor muere antes de ejecutar el defer, el código se pierde:
<?php
// ❌ Malo: si falla, pierdes el pago
defer(fn () => $this->confirmPayment($order));
// ✅ Bueno: usa queue para tareas críticas
ConfirmPaymentJob::dispatch($order);Acceso a variables
Los closures capturan variables por valor. Cuidado con objetos que pueden cambiar:
<?php
use function Illuminate\Support\defer;
$user = User::find(1);
defer(function () use ($user) {
// $user tiene los datos del momento en que se registró el defer
Log::info($user->name);
});
$user->name = 'Nuevo nombre'; // Esto NO afecta al deferConclusión
defer() es perfecto para esas pequeñas tareas que no quieres que afecten el tiempo de respuesta pero que tampoco justifican la complejidad de una cola. Logging, métricas, limpieza... todo eso puede ir después del response.
Curso Laravel 12
Completo 2026
El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.
star Incluido en cualquier suscripción