[ GUIDE ]

Monitoring Laravel Vapor

Vapor runs on AWS Lambda — persistent-worker APM patterns don't fit. Here's what actually works for serverless Laravel.

QUICK ANSWER

How do I monitor a Laravel Vapor app?

Vapor runs on AWS Lambda, which rules out APMs that assume a long-running agent process. Pick: (1) Laravel Nightwatch Cloud — first-party and Vapor-compatible, (2) Sentry or AppSignal — HTTP-based SDKs that work inside Lambda, (3) ship CloudWatch logs to a log aggregator for log-level visibility. Track cold starts separately from warm requests — they tell different stories. NightOwl's long-running agent doesn't currently fit Vapor; we're evaluating a Lambda-compatible path.

Updated · 2026-04-13

Why Vapor is different

Each request runs in a Lambda function. Two meaningful consequences for monitoring:

  1. No persistent process. Agents that buffer telemetry in-process and flush via a background thread fit PHP-FPM / Octane, not Lambda. Lambda's execution model assumes the function returns, memory evaporates, next invocation starts fresh (or reuses a warm container).
  2. Cold starts dominate p95. Lambda cold starts on PHP add 500-2000ms depending on layer size. A route that looks slow at p95 might be 95% fast + 5% cold-starting — a very different bug than being uniformly slow.
  3. CloudWatch is the default. All stdout/stderr ends up in CloudWatch Logs. Powerful but expensive at scale; queries (CloudWatch Insights) cost per GB scanned.

Tracking cold starts

Detect cold starts by checking whether a Lambda invocation is handling its first request. Record alongside route and duration:

app/Http/Middleware/TrackColdStart.php

php
use Closure;
use Illuminate\Http\Request;

class TrackColdStart
{
    private static bool $invoked = false;

    public function handle(Request $request, Closure $next)
    {
        $isColdStart = !self::$invoked;
        self::$invoked = true;

        $request->attributes->set('is_cold_start', $isColdStart);

        return $next($request);
    }
}

Push is_cold_start to your telemetry. Split p95 by cold vs warm — a slow cold-path is a bundle-size problem (reduce Vapor package), a slow warm-path is an actual code/DB problem.

CloudWatch → log aggregator

Raw CloudWatch gets expensive for search. Stream logs out via a subscription:

text
Lambda logs
   ↓
CloudWatch Logs
   ↓  (subscription filter)
Kinesis Data Firehose / Lambda forwarder
   ↓
Axiom / Loki / Papertrail / S3 + Athena

Better Stack, Axiom, and Papertrail all have AWS CloudWatch integrations. For self-hosted: a small Lambda forwarder that ships logs to your Loki or OpenSearch.

Queue monitoring

Vapor queues are SQS + Lambda consumers. Key metrics:

  • ApproximateAgeOfOldestMessage — SQS metric, surfaces queue lag
  • ApproximateNumberOfMessagesVisible — queue depth
  • Lambda Errors / Throttles — job failures / concurrency limit hit
  • Lambda Duration — per-job runtime

All visible in CloudWatch metrics. Alert on rising age-of-oldest or throttle rate.

Scheduled tasks

Vapor's scheduler runs via EventBridge Rule → Lambda. Each invocation logs to CloudWatch. For structured tracking:

app/Console/Kernel.php

php
$schedule->command('reports:send')
    ->daily()
    ->onSuccess(fn() => /* push metric */)
    ->onFailure(fn() => /* push metric + alert */);

Vapor-compatible APM options

  • Laravel Nightwatch Cloud — first-party Laravel APM, designed with Vapor as a first-class target
  • Sentry — HTTP-based SDK, Lambda-safe. Tracks errors + performance spans
  • AppSignal — also HTTP-based, Lambda-safe
  • Datadog APM — Lambda Extension handles the agent-process problem

NightOwl currently assumes a persistent agent process and doesn't fit Lambda. If you're committed to Vapor, pick from the options above.

Frequently asked questions

How is monitoring Laravel Vapor different from a traditional Laravel app?

Vapor runs your Laravel app on AWS Lambda. That changes three things for monitoring: (1) no persistent worker process to run an agent daemon in, (2) cold starts add variable latency that dominates p95 on low-traffic routes, (3) CloudWatch is the default log destination and costs add up fast. APMs that assume a long-running agent process don't fit; either use vendor SDKs that ship from within the Lambda, or stream telemetry out via CloudWatch → your sink.

Can I use NightOwl with Laravel Vapor?

Not directly today. NightOwl's agent is a long-running TCP process — the model doesn't fit Lambda's execution environment. We're evaluating a Lambda-compatible ingestion path. For Vapor specifically, the pragmatic picks are Laravel Nightwatch Cloud (first-party, designed for Lambda), Sentry (HTTP-based SDK, lambda-safe), or AppSignal.

How do I track Vapor cold starts?

Two ways. Vapor's own dashboard shows cold-start counts per function. For per-request cold-start tracking, check if the REQUEST_ID in a Lambda execution is new — the first request a Lambda container handles is a cold start. Record it alongside the route and duration so you can split p95 into cold-path and warm-path buckets — they tell very different stories.

How do I monitor Vapor queues?

Vapor uses SQS under the hood and runs queue workers as Lambda functions triggered by SQS events. AWS CloudWatch surfaces queue depth and age-of-oldest-message. For per-job-class tracking (duration, failure rate, retries) you need an APM that instruments within Lambda. Nightwatch Cloud's Vapor support covers this; other APMs depend on SDK support.

What about Vapor scheduled tasks?

Vapor runs the Laravel scheduler via AWS EventBridge. CloudWatch logs show each invocation. For structured monitoring (duration trending, missed-run detection, success rate per task) wire up an APM. Or manually: attach ->onSuccess() and ->onFailure() to each scheduled task in Kernel.php and push metrics to CloudWatch or your APM.

Do Lambda limits affect Vapor monitoring?

Yes. 15-minute max execution kills long-running tasks regardless of code. 10MB response payload is a hard limit — big exports need presigned S3 URLs, not direct responses. Memory is bounded per function (up to 10GB). Monitor for Lambda errors like 'Task timed out after 900 seconds' — those are function crashes, not slow requests.

How do I aggregate Vapor CloudWatch logs?

CloudWatch log groups per Lambda function. Options: (1) keep logs in CloudWatch and search via CloudWatch Insights (expensive at scale), (2) subscribe a Kinesis stream and ship to Loki / Axiom / Papertrail, (3) use a log-aggregator's CloudWatch integration. See our log aggregation guide for the general patterns — substitute your CloudWatch subscription for the file-tailing step.

PRICING

Flat pricing. No event caps. No per-seat fees.

14-day free trial, no credit card. Your PostgreSQL, your data.

HOBBY

$5 /month

1 app · 14 days lookback · all Laravel events

TEAM

$15 /month

Up to 3 connected apps · unlimited environments · all Laravel events

AGENCY

$69 /month

Unlimited apps · unlimited agent instances · same flat rate at any traffic

Related