Filament Multi-Panel Auth &amp; Table Query Tuning | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.msaied.com) [ Home ](https://www.msaied.com) [ Projects ](https://www.msaied.com/projects) [ Articles  ](https://www.msaied.com/articles) [ Certificates ](https://www.msaied.com/certificates) [ Contact ](https://www.msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://www.msaied.com) [ Projects ](https://www.msaied.com/projects) [ Articles ](https://www.msaied.com/articles) [ Certificates ](https://www.msaied.com/certificates) [ Contact ](https://www.msaied.com#contact-section) 

  [ home ](https://www.msaied.com)    [ articles ](https://www.msaied.com/articles)    Filament at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning        On this page       1. [  Why Multi-Panel Filament Gets Painful at Scale ](#why-multi-panel-filament-gets-painful-at-scale)
2. [  Registering Multiple Panels Without Coupling Them ](#registering-multiple-panels-without-coupling-them)
3. [  Per-Panel Middleware for Tenant Scoping ](#per-panel-middleware-for-tenant-scoping)
4. [  Table Query Tuning: Where Filament Tables Actually Slow Down ](#table-query-tuning-where-filament-tables-actually-slow-down)
5. [  Always Eager-Load in getTableQuery ](#always-eager-load-in-codegettablequerycode)
6. [  Deferring Expensive Counts ](#deferring-expensive-counts)
7. [  Scoping the Base Query for Authorization ](#scoping-the-base-query-for-authorization)
8. [  Index Your Filter Columns ](#index-your-filter-columns)
9. [  Takeaways ](#takeaways)

  ![Filament at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning](https://cdn.msaied.com/311/73c2aa4cf4d7c33e5903eaa8ede1309d.png)

  #filament   #laravel   #multi-panel   #performance  

 Filament at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning 
============================================================================

     28 Jun 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

  9 sections  

1. [  01   Why Multi-Panel Filament Gets Painful at Scale  ](#why-multi-panel-filament-gets-painful-at-scale)
2. [  02   Registering Multiple Panels Without Coupling Them  ](#registering-multiple-panels-without-coupling-them)
3. [  03   Per-Panel Middleware for Tenant Scoping  ](#per-panel-middleware-for-tenant-scoping)
4. [  04   Table Query Tuning: Where Filament Tables Actually Slow Down  ](#table-query-tuning-where-filament-tables-actually-slow-down)
5. [  05   Always Eager-Load in getTableQuery  ](#always-eager-load-in-codegettablequerycode)
6. [  06   Deferring Expensive Counts  ](#deferring-expensive-counts)
7. [  07   Scoping the Base Query for Authorization  ](#scoping-the-base-query-for-authorization)
8. [  08   Index Your Filter Columns  ](#index-your-filter-columns)
9. [  09   Takeaways  ](#takeaways)

       Why Multi-Panel Filament Gets Painful at Scale
----------------------------------------------

Filament's panel system is elegant for a single admin area. The moment you add a customer portal, a vendor dashboard, and an internal ops panel — each with its own auth guard, middleware, and data scope — the default conventions start to fight you. Add tables with 500k+ rows and you have a performance problem on top of an architecture problem.

This article addresses both.

---

Registering Multiple Panels Without Coupling Them
-------------------------------------------------

Each panel lives in its own `PanelProvider`. Keep them in `app/Panels/` and register them individually in `bootstrap/providers.php`.

```php
// app/Panels/VendorPanelProvider.php
use Filament\Panel;
use Filament\PanelProvider;

class VendorPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->id('vendor')
            ->path('vendor')
            ->authGuard('vendor')
            ->login()
            ->middleware([
                EncryptCookies::class,
                StartSession::class,
                VendorTenantMiddleware::class, // your custom scope
            ])
            ->authMiddleware([Authenticate::class])
            ->discoverResources(
                in: app_path('Filament/Vendor/Resources'),
                for: 'App\\Filament\\Vendor\\Resources'
            );
    }
}

```

The `authGuard('vendor')` call wires Filament's internal auth checks to your custom guard defined in `config/auth.php`. No shared session bleed between panels.

### Per-Panel Middleware for Tenant Scoping

Don't rely on global middleware for tenant resolution when panels have different scoping rules. A dedicated middleware per panel keeps the logic explicit:

```php
class VendorTenantMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        $vendor = auth('vendor')->user()?->vendor;

        if (! $vendor) {
            abort(403);
        }

        app()->instance(CurrentVendor::class, $vendor);

        return $next($request);
    }
}

```

Bind `CurrentVendor` as a scoped singleton so every Eloquent query in that request can resolve it without a second DB hit.

---

Table Query Tuning: Where Filament Tables Actually Slow Down
------------------------------------------------------------

Filament's `Table` component calls `->paginate()` on your base query. The base query is built in `getTableQuery()` on the resource. This is where most N+1 and missing-index problems live.

### Always Eager-Load in `getTableQuery`

```php
public static function getTableQuery(): Builder
{
    return parent::getTableQuery()
        ->with(['vendor', 'status', 'latestShipment'])
        ->withCount('lineItems');
}

```

Filament will not automatically eager-load relationships referenced in columns. If your `TextColumn` calls `->relationship('vendor', 'name')`, Filament does add a join internally — but for anything more complex, explicit `with()` is safer and more predictable.

### Deferring Expensive Counts

Avoid `->withCount()` on large tables when the count isn't displayed by default. Use a `TextColumn` with `->default('-')` and `->toggleable(isToggledHiddenByDefault: true)` so the count only loads when the user opts in:

```php
TextColumn::make('line_items_count')
    ->counts('lineItems')
    ->label('Lines')
    ->toggleable(isToggledHiddenByDefault: true),

```

### Scoping the Base Query for Authorization

For row-level security, apply the scope directly in `getTableQuery()` rather than a global scope. Global scopes affect every query in the process — dangerous under Octane.

```php
public static function getTableQuery(): Builder
{
    $vendor = app(CurrentVendor::class);

    return parent::getTableQuery()
        ->whereBelongsTo($vendor)
        ->with(['status']);
}

```

### Index Your Filter Columns

Filament table filters translate to `WHERE` clauses. If your `SelectFilter` targets `status` or `created_at`, those columns need indexes. Use `EXPLAIN ANALYZE` in PostgreSQL or `EXPLAIN` in MySQL to confirm the planner is using them.

```sql
CREATE INDEX idx_orders_vendor_status
    ON orders (vendor_id, status);

```

A composite index on `(vendor_id, status)` covers the common case of scoped + filtered queries in one scan.

---

Takeaways
---------

- Register each panel in its own `PanelProvider` with a dedicated `authGuard` and middleware stack — never share session state across panels.
- Inject tenant context via a scoped singleton bound in per-panel middleware, not a global scope.
- Always call `->with()` explicitly in `getTableQuery()`; don't rely on Filament's relationship column resolution for complex graphs.
- Hide expensive aggregate columns behind `->toggleable(isToggledHiddenByDefault: true)` to avoid counting millions of rows on every page load.
- Add composite indexes that match your most common `(tenant_id, filter_column)` query patterns.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Ffilament-at-scale-multi-panel-auth-custom-panels-and-table-query-tuning-1&text=Filament+at+Scale%3A+Multi-Panel+Auth%2C+Custom+Panels%2C+and+Table+Query+Tuning) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Ffilament-at-scale-multi-panel-auth-custom-panels-and-table-query-tuning-1) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Can two Filament panels share the same auth guard?        Technically yes, but it creates session and authorization ambiguity. Each panel should use a distinct guard so Filament's internal auth checks, redirects, and middleware operate independently without interfering with each other. 

      Q02  Does calling -&gt;with() in getTableQuery() conflict with Filament's built-in relationship column loading?        No. Filament's relationship columns add their own eager loads on top of your base query. Explicit -&gt;with() calls in getTableQuery() are additive and give you full control over which relationships are loaded and how. 

      Q03  How do I prevent a global Eloquent scope from leaking across panels under Octane?        Avoid global scopes for per-request tenant filtering entirely. Instead, apply the scope directly in getTableQuery() using the scoped singleton bound in your panel's middleware. This keeps the scope request-local and safe under Octane's persistent worker model. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://www.msaied.com/articles) 

 [ ![Filament v5 Preview: Schema Unification, Performance Shifts, and How to Prepare](https://cdn.msaied.com/340/1a05ca68637b898b676efb66f22e627f.png) filament laravel php 

### Filament v5 Preview: Schema Unification, Performance Shifts, and How to Prepare

Filament v5 is reshaping how panels, forms, and tables are composed. This deep-dive covers the confirmed archi...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 1 Jul 2026     4 min read  

  Read    

 ](https://www.msaied.com/articles/filament-v5-preview-schema-unification-performance-shifts-and-how-to-prepare) [ ![Laravel 13: New Features, Helpers, and Practical Upgrade Notes](https://cdn.msaied.com/339/58c4fa6fe9b6d25a2dac17c621b6f4c6.png) laravel laravel-13 upgrade 

### Laravel 13: New Features, Helpers, and Practical Upgrade Notes

Laravel 13 ships with async-first defaults, a leaner bootstrapping layer, and several quality-of-life helpers....

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 1 Jul 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/laravel-13-new-features-helpers-and-practical-upgrade-notes) [ ![Laravel 12: Structured Route Files, Slim Skeletons, and the New Application Bootstrapping](https://cdn.msaied.com/337/05b39d16d0f88a5fb94d0cf74049b88b.png) laravel laravel-12 upgrade 

### Laravel 12: Structured Route Files, Slim Skeletons, and the New Application Bootstrapping

Laravel 12 ships with a leaner skeleton, first-class route file organisation, and a revised application bootst...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 1 Jul 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/laravel-12-structured-route-files-slim-skeletons-and-the-new-application-bootstrapping) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://www.msaied.com)
- [Projects](https://www.msaied.com/projects)
- [Articles](https://www.msaied.com/articles)
- [Certificates](https://www.msaied.com/certificates)
- [Contact](https://www.msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
