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

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

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

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Filament v4 at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning        On this page       1. [  The Problem With One Panel Fits All ](#the-problem-with-one-panel-fits-all)
2. [  Registering Multiple Panels ](#registering-multiple-panels)
3. [  Per-Panel Authentication Guards ](#per-panel-authentication-guards)
4. [  Middleware Isolation ](#middleware-isolation)
5. [  Table Query Tuning ](#table-query-tuning)
6. [  Scoped Default Query ](#scoped-default-query)
7. [  Deferring Expensive Counts ](#deferring-expensive-counts)
8. [  Column-Level Eager Loading ](#column-level-eager-loading)
9. [  Takeaways ](#takeaways)

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

  #filament   #laravel   #multi-panel   #performance  

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

     13 Sep 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said  

       Table of contents

  9 sections  

1. [  01   The Problem With One Panel Fits All  ](#the-problem-with-one-panel-fits-all)
2. [  02   Registering Multiple Panels  ](#registering-multiple-panels)
3. [  03   Per-Panel Authentication Guards  ](#per-panel-authentication-guards)
4. [  04   Middleware Isolation  ](#middleware-isolation)
5. [  05   Table Query Tuning  ](#table-query-tuning)
6. [  06   Scoped Default Query  ](#scoped-default-query)
7. [  07   Deferring Expensive Counts  ](#deferring-expensive-counts)
8. [  08   Column-Level Eager Loading  ](#column-level-eager-loading)
9. [  09   Takeaways  ](#takeaways)

       The Problem With One Panel Fits All
-----------------------------------

Most Filament tutorials assume a single `/admin` panel. Real SaaS products need at least two: one for customers, one for internal staff — each with its own auth guard, middleware stack, and resource set. Filament v4's `PanelProvider` architecture makes this clean, but there are sharp edges around query performance once you push table row counts past a few thousand.

This article covers three concrete areas:

1. Registering and isolating multiple panels
2. Wiring per-panel authentication guards
3. Tuning table queries so Filament doesn't become your slowest endpoint

---

Registering Multiple Panels
---------------------------

Each panel gets its own `PanelProvider`. Create two:

```bash
php artisan make:filament-panel customer
php artisan make:filament-panel staff

```

This generates `app/Providers/Filament/CustomerPanelProvider.php` and `StaffPanelProvider.php`. Register both in `bootstrap/providers.php`:

```php
return [
    App\Providers\Filament\CustomerPanelProvider::class,
    App\Providers\Filament\StaffPanelProvider::class,
];

```

Each provider calls `Panel::make()` with a unique ID and path:

```php
public function panel(Panel $panel): Panel
{
    return $panel
        ->id('customer')
        ->path('portal')
        ->login()
        ->resources([
            App\Filament\Customer\Resources\OrderResource::class,
        ]);
}

```

---

Per-Panel Authentication Guards
-------------------------------

Filament v4 exposes `->authGuard()` on the panel builder. Pair it with a dedicated guard in `config/auth.php`:

```php
// config/auth.php
'guards' => [
    'customer' => [
        'driver'   => 'session',
        'provider' => 'customers',
    ],
    'staff' => [
        'driver'   => 'session',
        'provider' => 'staff',
    ],
],
'providers' => [
    'customers' => ['driver' => 'eloquent', 'model' => App\Models\Customer::class],
    'staff'     => ['driver' => 'eloquent', 'model' => App\Models\StaffUser::class],
],

```

Then in each panel provider:

```php
return $panel
    ->id('customer')
    ->path('portal')
    ->authGuard('customer')
    ->login(CustomerLoginPage::class);

```

Filament will resolve `Auth::guard('customer')` for all authorization checks inside that panel. Sessions are fully isolated — a customer cookie never authenticates a staff request.

### Middleware Isolation

Add panel-specific middleware to avoid leaking staff-only rate limits or audit logging into the customer panel:

```php
->middleware([
    EncryptCookies::class,
    StartSession::class,
    App\Http\Middleware\LogCustomerActivity::class,
])
->authMiddleware([
    Authenticate::class,
])

```

---

Table Query Tuning
------------------

Filament's `Table` component calls `->query()` on every page load. The default is `Model::query()` — no eager loads, no scopes. At scale that's a disaster.

### Scoped Default Query

Always scope to the authenticated tenant and eager-load relations the table columns touch:

```php
public static function getEloquentQuery(): Builder
{
    return parent::getEloquentQuery()
        ->with(['customer', 'items.product'])
        ->where('tenant_id', Filament::getTenant()?->id)
        ->withoutGlobalScope(SoftDeletingScope::class);
}

```

### Deferring Expensive Counts

Filament renders a row count badge by default. On large tables this fires a `COUNT(*)` on every render. Disable it when the table is filtered by default and the count is meaningless:

```php
Table::make()
    ->paginated([25, 50, 100])
    ->paginationPageOptions([25, 50])
    ->defaultPaginationPageOption(25)
    ->extremePaginationLinks(false)
    ->queryStringIdentifier('orders')

```

For the count itself, override `getTableRecordsPerPageSelectOptions` or use a database view with a materialized count column rather than a live aggregate.

### Column-Level Eager Loading

Filament v4 columns support `->relationship()` declarations. Use them so the table builder can batch-load only what's rendered:

```php
TextColumn::make('customer.name')
    ->label('Customer')
    ->searchable(query: fn (Builder $q, string $s) =>
        $q->whereHas('customer', fn ($q) => $q->where('name', 'like', "%{$s}%"))
    ),

```

Avoid `->getStateUsing()` callbacks that hit the database per row — they bypass Eloquent's eager loading entirely.

---

Takeaways
---------

- Register each panel in its own `PanelProvider`; use `->authGuard()` to fully isolate sessions.
- Scope `getEloquentQuery()` to the tenant and eager-load every relation the table touches.
- Disable or defer row counts on large tables; a live `COUNT(*)` on 500k rows is expensive.
- Keep panel-specific middleware in the panel provider, not in global `app/Http/Kernel.php`.
- Use `->relationship()` on columns so Filament can batch-load relations rather than resolving them per row.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ffilament-v4-at-scale-multi-panel-auth-custom-panels-and-table-query-tuning&text=Filament+v4+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%2Fmsaied.com%2Farticles%2Ffilament-v4-at-scale-multi-panel-auth-custom-panels-and-table-query-tuning) 

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

  2 questions  

     Q01  Can two Filament v4 panels share the same Eloquent model but use different guards?        Yes. Guards are independent of models. You can point two guards at the same `User` model with different session drivers or providers, then assign each guard to a separate panel via `-&gt;authGuard()`. Sessions remain isolated because Filament resolves auth through the panel's configured guard, not the default `web` guard. 

      Q02  How do I prevent N+1 queries in Filament table columns that use -&gt;relationship()?        Override `getEloquentQuery()` in your resource and call `-&gt;with([...])` for every relation your columns reference. Filament does not auto-detect required eager loads from column definitions, so explicit `with()` calls in the base query are the most reliable approach. 

  Continue reading

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

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

 [ ![Macros, Mixins, and Custom Collection Methods in Laravel](https://cdn.msaied.com/663/b8e39b17d427358aa43b5c3e8c1be908.png) laravel collections macros 

### Macros, Mixins, and Custom Collection Methods in Laravel

Learn how to extend Laravel's core classes with macros, mixins, and custom Collection methods — keeping your c...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 13 Sep 2026     4 min read  

  Read    

 ](https://msaied.com/articles/macros-mixins-and-custom-collection-methods-in-laravel-2) [ ![Modular Monolith in Laravel: Enforcing Bounded Contexts with Module Service Providers](https://cdn.msaied.com/662/7f9c800590e5d7c07197293837cf0114.png) laravel architecture modular-monolith 

### Modular Monolith in Laravel: Enforcing Bounded Contexts with Module Service Providers

Learn how to carve a Laravel application into cohesive bounded contexts using per-module service providers, ex...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 12 Sep 2026     3 min read  

  Read    

 ](https://msaied.com/articles/modular-monolith-in-laravel-enforcing-bounded-contexts-with-module-service-providers) [ ![Filament v4 Table Bulk Actions: Custom Confirmation Modals and Scoped Authorization](https://cdn.msaied.com/661/5f319b485f1bc0c76e2c82746f730c8c.png) filament laravel authorization 

### Filament v4 Table Bulk Actions: Custom Confirmation Modals and Scoped Authorization

Go beyond the default delete bulk action. Learn how to build custom Filament v4 bulk actions with typed confir...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 12 Sep 2026     4 min read  

  Read    

 ](https://msaied.com/articles/filament-v4-table-bulk-actions-custom-confirmation-modals-and-scoped-authorization) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://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://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://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)
