Measure first

How to speed up a slow PHP/Symfony application

Do not guess what is slow. Find one bottleneck, fix it, and measure the result again.

25 minutes · PHP and Symfony

First, the short version

Why is an application slow?

The slowness is often not caused by PHP itself. It may come from one unnecessary SQL query, a remote API, or work repeated on every page load.

Start with one URL and the same scenario. The Symfony profiler shows time, queries, and other calls. In production, use safe monitoring — not a public debug panel.

Get ready

What you need

Measure before and after the change. Otherwise you cannot know whether it really helped.

  • One slow page or API request you can repeat with the same data.
  • A development environment with the Symfony profiler or safely configured application monitoring in production.
  • Access to slow SQL queries and their execution plans.
  • A way to clear and inspect cache, so you do not accidentally measure an old result.

Step 1

Look for the cause in this order

Do not make ten optimizations at once. Each step needs a measurable reason.

1. Measure a specific request

  1. Open the same page several times. The first load can be affected by cache warm-up, so record more than one measurement.
  2. In the profiler, look at total time, the number of database queries, and slow external calls.
  3. Choose one most expensive part. Only then change code.
php bin/console about
Symfony profiler

2. Fix the database query

  1. Find repeated queries and loading data one record at a time. This is often the N+1 problem.
  2. Run a plan for the specific SQL query. Add a database index only when it matches filters and sorting you actually use.
  3. After the change, compare time and the number of rows read. Indexes also have a cost on writes.
EXPLAIN SELECT ...;
PostgreSQL: EXPLAIN

3. Cache repeated work

  1. Use cache for an expensive calculation or data that does not change for a while. Do not cache all personalized content without thinking.
  2. For shared cache, you can use Redis. The key must distinguish language, user, or filter when they change the result.
  3. When source data changes, clear the related cache intentionally. This is called cache invalidation.
php bin/console cache:pool:list
Symfony Cache

Step 2

Check that the right part is faster

A faster number is not enough. The result must stay correct for a regular user.

  1. Repeat the same measurement

    Compare several loads of the same page. Record the time before and after the change.

  2. Check queries

    In the profiler, confirm fewer queries or a better plan. An index that is not actually used does not solve the problem.

    EXPLAIN ANALYZE SELECT ...;
  3. Test behavior without cache

    Clear the cache, change data, and open the page again. A user must not receive stale or someone else’s content.

    php bin/console cache:pool:clear cache.app

If something goes wrong

Common problems

I added cache and the page is still slow

Check whether a cache hit ever occurs. You may have a different key every time, a very short lifetime, or slow code before the cache.

The new index did not help

Look at the plan with EXPLAIN. The query may filter another column, return most of the table, or need a different SQL shape.

I enable the profiler for everyone in production

Do not do that. The profiler can expose sensitive data and adds overhead. Use limited monitoring with access only for the team.

Old data appears after optimization

Add a clear cache invalidation rule. Clear only keys related to the change, not everything blindly on every write.

Done

The application has less work to do.

You now have a repeatable process: measure, find the bottleneck, change one thing, and check the result.

Request a call

I will call you on the next working day between 9:00 and 17:00.

You can also call me directly.

+420 605 181 728

Leave your phone number and send a callback request.

By sending, you agree to processing your data in order to handle your request.