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://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

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

Menu
----

Close 

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

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

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/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 distinct auth guards and thousands of table rows? This guide covers custom panel providers, per-panel middleware, and Eloquent query tuning to keep every panel fast.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 28 Jun 2026 · Updated 28 Jun 2026 · 4 min read

ShareCopy linkCopied

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

  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)

 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.

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

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

  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.

   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.

   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.

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

[Mohamed Said](https://www.msaied.com/public#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://www.msaied.com/public#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 articlePartial Indexes, Covering Indexes, and Query Plan Analysis in Laravel](https://www.msaied.com/public/articles/partial-indexes-covering-indexes-and-query-plan-analysis-in-laravel) [Next articleExtending Laravel Collections: Macros, Mixins, and Higher-Order Proxies](https://www.msaied.com/public/articles/extending-laravel-collections-macros-mixins-and-higher-order-proxies)  

   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)

 ###  Have a technical challenge?

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

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

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

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](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://www.msaied.com/public/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://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

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

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

 [Discuss your project ↗](https://www.msaied.com/public#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://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/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://www.msaied.com/public/sitemap.xml)
