Filament 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 at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning        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. [  Isolating Auth Guards ](#isolating-auth-guards)
4. [  Custom Panel Middleware for Tenant Resolution ](#custom-panel-middleware-for-tenant-resolution)
5. [  Table Query Tuning at Scale ](#table-query-tuning-at-scale)
6. [  Disable the Count Query When Unnecessary ](#disable-the-count-query-when-unnecessary)
7. [  Eager-Load Relationship Columns ](#eager-load-relationship-columns)
8. [  Key Takeaways ](#key-takeaways)

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

  #filament   #laravel   #performance   #multi-tenant  

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

     22 Jul 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   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. [  02   Registering Multiple Panels  ](#registering-multiple-panels)
3. [  03   Isolating Auth Guards  ](#isolating-auth-guards)
4. [  04   Custom Panel Middleware for Tenant Resolution  ](#custom-panel-middleware-for-tenant-resolution)
5. [  05   Table Query Tuning at Scale  ](#table-query-tuning-at-scale)
6. [  06   Disable the Count Query When Unnecessary  ](#disable-the-count-query-when-unnecessary)
7. [  07   Eager-Load Relationship Columns  ](#eager-load-relationship-columns)
8. [  08   Key Takeaways  ](#key-takeaways)

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

Filament v3/v4 ships with a clean panel-per-provider model, but most tutorials stop at a single `AdminPanelProvider`. Production SaaS apps routinely need an **admin panel**, a **tenant panel**, and a **public-facing portal** — each with its own auth guard, middleware stack, and URL prefix. Add a table that pages through 500 k rows and you have a real engineering problem.

This article covers both concerns with concrete, copy-paste-ready patterns.

---

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

Each panel lives in its own service provider. Register them all in `bootstrap/providers.php`.

```php
// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
    return $panel
        ->id('admin')
        ->path('admin')
        ->authGuard('admin')          // dedicated guard
        ->login(AdminLogin::class)
        ->middleware([
            EncryptCookies::class,
            VerifyCsrfToken::class,
            RequireAdminRole::class,  // custom middleware
        ])
        ->resources([
            UserResource::class,
            TenantResource::class,
        ]);
}

```

```php
// app/Providers/Filament/TenantPanelProvider.php
public function panel(Panel $panel): Panel
{
    return $panel
        ->id('tenant')
        ->path('app')
        ->authGuard('web')            // standard guard, tenant resolved by middleware
        ->tenant(Team::class, slugAttribute: 'slug')
        ->tenantMiddleware([EnsureTeamIsActive::class], isPersistent: true)
        ->resources([DashboardResource::class]);
}

```

### Isolating Auth Guards

Define a dedicated `admin` guard in `config/auth.php`:

```php
'guards' => [
    'admin' => [
        'driver'   => 'session',
        'provider' => 'admins',
    ],
],
'providers' => [
    'admins' => [
        'driver' => 'eloquent',
        'model'  => App\Models\Admin::class,
    ],
],

```

This means an authenticated `User` session cannot bleed into the admin panel — a common security gap when teams share a single guard.

---

Custom Panel Middleware for Tenant Resolution
---------------------------------------------

When the tenant panel resolves a team from the URL slug, you want that team bound into the container early so every resource query can scope itself automatically.

```php
class ResolveCurrentTeam
{
    public function handle(Request $request, Closure $next): mixed
    {
        $team = Team::where('slug', $request->route('tenant'))->firstOrFail();

        app()->instance(CurrentTeam::class, $team);
        app()->instance('current_team_id', $team->id);

        return $next($request);
    }
}

```

Resources then inject `CurrentTeam` via the container rather than re-querying:

```php
public static function getEloquentQuery(): Builder
{
    return parent::getEloquentQuery()
        ->where('team_id', app('current_team_id'));
}

```

---

Table Query Tuning at Scale
---------------------------

Filament tables issue a `COUNT(*)` for pagination and a `SELECT` for the page. On large tables both queries hit the same indexes — or miss them.

### Disable the Count Query When Unnecessary

```php
public function table(Table $table): Table
{
    return $table
        ->paginated([25, 50, 100])
        ->paginationPageOptions([25, 50])
        ->extremePaginationLinks(false)
        ->query(
            Invoice::query()
                ->select(['id','number','status','total','created_at'])
                ->with('customer:id,name')   // avoid N+1
        );
}

```

For very large tables, replace the default paginator with a **cursor paginator** — Filament supports it natively:

```php
->paginationMode(PaginationMode::Cursor)

```

Cursor pagination skips `COUNT(*)` entirely and uses a keyset on an indexed column.

### Eager-Load Relationship Columns

Every `TextColumn` that calls `->relationship()` under the hood issues a separate query per row unless you declare the relationship in `$with` or override `getEloquentQuery()`.

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

```

Always profile with `\DB::enableQueryLog()` or Telescope before deploying a new resource to production.

---

Key Takeaways
-------------

- Register each panel in its own provider; use `->authGuard()` to isolate session state per audience.
- Bind resolved tenant models into the container in persistent middleware so resources never re-query.
- Use `->select()` on the base query to avoid fetching unused columns across wide tables.
- Switch to cursor pagination for append-only or time-series tables to eliminate expensive `COUNT(*)` calls.
- Always declare eager-loads explicitly; Filament's relationship columns will not batch-load automatically unless you tell them to.

 Found this useful?

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

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

  3 questions  

     Q01  Can two Filament panels share the same Eloquent model but use different guards?        Yes. The guard controls which session store and provider are used for authentication, not which model is queried. You can point both guards at the same `User` model but use different providers or add role checks in panel middleware. 

      Q02  Does cursor pagination work with Filament's search and filter features?        Cursor pagination works with filters that do not change the sort order. Full-text search that re-orders results by relevance is incompatible with keyset cursors; fall back to offset pagination for those cases. 

      Q03  How do I prevent a logged-in admin from accessing the tenant panel URL directly?        Add a custom middleware to the tenant panel's `-&gt;middleware()` stack that checks `auth()-&gt;guard('web')-&gt;check()` and redirects admins away. Because each panel uses a separate guard, the admin session is invisible to the tenant panel by default, but an admin who also has a web session could still access it without the extra check. 

  Continue reading

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

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

 [ ![Building a Laravel Package: Service Providers, Auto-Discovery, and Config Merging](https://cdn.msaied.com/454/449f0f66a4aebbd744a318fc44906f1c.png) laravel packages service-providers 

### Building a Laravel Package: Service Providers, Auto-Discovery, and Config Merging

A practical walkthrough of building a production-ready Laravel package — covering service provider design, aut...

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

 22 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/building-a-laravel-package-service-providers-auto-discovery-and-config-merging-2) [ ![Modular Monolith in Laravel: Enforcing Bounded Contexts Without a Microservices Tax](https://cdn.msaied.com/451/014ea4597c12e3ba1ce7a4f4a33d299e.png) laravel architecture ddd 

### Modular Monolith in Laravel: Enforcing Bounded Contexts Without a Microservices Tax

Learn how to carve a Laravel application into cohesive bounded contexts using modules, internal contracts, and...

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

 21 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/modular-monolith-in-laravel-enforcing-bounded-contexts-without-a-microservices-tax-3) [ ![DDD Value Objects and DTOs in Laravel Without the Bloat](https://cdn.msaied.com/450/41688537085b86f102fd8c219a35319f.png) laravel ddd php 

### DDD Value Objects and DTOs in Laravel Without the Bloat

Learn how to implement domain-driven value objects and data transfer objects in Laravel using PHP 8.3 readonly...

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

 21 Jul 2026     1 min read  

  Read    

 ](https://msaied.com/articles/ddd-value-objects-and-dtos-in-laravel-without-the-bloat) 

   [  ![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)
