Monitor Your Laravel App with LaraScope

You've deployed your Laravel app. Users are hitting your endpoints. But do you know which routes are slow? How many SQL queries a single request fires? How much memory it's consuming?
Most of the time, we find out about these things after something breaks. LaraScope fixes that, it's a Laravel package I built to give you real-time visibility into every HTTP request your app handles, with zero setup friction.
In this article, I'll walk you through what LaraScope does, how it works, and how to get it running in your project in under 5 minutes.
The Problem
Debugging performance issues in Laravel usually means one of the following:
Dumping queries with
DB::enableQueryLog()and forgetting to remove itInstalling Laravel Telescope (great tool, but heavy if you only care about HTTP + SQL)
Paying for an external APM service and sending your data to a third party
I wanted something in the middle, lightweight, self-hosted, and focused.
Introducing LaraScope
LaraScope is a Laravel package that automatically logs every HTTP request passing through your app, capturing:
✅ HTTP method, URL, path, and named route
✅ Response status code
✅ Request duration (ms)
✅ Peak memory usage (MB)
✅ Every SQL query fired, with raw SQL, bindings, and execution time
✅ Slow query detection with a configurable threshold
✅ Authenticated user ID
✅ Request headers (with sensitive ones stripped by default)
All of this is stored in your own database, and browsable through a built-in dashboard, no external service, no API key, no data leaving your infrastructure.
Installation
Getting started is a single command:
composer require amjadah/larascope
Then publish the config and migration:
php artisan vendor:publish --tag=larascope-config
php artisan vendor:publish --tag=larascope-migrations
php artisan migrate
That's it. LaraScope automatically injects itself into your web and api middleware groups. No manual Kernel.php edits, no service provider registration, it just works.
The Dashboard
Once installed, navigate to /larascope in your browser and you'll see the live request log.
The list gives you an at-a-glance view of every request: method badge, path, status code, how long it took, how many queries it ran, and peak memory. You can immediately spot the slow ones.
Filtering
The dashboard comes with built-in filters so you're not drowning in noise:
You can filter by:
HTTP Method: show only
POSTorGETrequestsStatus Code: find all
500errors or404s in secondsPath: search by partial path, e.g.
/api/users
🚧 Coming soon: I'm working on advanced filters, think filtering by slow queries, response time ranges, and more. The goal is to make the dashboard a proper debugging tool, not just a log viewer.
Request Detail
Click any entry to drill into the full detail view:
Here you get:
The full URL and route name
All SQL queries with their raw SQL, bindings, execution time, and a "slow" badge if they exceeded your threshold
Request headers (after filtering out
Authorization,Cookie, andX-CSRF-TOKEN)Peak memory usage
Total request duration
Slow Query Detection
One of my favourite features. Every captured SQL query is automatically compared against a configurable threshold:
// config/larascope.php
'queries' => [
'enabled' => true,
'slow_threshold_ms' => 100, // flag any query taking over 100ms
],
If a query exceeds the threshold, it gets flagged as slow. The RequestLog model even exposes a helper for this:
$log->hasSlowQueries(); // true if any query was slow
Privacy First
LaraScope is designed to be production-safe out of the box.
Request and response bodies are disabled by default. You have to explicitly opt in:
'logging' => [
'include_request_headers' => true,
'include_request_body' => false, // opt-in
'include_response_body' => false, // opt-in
// Sensitive headers are always stripped:
'exclude_headers' => [
'authorization',
'cookie',
'x-csrf-token',
],
],
You can also exclude entire paths or HTTP methods from being logged:
'exclude_paths' => ['health', '_debugbar/*', 'telescope/*'],
'exclude_methods' => ['OPTIONS'],
💡 Dashboard routes (
/larascope/*) are always auto-excluded to prevent infinite log growth.
Securing the Dashboard
By default the dashboard is open. Before going to production, add auth to its middleware:
'dashboard' => [
'path' => env('LARASCOPE_DASHBOARD_PATH', 'larascope'),
'middleware' => ['web', 'auth'], // 👈 add this
],
Keeping Logs Under Control
LaraScope ships with a built-in prune command to clean up old records:
php artisan larascope:prune
By default it retains 30 days of logs. Schedule it so you never have to think about it:
// routes/console.php (Laravel 11+)
Schedule::command('larascope:prune')->daily();
Octane Compatible
LaraScope is built to work correctly with Laravel Octane. Since the middleware can be a singleton in a persistent runtime, every request resets its own state at the start of handle(), preventing query data from bleeding across requests.
LaraScope vs. Telescope
A fair question: why not just use Telescope?
| Feature | LaraScope | Telescope |
|---|---|---|
| HTTP request logging | ✅ | ✅ |
| SQL query logging | ✅ | ✅ |
| Slow query flagging | ✅ | ✅ |
| Memory tracking | ✅ | ❌ |
| Jobs / Queues / Mail | ❌ | ✅ |
| Exception tracking | ❌ | ✅ |
| Built-in dashboard | ✅ | ✅ |
| Privacy defaults | Strict | Moderate |
| Setup overhead | Minimal | Moderate |
If you need full-stack observability, jobs, mail, notifications, exceptions, Telescope is the right call. If you want fast, focused HTTP + SQL monitoring with minimal setup, LaraScope is a great fit.
Wrapping Up
LaraScope started as a personal tool because I kept reaching for DB::enableQueryLog() in the same five situations over and over. Packaging it up properly forced me to think about edge cases I hadn't considered, Octane state isolation, privacy defaults, log growth, and the result is something I actually use in my own projects.
If it solves a problem you've had, give it a try and drop a ⭐ on the repo.
GitHub: github.com/amjadAH/larascope
composer require amjadah/larascope
Have a feature request or found a bug? Open an issue on GitHub, contributions are welcome!


