Table of contents

How do I customize the timeout for a request in Guzzle?

Setting proper timeouts is crucial when making HTTP requests with Guzzle to prevent your application from hanging indefinitely on slow or unresponsive servers. Guzzle provides two main timeout options to give you fine-grained control over request timing.

Understanding Timeout Types

Guzzle offers two distinct timeout settings:

  • timeout: Maximum time to wait for the complete response (including response body)
  • connect_timeout: Maximum time to wait while establishing a connection to the server

Setting Timeouts Per Request

You can customize timeouts for individual requests by passing options to the request method:

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ConnectException;

$client = new Client();

try {
    $response = $client->request('GET', 'https://httpbin.org/delay/3', [
        'timeout' => 5.0,        // 5 seconds for complete response
        'connect_timeout' => 2.0  // 2 seconds to establish connection
    ]);

    echo "Response received: " . $response->getStatusCode() . "\n";
    echo $response->getBody();

} catch (ConnectException $e) {
    echo "Connection timeout: " . $e->getMessage() . "\n";
} catch (RequestException $e) {
    echo "Request timeout or other error: " . $e->getMessage() . "\n";
}

Setting Default Timeouts for All Requests

For consistent timeout behavior across all requests, configure defaults in the client constructor:

<?php
use GuzzleHttp\Client;

$client = new Client([
    'base_uri' => 'https://api.example.com',
    'timeout' => 10.0,         // Default 10 seconds for all requests
    'connect_timeout' => 3.0,  // Default 3 seconds to connect
    'headers' => [
        'User-Agent' => 'MyApp/1.0'
    ]
]);

// This request will use the default timeouts
$response = $client->get('/users');

// Override defaults for specific requests
$response = $client->get('/slow-endpoint', [
    'timeout' => 30.0  // Extend timeout for this specific request
]);

Advanced Timeout Configuration

Read Timeout for Streaming

For streaming responses or large file downloads, you might need to configure the read timeout separately:

<?php
use GuzzleHttp\Client;

$client = new Client();

$response = $client->request('GET', 'https://example.com/large-file.zip', [
    'timeout' => 0,           // Disable overall timeout
    'read_timeout' => 30.0,   // 30 seconds between data chunks
    'connect_timeout' => 5.0,
    'stream' => true          // Enable streaming
]);

Different Timeouts for Different HTTP Methods

<?php
use GuzzleHttp\Client;

class ApiClient
{
    private $client;

    public function __construct()
    {
        $this->client = new Client([
            'base_uri' => 'https://api.example.com',
            'connect_timeout' => 3.0
        ]);
    }

    public function get($endpoint)
    {
        return $this->client->get($endpoint, [
            'timeout' => 5.0  // Quick reads
        ]);
    }

    public function post($endpoint, $data)
    {
        return $this->client->post($endpoint, [
            'timeout' => 15.0,  // Longer timeout for writes
            'json' => $data
        ]);
    }
}

Handling Timeout Exceptions

Different timeout scenarios throw different exception types:

<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\TransferException;

$client = new Client();

try {
    $response = $client->get('https://slow-server.com/api', [
        'timeout' => 5.0,
        'connect_timeout' => 2.0
    ]);

} catch (ConnectException $e) {
    // Connection timeout or connection failed
    error_log("Failed to connect: " . $e->getMessage());

} catch (RequestException $e) {
    // Request timeout or HTTP error
    if ($e->hasResponse()) {
        error_log("HTTP error: " . $e->getResponse()->getStatusCode());
    } else {
        error_log("Request timeout: " . $e->getMessage());
    }

} catch (TransferException $e) {
    // Other transfer-related errors
    error_log("Transfer error: " . $e->getMessage());
}

Timeout Best Practices

  1. Set appropriate defaults: Start with reasonable defaults (5-10 seconds) and adjust based on your API's performance
  2. Use different timeouts for different operations: Quick reads vs. slow writes or uploads
  3. Consider your infrastructure: Factor in network latency and server processing time
  4. Monitor and adjust: Track timeout frequencies and adjust values based on real-world performance
  5. Handle exceptions gracefully: Always catch and handle timeout exceptions appropriately

Asynchronous Requests

Timeouts work the same way with Guzzle's asynchronous requests:

<?php
use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client();

$promises = [
    'fast' => $client->getAsync('https://httpbin.org/delay/1', [
        'timeout' => 3.0
    ]),
    'slow' => $client->getAsync('https://httpbin.org/delay/5', [
        'timeout' => 10.0
    ])
];

$responses = Promise\settle($promises)->wait();

foreach ($responses as $key => $response) {
    if ($response['state'] === 'fulfilled') {
        echo "$key request succeeded\n";
    } else {
        echo "$key request failed: " . $response['reason']->getMessage() . "\n";
    }
}

By properly configuring timeouts, you ensure your application remains responsive and handles network issues gracefully while still allowing sufficient time for legitimate requests to complete.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon