To install Laravel Telescope in Laravel 13, run composer require laravel/telescope --dev, then php artisan telescope:install and php artisan migrate. Open /telescope in the browser to inspect requests, queries, jobs, exceptions, mail and more. In production, restrict access with a gate or leave it out entirely.
This guide targets Laravel 13 on PHP 8.3 to 8.5. Commands follow the Telescope documentation for the 13.x docs. The code here was written for this article and not executed in a live project.
What is Laravel Telescope used for?
Telescope is a debug assistant that records what your app does while it handles requests. Its dashboard lists HTTP requests, database queries (with durations), queued jobs, exceptions, log entries, mail, notifications, cache operations, scheduled tasks and dumps. It is most useful in local and staging environments to find N+1 queries, slow SQL and failing jobs.
Prerequisites
- A Laravel 13 project with a configured database.
- PHP 8.3+ and Composer.
Step 1: How do you install Telescope?
composer require laravel/telescope --dev
php artisan telescope:install
php artisan migratetelescope:install publishes the config file, assets and the TelescopeServiceProvider. The migration creates the tables where entries are stored.
Step 2: How do you install it for local development only?
Because the package is a dev dependency, it must not load in production where it is not installed. Stop automatic discovery by adding this to composer.json:
"extra": {
"laravel": {
"dont-discover": [
"laravel/telescope"
]
}
}Then register the provider manually in AppServiceProvider::register(), and remove the provider that telescope:install added to bootstrap/providers.php so it is not registered twice.
public function register(): void
{
if ($this->app->environment('local')) {
$this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
$this->app->register(TelescopeServiceProvider::class);
}
}Here TelescopeServiceProvider refers to App\Providers\TelescopeServiceProvider, so add a use statement for it.
Step 3: How do you open the dashboard?
Start the app and visit /telescope. In the local environment anyone can open it by default. Click around your app, then reload the dashboard to see new entries.
How do you restrict access outside local?
If you do run Telescope on a staging server, edit the gate() method in app/Providers/TelescopeServiceProvider.php:
protected function gate(): void
{
Gate::define('viewTelescope', function ($user) {
return in_array($user->email, [
'admin@example.com',
]);
});
}Never leave this open on a public production site. Telescope records request payloads, headers and queries, and may expose sensitive data.
How do you hide sensitive data?
In the same provider, use hideSensitiveRequestDetails() to mask tokens and cookies outside local:
protected function hideSensitiveRequestDetails(): void
{
if ($this->app->environment('local')) {
return;
}
Telescope::hideRequestParameters(['_token']);
Telescope::hideRequestHeaders([
'cookie',
'x-csrf-token',
'x-xsrf-token',
]);
}How do you control what Telescope records?
Use the filter callback in the provider's register() method to keep only the entries you care about. This example keeps everything locally and only important entries elsewhere.
Telescope::filter(function (IncomingEntry $entry) {
if ($this->app->environment('local')) {
return true;
}
return $entry->isReportableException() ||
$entry->isFailedRequest() ||
$entry->isFailedJob() ||
$entry->isScheduledTask() ||
$entry->hasMonitoredTag();
});You can also turn individual watchers on or off in the watchers array of config/telescope.php. To pause recording entirely, set TELESCOPE_ENABLED=false in .env.
How do you stop the database from filling up?
Telescope stores every entry, so the tables grow quickly. Schedule the prune command in routes/console.php:
use Illuminate\Support\Facades\Schedule;
Schedule::command('telescope:prune --hours=48')->daily();This deletes entries older than 48 hours. You can run php artisan telescope:clear to delete all entries immediately.
How do you find an N+1 query problem?
- Open the page that loads a list, for example a table of posts with their authors.
- In Telescope, open the Requests tab and click the request.
- Look at the Queries panel. If you see the same
select * from users where id = ?repeated once per row, you have an N+1 problem. - Fix it with eager loading:
Post::with('author')->get(). - Reload and confirm the repeated queries are gone.
Common mistakes
- Running
composer install --no-devin production with Telescope still registered. This causes a "class not found" error. Use the conditional registration above. - Registering the provider twice. Leaving it in
bootstrap/providers.phpand also inAppServiceProvidercreates duplicate routes. - Skipping migrations. The dashboard errors out because the
telescope_entriestable does not exist. - Never pruning. Tables can grow to gigabytes on a busy app.
- Leaving it open to the public. Always check the gate outside local.
How do you verify it works?
- Open
/telescopeand confirm the dashboard loads without errors. - Visit another route in your app and confirm it appears under Requests.
- Throw a test exception and confirm it appears under Exceptions.
- Run
php artisan route:list --path=telescopeto confirm the routes exist only where you expect.
FAQ
Is Telescope safe for production?
It can be used with a strict gate and filters, but it adds overhead and stores sensitive data. Most teams use it only in local and staging.
Telescope or Debugbar?
Debugbar shows data for the current page in a toolbar. Telescope stores history, including jobs, mail and exceptions, and lets you browse it later.
Does it record queued jobs?
Yes, through the job watcher. Run a queue worker to see jobs appear.



