Filament Multi-Panel Auth &amp; Table Query Tuning | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://msaied.com) - [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [About](https://msaied.com#about)

           [  Contact](https://msaied.com#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://msaied.com)
- [ProjectsCase studies](https://msaied.com/projects)
- [ArticlesEngineering notes](https://msaied.com/articles)
- [CertificatesCredentials](https://msaied.com/certificates)
- [AboutHow I work](https://msaied.com#about)
- [ContactGet in touch](https://msaied.com#contact)

  [Start a conversation](https://msaied.com#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://msaied.com)
2. /
3. [Articles](https://msaied.com/articles)
4. /
5. Filament at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning

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

 Running Filament across multiple panels with separate auth guards and scoped table queries requires deliberate architecture. This guide covers custom panel providers, per-panel middleware, and query tuning strategies that keep large datasets fast.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://msaied.com#person) Published 5 Jul 2026 · Updated 5 Jul 2026 · 3 min read

ShareCopy linkCopied

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

  On this page +1. [Filament at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning](#filament-at-scale-multi-panel-auth-custom-panels-and-table-query-tuning)
2. [Registering Multiple Panels](#registering-multiple-panels)
3. [Per-Panel Middleware Stacks](#per-panel-middleware-stacks)
4. [Scoping Table Queries Without Global Scopes](#scoping-table-queries-without-global-scopes)
5. [Table Query Tuning: The Real Bottlenecks](#table-query-tuning-the-real-bottlenecks)
6. [Eager Loading in Table Columns](#eager-loading-in-table-columns)
7. [Covering Indexes for Filter Columns](#covering-indexes-for-filter-columns)
8. [Key Takeaways](#key-takeaways)

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

Most Filament tutorials assume a single admin panel with a single `users` table. Production SaaS apps rarely look like that. You might have a customer-facing portal, an internal ops panel, and a super-admin panel — each with its own guard, middleware, and data scope. Getting that wrong means auth bleed, slow tables, and unmaintainable panel code.

### Registering Multiple Panels

Each panel lives in its own `PanelProvider`. Register them all in `bootstrap/providers.php`:

```php
// app/Providers/Filament/CustomerPanelProvider.php
class CustomerPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->id('customer')
            ->path('portal')
            ->authGuard('customer')
            ->login(CustomerLogin::class)
            ->middleware([
                EncryptCookies::class,
                StartSession::class,
                EnsureEmailIsVerified::class,
            ])
            ->authMiddleware([Authenticate::class])
            ->discoverResources(
                in: app_path('Filament/Customer/Resources'),
                for: 'App\\Filament\\Customer\\Resources'
            );
    }
}

```

The `->authGuard('customer')` call is the critical line. Filament will use that guard for all authentication checks within this panel, completely isolated from your `admin` guard.

### Per-Panel Middleware Stacks

Don't share middleware stacks between panels unless you have a deliberate reason. The `->middleware()` call sets the web-layer stack; `->authMiddleware()` runs after authentication resolves. A common pattern is adding a tenant-scoping middleware only to the customer panel:

```php
->authMiddleware([
    Authenticate::class,
    ApplyTenantScope::class, // sets app()->instance('current_tenant', ...)
])

```

This keeps the ops panel free of tenant logic entirely.

### Scoping Table Queries Without Global Scopes

Global Eloquent scopes are tempting but dangerous across panels — they apply everywhere, including jobs and CLI commands. Instead, scope at the resource level:

```php
// app/Filament/Customer/Resources/OrderResource.php
public static function getEloquentQuery(): Builder
{
    return parent::getEloquentQuery()
        ->whereBelongsTo(app('current_tenant'), 'tenant')
        ->with(['items', 'status']);
}

```

This query runs only when the Filament table renders. No leakage.

### Table Query Tuning: The Real Bottlenecks

Filament tables generate a `COUNT(*)` query for pagination alongside the data query. On large tables this is expensive. Use `->paginationPageOptions([25, 50])` and consider disabling the count entirely for very large datasets:

```php
public static function table(Table $table): Table
{
    return $table
        ->query(fn () => static::getEloquentQuery())
        ->paginationPageOptions([25, 50])
        ->defaultPaginationPageOption(25)
        ->extremePaginationLinks(false)
        ->columns([...]);
}

```

For tables exceeding 500k rows, switch to simple pagination to drop the `COUNT`:

```php
->paginated([25, 50])
->paginateUsing(fn (Builder $query, int $page, int $perPage) =>
    $query->simplePaginate($perPage, page: $page)
)

```

### Eager Loading in Table Columns

Filament does not automatically eager-load relationships referenced in columns. Declare them explicitly:

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

```

And in `getEloquentQuery()`:

```php
return parent::getEloquentQuery()->with(['customer', 'items.product']);

```

Missing this on a 10k-row table produces thousands of queries per page load.

### Covering Indexes for Filter Columns

Filament filter dropdowns translate to `WHERE` clauses. If your `orders` table is filtered by `status` and sorted by `created_at`, add a composite index:

```php
$table->index(['tenant_id', 'status', 'created_at']);

```

The column order matters: equality columns first, range/sort columns last.

### Key Takeaways

- Register each panel in its own `PanelProvider` with a dedicated `authGuard`.
- Scope table queries in `getEloquentQuery()`, not via global Eloquent scopes.
- Disable `COUNT(*)` pagination on very large tables using `simplePaginate`.
- Declare eager loads explicitly — Filament will not infer them from column definitions.
- Add composite indexes that match your filter + sort column order.

- [filament](https://msaied.com/articles?search=filament)
- [laravel](https://msaied.com/articles?search=laravel)
- [multi-panel](https://msaied.com/articles?search=multi-panel)
- [performance](https://msaied.com/articles?search=performance)

 Frequently asked questions 
---------------------------

  Can two Filament panels share the same Eloquent models but use different guards?Yes. Guards control authentication, not model access. Both panels can query the same models; the difference is which user table and token driver authenticates the request. Scope queries per-panel inside `getEloquentQuery()` rather than relying on the guard to restrict data.

   How do I prevent a Filament resource registered in one panel from appearing in another?Use `-&gt;discoverResources(in: ..., for: ...)` with panel-specific namespaces, or register resources explicitly with `-&gt;resources(\[...\])`. Resources are scoped to the panel they are registered in and will not bleed across panels.

   Does switching to simplePaginate break Filament's built-in pagination UI?Simple pagination removes the total-count-based page links, so users see only previous/next controls. Filament renders this correctly when you return a `Paginator` instance from `paginateUsing`. It is a deliberate UX trade-off worth making on very large datasets.

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

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

[About](https://msaied.com#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleOctane Worker Lifecycle, State Leakage, and Safe Singleton Patterns in Laravel](https://msaied.com/articles/octane-worker-lifecycle-state-leakage-and-safe-singleton-patterns-in-laravel) [Next articleMacros, Mixins, and Custom Collection Methods in Laravel](https://msaied.com/articles/macros-mixins-and-custom-collection-methods-in-laravel-1)  

   On this page
-------------

1. [Filament at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning](#filament-at-scale-multi-panel-auth-custom-panels-and-table-query-tuning)
2. [Registering Multiple Panels](#registering-multiple-panels)
3. [Per-Panel Middleware Stacks](#per-panel-middleware-stacks)
4. [Scoping Table Queries Without Global Scopes](#scoping-table-queries-without-global-scopes)
5. [Table Query Tuning: The Real Bottlenecks](#table-query-tuning-the-real-bottlenecks)
6. [Eager Loading in Table Columns](#eager-loading-in-table-columns)
7. [Covering Indexes for Filter Columns](#covering-indexes-for-filter-columns)
8. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://msaied.com#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://msaied.com/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://msaied.com/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) [ ![](https://cdn.msaied.com/737/f5c7e78a645325d4cff8d43f2835f136.png)  · 4 min read### Laravel Telescope Alternatives: Structured Observability with Pulse, Debugbar, and Custom Watchers

4 Oct 2026 ](https://msaied.com/articles/laravel-telescope-alternatives-structured-observability-with-pulse-debugbar-and-custom-watchers) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://msaied.com#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://msaied.com)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://msaied.com/sitemap.xml)
