What is the Symfony firewall doing that takes so long?

My Symfony page isn't too slow (it loads in about 400 ms) but considering the fact that it's just a simple hello world page with basic authentication, it should be loading in less than 100 ms. When I enter the profiler, I see this:

Profiler timeline

Notice it just says "Firewall" for 250 ms. I thought the firewall was just responsible for keeping users out of certain areas of the page - I can't imagine that taking any longer than a few milliseconds plus the time it takes to fetch the user information from the database (which in this case is 61 ms).

Could somebody explain what the firewall actually does? If you have any general pointers on how to increase the firewall performance as well that would be greatly appreciated.


Note: I have Googled this of course, and I want to specify up front that I'm connecting to the MySQL database by IP address, not host name. This seemed to be the issue for every other case of slow Symfony firewall I could find.


Some resources from my project that could be relevant:

  • security.yaml
  • routing.yaml
  • Astrups/SpectacleBundle/Entity/User.php
  • Astrups/SpectacleBundle/Service/Sha1Salted.php

I did some googling and I see that this guy, seems to have the answer to your question.

After 15 minutes of research I ended up figuring out that this was due to the PHP PDO constructor (my Firewall is the first to connect to the database as I use Entities as users). With this knowledge the issue was pretty quickly found ([1], [2]): as it turns out using a DNS name (like 'localhost') instead of an IP (like '127.0.0.1') causes this issue.

A simple edit of the parameters.yml file (changing localhost to 127.0.0.1) did the trick of reducing the Firewall load time to only a minimum.


Alas, it turns out Rawdreeg was partly right. I made a 20 line PHP script to profile how long it takes to connect to my MySQL server:

<?php

$time = microtime(true);

$con = new PDO(...);

$connect_time = microtime(true);

$result = $con->query('SHOW TABLES');

$query_time = microtime(true);

var_dump($result->fetchAll(PDO::FETCH_ASSOC));

$time_con = ($connect_time - $time) * 1000;
$time_query = ($query_time - $connect_time) * 1000;

echo "Connection took $time_con ms\n";
echo "Query took $time_query ms\n";

The output was:

Connection took 230.18503189087 ms
Query took 64.532995223999 ms

Which fills the blanks of the Symfony profiler perfectly. The good news is that when my application goes live, it will connect to the MySQL server locally by socket, so it'll probably be blazing fast! There is little I can do about the speed during the development though, other than mirroring the MySQL server locally.

So to summarize the answer; the Symfony firewall initially creates the connection to the MySQL database, and in my case, that connection is quite slow. The MySQL connection time accounts for over 80% of the firewall's profiled time in my case.


Note: I'm already connecting to the MySQL server by IP address, and I've added skip-name-resolve to the MySQL configuration to no avail.


Your MySQL server might be the problem. Try adding skip-name-resolve to the [mysqld] section of your my.cnf file. This stops MySQL from doing a reverse DNS lookup on the IP address of incoming connections.