← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Promises & Futures

Concurrency PHP 7.0+ Intermediate
debt(d7/e3/b5/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7) — forgetting to call ->wait() or unhandled rejections aren't flagged by standard PHP linters; detection_hints empty, but PHPStan/Psalm don't generally catch missing wait() calls, only careful review or runtime observation reveals the missing concurrency.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3) — per quick_fix, swapping sequential Guzzle calls to async with Utils::all() is a localised pattern change within the integration code, not a full refactor.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5) — async/Promise code colours every function that touches it; mixing sync and async logic slows many workstreams since applies_to spans web and cli contexts, and Promise chains shape error handling throughout integration layers.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7) — the misconception that PHP Promises provide true parallelism contradicts how Promises behave in genuinely threaded environments; developers coming from JS or threaded languages reasonably assume parallel execution but get cooperative concurrency, and Promises don't execute at all without wait().

About DEBT scoring →

Also Known As

Promise Future async promise deferred then/catch PromiseInterface

TL;DR

Abstractions representing the eventual result of an async operation — a Promise or Future is a placeholder for a value not yet available, enabling non-blocking code composition without nested callbacks.

Explanation

A Promise (JavaScript term) or Future (Java/PHP term) represents a computation that may not have completed yet. The object provides methods to attach callbacks that run when the value is ready (then/onFulfilled) or when an error occurs (catch/onRejected). Promises solve callback hell — the pyramid of nested callbacks that becomes unreadable when composing multiple async operations. In JavaScript, Promises are built-in and async/await is syntactic sugar over them. In PHP, Promises appear in ReactPHP and Guzzle — Guzzle's async HTTP client returns PromiseInterface objects that can be composed with Utils::all() for parallel requests. PHP Fibers (8.1+) provide a lower-level cooperative multitasking primitive that async frameworks use internally. The key distinction: a Promise represents a result that will be ready; a Future is a handle to cancel or check the status of the operation as well.

Common Misconception

PHP Promises provide true parallel execution. PHP is single-threaded — Promises and Fibers in PHP provide cooperative concurrency (one thing runs at a time, yielding control voluntarily) not parallel execution. Multiple Guzzle async requests run concurrently because they yield during network I/O wait time, not because PHP spawns threads. For CPU-bound parallelism in PHP, pcntl_fork(), separate processes, or a queue with multiple workers are the correct tools.

Why It Matters

Promises enable concurrent I/O without threads. A PHP script that needs to make five API calls can fire all five simultaneously with Guzzle's async client and Promise::all(), completing in the time of the slowest call rather than the sum of all five. Without Promises, sequential synchronous calls take 5× longer. For PHP applications with multiple external service dependencies — payment gateways, shipping APIs, product feeds — async Promises with concurrent requests is the highest-impact performance optimisation for integration-heavy pages.

Common Mistakes

  • Forgetting to call $pool->promise()->wait() — creating async Guzzle requests without waiting for them means they never execute.
  • Assuming PHP Promises provide thread-level parallelism — they provide I/O concurrency, not CPU parallelism.
  • Not handling Promise rejections — an unhandled rejection silently swallows errors in some implementations; always attach a catch handler.
  • Mixing synchronous and async code without understanding when execution occurs — a Promise callback runs when the event loop processes it, not immediately.

Code Examples

✗ Vulnerable
// Sequential — total time = sum of all request times
$client = new GuzzleHttp\Client();
$user    = $client->get('/api/user/' . $id)->getBody();    // 200ms
$orders  = $client->get('/api/orders?user=' . $id)->getBody(); // 180ms
$prefs   = $client->get('/api/prefs/' . $id)->getBody();   // 150ms
// Total: ~530ms
✓ Fixed
// Concurrent — total time = slowest single request
use GuzzleHttp\Client;
use GuzzleHttp\Utils;

$client  = new Client();
$promises = [
    'user'   => $client->getAsync('/api/user/' . $id),
    'orders' => $client->getAsync('/api/orders?user=' . $id),
    'prefs'  => $client->getAsync('/api/prefs/' . $id),
];

$results = Utils::unwrap(Utils::all($promises));
// All three fire simultaneously — total: ~200ms
$user   = json_decode($results['user']->getBody(), true);
$orders = json_decode($results['orders']->getBody(), true);

Added 23 Mar 2026
Edited 5 Apr 2026
Views 46
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 2 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 2 pings T 1 ping F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 2 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 10 Google 8 ChatGPT 3 Perplexity 3 Ahrefs 3 Scrapy 3 Meta AI 2 Bing 2 SEMrush 2 Claude 1 PetalBot 1
crawler 33 crawler_json 5
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: Medium
⚡ Quick Fix
Use Guzzle's async client with Utils::all() to fire multiple HTTP requests concurrently — reduces total I/O time from sum to max of individual request times
📦 Applies To
PHP 7.0+ web cli


✓ schema.org compliant