Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

timgavin's avatar

Debugbar Shows over 300 queries

I just installed Laravel Debugbar and it's showing 320 queries on my page, many of them duplicates and from other methods.

it's almost as if I'm seeing every single query in my app all at once.

I'm accessing my index() method, which is very simple and uses eager loading, so I'm at a loss as to what's happening or even where to begin looking for answers.

My index method. Surely this isn't producing 320 queries...

public function index()
    {
        $user = User::where('id', auth()->user()->id)
            ->with('following')
            ->with('categories')
            ->first();

        $mycats = $user->categories->pluck('category_id')->toArray();

        return view('explore.index', compact('mycats'));
    }

Here's the message from debugbar: 320 statements were executed, 315 of which were duplicated, 5 unique

Any suggestions?

0 likes
11 replies
tykus's avatar

What are the duplicated queries?

Snapey's avatar
Snapey
Best Answer
Level 122

do you have view composers?

btw as you are not actually passing the user to the view, just eager loading relations, you could do this with just

    auth()->user()->load('following','categories');
1 like
timgavin's avatar

@Snapey Yep, sure do have view composers, and that's definitely what's causing the issue. Not sure how to fix though.

What I'm doing is just gathering information about the user's account, such as followers, who they blocked, etc.

Here's one of the things I'm doing in my View Controller which is causing so many queries.

In the view composer

public function compose(View $view)
{
    $view->with('access', User::getAccess());
    ...

In User

public static function getAccess()
    {
        if (auth()->guest()) {
            return [];
        }

        $collection = new \Illuminate\Database\Eloquent\Collection();
        $collection->memberships = auth()->user()->memberships()->where('rebill_attempts', null)->pluck('price');
        $collection->purchased = auth()->user()->purchased()->pluck('post_id');

        return $collection;
    }

Also, thanks for the eager loading tip, that's awesome!

EDIT

So after some investigating, I believe this is the culprit in my GlobalServiceProvider

public function boot(ViewFactory $view)
    {
        $view->composer('*', \App\Http\ViewComposers\GlobalComposer::class);
    }

not sure how to fix this though.

Snapey's avatar

you need to replace the * with the names of the views that need the shared data. otherwise the composer is run for every included view.

timgavin's avatar

Yeah, that's actually what I mean when I said "not sure how to fix this." I knew that's what I should do, but not sure how. Sorry for my bad communication skills.

I'm reading the docs, but it's just not clicking for me. Where do I get the names of the views? if I have views/app.blade.php would app be the view name?

$view->composer('app', \App\Http\ViewComposers\GlobalComposer::class);

I tried that but it didn't work. That information basically need to be available everywhere, so I was receiving errors.

This didn't work either.

$view->composer('layouts.app', \App\Http\ViewComposers\GlobalComposer::class);

I've thought about storing all of this data in Redis but can't figure out how to get the user's information after login.

timgavin's avatar

Here's what I ended up doing. I added the information to a session after the user logged in, and then accessed that session in the view composer, which greatly reduced my queries.

protected function sendLoginResponse(Request $request)
{
    $request->session()->regenerate();

    $request->session()->put('access', \App\User::getAccess());
    $request->session()->put('blocking', \App\User::getBlocking());
    $request->session()->put('followers', \App\User::getFollowers());
    $request->session()->put('following', \App\User::getFollowing());

    $this->clearLoginAttempts($request);
    return $this->authenticated($request, $this->guard()->user())
            ?: redirect()->intended($this->redirectPath());
}

is there a drawback to storing collections in a session? Or should I port this over to Redis?

Snapey's avatar

Hi The problem I have found with the view composers and * that is not immediately obvious i that if you have a partial in a loop then the composer is called for each inclusion (like an n+1 problem for views)

the view composer can take an array of strings, with the string being the same as you would use in a controller to specify the view;

$view->composer(['posts.index', 'posts.edit', 'posts.create'], \App\Http\ViewComposers\GlobalComposer::class);

if all those extended resources/views/layouts/master.blade.php then you can just mention the master layout and all those that extend it will have access to the variables.

$view->composer('layouts.master', \App\Http\ViewComposers\GlobalComposer::class);
timgavin's avatar

Unfortunately, it's much more complex than that, so I ended up creating a bunch of functions in a helper file and moving them into that. I'm still running more queries than I want, but it's much, much better than before, and will go a long way in helping me break this down further and figure out a better solution.

Thanks for your help!

timgavin's avatar

@ederson Not really, because the information gathered has to be up-to-date.

For instance, if a user follows someone, and the query is cached, they may refresh the page and it would look like they're not following that person, so they might keep hitting the follow button thinking something is wrong.

Edit: I am, however, looking into storing the query results in Redis, and updating that each time a user makes a change.

ederson's avatar

My idea was that you could cache it for a few seconds so they won't be repeated in the same request ...

I had a similar problem and caching solved but maybe your data change faster

Please or to participate in this conversation.