Profiling Laravel with Blackfire &amp; Xdebug | 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)    Blackfire &amp; Xdebug Profiling in Laravel: Finding Real Bottlenecks        On this page       1. [  Why Guessing Is Expensive ](#why-guessing-is-expensive)
2. [  Xdebug: Local Call-Graph Profiling ](#xdebug-local-call-graph-profiling)
3. [  What to Look For ](#what-to-look-for)
4. [  Blackfire: Profiling With Intent ](#blackfire-profiling-with-intent)
5. [  Writing Performance Assertions ](#writing-performance-assertions)
6. [  Profiling Queued Jobs ](#profiling-queued-jobs)
7. [  Practical Workflow ](#practical-workflow)
8. [  Takeaways ](#takeaways)

  ![Blackfire & Xdebug Profiling in Laravel: Finding Real Bottlenecks](https://cdn.msaied.com/205/019d80d4be977814ed6353286ef25688.png)

  #laravel   #performance   #profiling   #blackfire   #xdebug  

 Blackfire &amp; Xdebug Profiling in Laravel: Finding Real Bottlenecks 
=======================================================================

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

       Table of contents

1. [  01   Why Guessing Is Expensive  ](#why-guessing-is-expensive)
2. [  02   Xdebug: Local Call-Graph Profiling  ](#xdebug-local-call-graph-profiling)
3. [  03   What to Look For  ](#what-to-look-for)
4. [  04   Blackfire: Profiling With Intent  ](#blackfire-profiling-with-intent)
5. [  05   Writing Performance Assertions  ](#writing-performance-assertions)
6. [  06   Profiling Queued Jobs  ](#profiling-queued-jobs)
7. [  07   Practical Workflow  ](#practical-workflow)
8. [  08   Takeaways  ](#takeaways)

 Why Guessing Is Expensive
-------------------------

Most performance work in Laravel starts with a hunch: "It's probably the database" or "Maybe we need Redis here." Hunches are expensive. A profiler gives you a call graph with wall-clock time and memory allocations per function call. You stop optimising the wrong thing.

This article covers two tools with distinct roles:

- **Xdebug** — free, local, great for deep call-stack traces and code-coverage-adjacent profiling.
- **Blackfire** — commercial (free tier available), designed for continuous profiling, CI assertions, and production-safe sampling.

---

Xdebug: Local Call-Graph Profiling
----------------------------------

Enable profiling output in `php.ini` (or a `.ini` drop-in for Sail/Herd):

```ini
[xdebug]
xdebug.mode = profile
xdebug.output_dir = /tmp/xdebug
xdebug.profiler_output_name = cachegrind.out.%p.%r

```

Trigger a single request profile without profiling every request:

```ini
xdebug.start_with_request = trigger

```

Then hit the route with the trigger query string:

```bash
curl "http://localhost/api/reports/monthly?XDEBUG_PROFILE=1"

```

Open the resulting `cachegrind.out.*` file in **QCacheGrind** (macOS: `brew install qcachegrind`). Sort by *Self Cost* to find functions that consume time independent of their callees — this is where actual work happens, not just delegation.

### What to Look For

- `PDOStatement::execute` called hundreds of times → N+1 query.
- `Illuminate\View\Compilers\BladeCompiler::compileString` in production → missing compiled view cache (`php artisan view:cache`).
- `serialize` / `unserialize` in a hot path → over-eager session or cache serialisation.

---

Blackfire: Profiling With Intent
--------------------------------

Blackfire's agent runs as a sidecar. Install the CLI and browser extension, then profile from the terminal:

```bash
blackfire curl http://localhost/api/reports/monthly

```

The output is a URL to an interactive call graph. More useful for CI is the **assertion** system.

### Writing Performance Assertions

Create `.blackfire.yaml` at the project root:

```yaml
tests:
  "Monthly report endpoint is fast enough":
    path: /api/reports/monthly
    assertions:
      - "main.wall_time < 300ms"
      - "metrics.sql.queries.count < 10"

```

Run in CI:

```bash
blackfire validate --reference=1 --scenario=monthly_report

```

This turns performance into a first-class contract. A PR that introduces an N+1 fails the build before it ships.

### Profiling Queued Jobs

Blackfire can profile CLI processes, which means you can profile a job in isolation:

```bash
blackfire run php artisan queue:work --once

```

Pair this with a seeded database and a known job payload so the profile is reproducible. Look for unexpected filesystem calls (`file_get_contents` on config files that should be cached) or repeated model hydration.

---

Practical Workflow
------------------

```php
// Temporarily wrap a suspect code path with DB query logging
DB::enableQueryLog();

$report = app(MonthlyReportBuilder::class)->build($tenant);

dd(DB::getQueryLog()); // count, bindings, time per query

```

This is a quick sanity check before reaching for a profiler. If you see 80 queries for a report that should need 3, you already know where to look. The profiler then tells you *which call site* is responsible.

---

Takeaways
---------

- Use **Xdebug** locally for deep call-graph exploration; sort by *Self Cost*, not *Inclusive Cost*.
- Use **Blackfire** for repeatable, assertion-driven profiling in CI and staging.
- Profile queued jobs the same way you profile HTTP requests — they have the same bottleneck patterns.
- `DB::enableQueryLog()` is a fast first filter before opening a full profiler.
- Never optimise without a baseline measurement; profilers give you before/after proof.
- Blade view compilation, config loading, and session serialisation are common non-obvious hotspots.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Fblackfire-xdebug-profiling-in-laravel-finding-real-bottlenecks&text=Blackfire+%26+Xdebug+Profiling+in+Laravel%3A+Finding+Real+Bottlenecks) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Fblackfire-xdebug-profiling-in-laravel-finding-real-bottlenecks) 

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

  3 questions  

     Q01  Can I use Blackfire in production without impacting all users?        Yes. Blackfire uses a request-triggered sampling model. Only requests carrying the Blackfire header (injected by the browser extension or CLI) are profiled. Normal traffic is unaffected, making it safe for production use. 

      Q02  Xdebug slows my app significantly — is that a problem for profiling?        Xdebug adds overhead, so absolute wall-clock numbers are inflated. However, the *relative* cost between functions remains proportional, so the call graph still correctly identifies which code paths are expensive. Use Blackfire when you need accurate wall-clock assertions. 

      Q03  How do I profile a specific Artisan command with Blackfire?        Run `blackfire run php artisan your:command` from the terminal. Blackfire wraps the process, collects the profile, and uploads it to your dashboard exactly as it does for HTTP requests. 

  Continue reading

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

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

 [ ![Laravel Telescope Alternatives: Building a Lightweight Request Inspector with Middleware](https://cdn.msaied.com/216/9b6d240010b80483f072902dafcd216c.png) laravel middleware debugging 

### Laravel Telescope Alternatives: Building a Lightweight Request Inspector with Middleware

Telescope is powerful but heavy for production. Learn how to build a focused, low-overhead request inspector u...

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

 16 Jun 2026     1 min read  

  Read    

 ](https://www.msaied.com/articles/laravel-telescope-alternatives-building-a-lightweight-request-inspector-with-middleware) [ ![RAG Pipelines in Laravel: Chunking, Embedding, and Retrieval with pgvector](https://cdn.msaied.com/215/e037e13535aa77822f879ee829ec3f68.png) laravel ai pgvector 

### RAG Pipelines in Laravel: Chunking, Embedding, and Retrieval with pgvector

Build a production-ready Retrieval-Augmented Generation pipeline in Laravel using pgvector, OpenAI embeddings,...

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

 16 Jun 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/rag-pipelines-in-laravel-chunking-embedding-and-retrieval-with-pgvector) [ ![Laravel Pest: Architecture Tests, Mutation Testing, and Type Coverage in CI](https://cdn.msaied.com/214/0d4822fa8ee1765d0689e387dd849d92.png) laravel pest testing 

### Laravel Pest: Architecture Tests, Mutation Testing, and Type Coverage in CI

Go beyond feature tests. Learn how to enforce architectural rules, catch logic gaps with mutation testing, and...

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

 16 Jun 2026     4 min read  

  Read    

 ](https://www.msaied.com/articles/laravel-pest-architecture-tests-mutation-testing-and-type-coverage-in-ci) 

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