TubeSum ← Transcribe a video

Why Default Timeouts Are Hurting Your PHP App (and What to Do About It)

0h 12m video Published Jun 25, 2025 Transcribed Aug 3, 2026 T Tideways
Intermediate 6 min read For: PHP developers who want to improve application reliability by properly configuring timeouts.
AI Trust Score 75/100
⚠️ Average / Some Fluff

"Delivers exactly what the title promises: a clear explanation of default timeout pitfalls and actionable fixes."

AI Summary

This video discusses the critical issue of timeouts in PHP applications, explaining why default timeout settings are often too high and can lead to application instability during failures. The presenter, Benjamin, demonstrates how to configure timeouts for various PHP functions and libraries to achieve fast failures and maintain application responsiveness.

[00:01]
The Problem with Default Timeouts

Default timeouts are too high (e.g., 60 seconds for default_socket_timeout), causing requests to hang and exhaust PHP's limited parallel request capacity, leading to rejection of healthy requests.

[01:01]
Status Quo of Timeouts in PHP

The PHP ini setting default_socket_timeout is 60 seconds by default, affecting internal functions like file_get_contents, fopendoc, and SOAP client.

[01:35]
Curl and Max Execution Time Misconceptions

Curl has no default timeout, and relying on max_execution_time is wrong because it measures CPU time, not wall time, so IO waits don't count toward it.

[04:41]
Connection Timeouts

Connection timeouts are often forgotten; there are two independent timeouts: read/write timeout and connection timeout. Defaults like 2 seconds may be too high for local networks.

[06:21]
Why Fast Failures Matter

Slow failures hurt user experience and capacity; reducing timeouts to 5-10 seconds globally is recommended as a first step.

[07:05]
Configuring Timeouts for file_get_contents

Use stream_context_create with HTTP timeout option to set timeouts below 1 second, but be aware of TCP internals like TCP_NODELAY for very low timeouts.

[08:21]
Configuring Timeouts for DOMDocument and SOAP

For DOMDocument, use stream context and libxml_set_streams_context; for SOAP, use default_socket_timeout for read/write and connection_timeout option.

[09:36]
Configuring Timeouts for cURL

Set CURLOPT_TIMEOUT for read/write and CURLOPT_CONNECTTIMEOUT for connection; check HTTP code 0 to detect timeout. Millisecond options available.

[10:46]
Configuring Timeouts for Predis

Set timeout for connection and read_write_timeout for idle; also set TCP_NODELAY to true for low timeouts to work correctly.

Properly configuring timeouts is essential for PHP application stability during failures. By reducing timeouts and setting them appropriately for each client, you can ensure fast failures and maintain capacity for healthy requests.

Mentioned in this Video

Tutorial Checklist

1 06:49 Reduce global timeouts to 5-10 seconds using ini_set('default_socket_timeout', 5) or in php.ini.
2 07:05 For file_get_contents, create a stream context with HTTP timeout option (e.g., 0.5 seconds) and pass it to the function.
3 08:21 For DOMDocument, create a stream context with timeout and set it via libxml_set_streams_context() before loading remote documents.
4 08:50 For SOAP client, set default_socket_timeout for read/write and connection_timeout option in SOAP options.
5 09:36 For cURL, set CURLOPT_TIMEOUT and CURLOPT_CONNECTTIMEOUT; use millisecond options for finer control.
6 10:46 For Predis, set 'timeout' for connection and 'read_write_timeout' for idle; also set 'tcp_nodelay' to true.

Study Flashcards (6)

What is the default value of default_socket_timeout in PHP?

easy Click to reveal answer

60 seconds

01:01

Why is max_execution_time not effective for long-running IO operations?

medium Click to reveal answer

It measures CPU time, not wall time, so IO waits don't count toward it.

02:01

What are the two independent timeouts in network communication?

easy Click to reveal answer

Read/write timeout and connection timeout.

04:56

How can you set a timeout for file_get_contents?

medium Click to reveal answer

Use stream_context_create with HTTP timeout option.

07:05

What options are needed for cURL timeouts?

medium Click to reveal answer

CURLOPT_TIMEOUT for read/write and CURLOPT_CONNECTTIMEOUT for connection.

09:36

What is the recommended global timeout range?

easy Click to reveal answer

5 to 10 seconds.

06:49

💡 Key Takeaways

💡

Timeouts as Jenga Tower

Vivid analogy illustrating how one slow service can collapse the whole application.

00:01
📊

Max Execution Time Measures CPU Time

Critical fact that max_execution_time doesn't count IO waits, debunking a common misconception.

02:01
⚖️

Fast Failures for Stability

Explains why reducing timeouts is crucial for user experience and capacity.

06:21
🔧

TCP_NODELAY for Low Timeouts

Practical tip that TCP_NODELAY may be required for very low timeouts to work.

07:34

[00:01] timeouts is like balancing a Jenga tower during an earthquake. One shaky external service and the whole thing collapses. Timeouts are way too high by default. They are not affected by max execution time and code often forgets to handle

[00:16] connection timeouts. In this video, I'm going to talk about how you can application to keep control during failure scenarios. Mo, I'm Benjamin and PHP performance is my main focus for the last 10 years, helping thousands of

[00:31] developers, companies, and open source projects along the way. Why even care about timeouts and achieving fast failures? Because PHP can only handle a limited amount of parallel requests at the same time configured in Apache or

[00:45] PHP FBM. When you have enough of them waiting for a long time because of timeouts, then at some point other perfectly fine requests will be rejected at the web server level because there's no available capacity to process them.

[01:01] Let's review the status quo of timeouts in PHP. In general, timeouts are controlled by the PHP ini setting, default socket timeout, which is at an default socket timeout, which is at an incredible high 60 seconds by default.

[01:16] This applies to file get contents fop dump document soap client and more internal APIs. Let's look at some code to understand it. This 60-cond default applies to internal functions that are using streams such as fet contents fop

[01:35] using streams such as fet contents fop document or the soap client. curl is supplying no timeout by default and if the back end is hanging then also the PHP request would wait indefinitely for it but you would be wrong to rely on max

[01:49] it but you would be wrong to rely on max execution time to rescue you. The 30 seconds default is not applying to uh IO functions. First uh if an IO function is

[02:01] functions. First uh if an IO function is running for a long time then the Zent uh and PHP virtual machine is not actually getting to a state where it checks that the execution time is reached and aborting the script. Second, even on

[02:15] aborting the script. Second, even on Linux the max execution time is measured in CPU time and not in wall time. That means if you're waiting for IO the um max execution time is not actually increasing. It's best to look at some

[02:30] code to understand how this uh works. So we have this example here and I want to explain it a little bit. So we we reduce the max execution time to 1 second so that uh we have a short example to test.

[02:45] that uh we have a short example to test. I have uh included a timer PHP here. I have uh included a timer PHP here. The timer PHP um is just a simple include that takes the start time uh using the high resolution timing API of

[03:00] PHP. Uh if you're not familiar with it, it's uh a new API um that replaces micro time for benchmarking because it uses a more uh a better timer

[03:13] because it uses a more uh a better timer uh API from Linux or other systems than microt uses. Then we register a shutdown function. It also takes the high resolution timer. It computes the difference and uh calculates this in

[03:27] difference and uh calculates this in seconds. So it's human readable. And what we do then in the script is we run an endless loop. We perform one IO an endless loop. We perform one IO weight operation. Uh sleep is uh an IO

[03:42] operation. But this could be a database query or an expensive HTTP call taking a query or an expensive HTTP call taking a long time. And then we uh perform some uh expensive CPU uh weight time uh which

[03:56] is the password hash function which encrypts the string into a password and encrypts the string into a password and this is um taking quite some time. this is um taking quite some time. So uh let's run this and see how max

[04:08] execution time works here with regard to um IO time. So running the script, we expect it to run just 1 second based on max execution time, but it actually runs 4 seconds. And the reason for this is that it only

[04:25] calculates the 1 second of CPU time that the script takes, but there is uh around the script takes, but there is uh around 3 seconds of uh IO weight time through the use function here, which is not counted towards the next execution time.

[04:41] And uh therefore if you have scripts that have long running IO then max execution time is not the right way to prevent um scripts from running too long and aborting them. Connection timeouts are the next problem. They are usually

[04:56] forgotten in network communication. There are usually two independent timeouts in effect. First the timeout that is measured for readr writing on the connection and then second the time out for the connection itself. So

[05:11] waiting for um actually connecting to the machine in um and communicating with the machine in um and communicating with it. Uh let's see how uh this works um in practice. In this script, we set the default socket timeout to 2 seconds. We

[05:27] include our timer as before and then we perform file get contents against an address that doesn't exist. So it's not reachable. So when we run the script php

[05:40] reachable. So when we run the script php connect time out to then we would expect it to be uh terminated at 2 seconds. That's true. So here this is the That's true. So here this is the connection time. So um

[05:54] it waited 2 seconds before it decided that this server is not reachable for local connections. 2 seconds or even 1 second might be way too high. Uh if you

[06:06] know that a service is not available in the local network, you can usually know this in like a very few milliseconds. Uh and the timeout uh the connection timeout for this should be configured way lower. By now it should be obvious

[06:21] that this slow failure mode by default is bad for application stability during a failure. For user experience reasons, you want the users to see a failure page quickly enough, not after 60 seconds. And for capacity reasons, you want to

[06:36] keep your PHP process free for handling requests that are not relying on the requests that are not relying on the unavailable services. As a first step, you should therefore reduce the global timeouts to a more manageable number of

[06:49] 5 to 10 seconds. What makes you feel comfortable? You can change this in code like I'm showing here using ini set function or globally in the php.ini. To reduce the time out for file get

[07:05] contents, you need to use the stream context create function to create a context create function to create a context and you specify HTTP uh options here. So you can specify the timeout in this case to be 1 second or even below 1

[07:21] second. So let's say half a second. However, be careful um because of TCP uh inner workings uh Linux and how PHP works. uh a very low time out might not

[07:34] actually be recognized and um there's let's say one option TCP no delay that is not set by default which might be required to be set here as well to get low timeouts. So then uh we have the f get contents

[07:48] call against uh a local address that's not available. Let's run this. PHP not available. Let's run this. PHP reduce file get contents time out. And there we see the script uh stops after um half a second. So the time out

[08:05] after um half a second. So the time out here works um perfectly fine. If you are making HTTP calls through the DOM document API, then you also need to use stream uh context create again HTTP set a timeout and then you need to pass

[08:21] this context to lip XML set stream context and then it's being used for outgoing HTTP requests. So if you load a remote document with uh DOM document API then this will work. So, PHP reduce

[08:36] document and we see um there's the timeout stopping the script after 1 timeout stopping the script after 1 second again uh against an endpoint that is not available. For the SOAP client, it's similar but different because the

[08:50] SOAP client is not using the PHP streams API internally. We cannot configure it using uh a stream context. Instead we have to use the default socket timeout for the read write timeout and then we have to set a connection time out using

[09:06] the SOAP options and uh then again making a call against an an endpoint making a call against an an endpoint that is not available not reachable. that is not available not reachable. Then we find out that uh we have the

[09:20] error could not connect to host after 1 second. So the script is supported. Continuing with timeouts for curl, you need to set curl opt out for the read write timeout and you need to set curl

[09:36] opt connection time out or connect time out for the connection timeout. So these out for the connection timeout. So these are configured separately uh compared to u the stream context API where the timeout is used for both settings.

[09:51] uh then we can determine that a timeout happened. If the HTTP code is uh zero then the script was aborted. We don't have a um response. So let's see and

[10:04] have a um response. So let's see and test this So we see here after 1 second uh the timeout happened. We see the error

[10:18] message. If you need more control over the timeouts in curl, there are also options that allow you to configure the timeout in milliseconds. So, let's say timeout in milliseconds. So, let's say 2,00 milliseconds for readr timeout and

[10:32] 1,000 milliseconds for the connection timeout. the script uh terminates. Last but not least, uh I want to show how to

[10:46] configure timeouts for the P reddus library because it's quite widespread. library because it's quite widespread. You need to set um the option time out and then read write timeout. So timeout is the connection timeout. Read write

[10:59] is the connection timeout. Read write timeout is the timeout uh that applies when the connection is already present but uh nothing is happening on it. And then in uh this case also we set TCP no delay to true. Otherwise for a very low

[11:13] timeout uh we have seen that it doesn't work uh this way. It takes way longer to work uh this way. It takes way longer to uh um like stop the script if the timeout is reached. So let's see how this works in practice. We run the

[11:30] reduce prediscript and then we can see after zero uh six uh 260 milliseconds the script is stopped with an error and if we go up here then

[11:44] with an error and if we go up here then we can see operation timed out. So this is um the error happening on the PHP stream when the timeout is reached. I hope this was some helpful advice on timeouts in PHP for you. I also have a

[11:59] video on max execution time on this channel that you should watch. And newsletter. The link is in the description. Bye.

More from Tideways

View all

⚡ Saved you 0h 12m reading this? Transcribe any YouTube video for free — no signup needed.