sebastianbergmann/php-timer · error · TimeSinceStartOfRequestNotAvailableException
Cannot determine time at which the request started because…
Error message
Cannot determine time at which the request started because $_SERVER['REQUEST_TIME_FLOAT'] is not available
What it means
This exception is thrown by ResourceUsageFormatter::resourceUsageSinceStartOfRequest() when the superglobal $_SERVER['REQUEST_TIME_FLOAT'] is not set. The library uses that value (the timestamp the request started, provided by PHP's SAPI) to compute how much time/resources the request has consumed. Without it, no duration can be calculated, so the method fails fast with TimeSinceStartOfRequestNotAvailableException.
Solutions
- Check isset($_SERVER['REQUEST_TIME_FLOAT']) (and that it is a float) before calling resourceUsageSinceStartOfRequest(), and fall back to a manually recorded start time when absent
- Use the alternative ResourceUsageFormatter::resourceUsage(Duration $duration) API with a Duration you build yourself (e.g. Duration::fromMicroseconds((microtime(true) - $start) * 1000000)) when not in a request context
- Only call resourceUsageSinceStartOfRequest() from genuine HTTP request handling code; in CLI code, capture your own start timestamp instead
Example fix
// before
$usage = $formatter->resourceUsageSinceStartOfRequest();
// after
if (isset($_SERVER['REQUEST_TIME_FLOAT']) && is_float($_SERVER['REQUEST_TIME_FLOAT'])) {
$usage = $formatter->resourceUsageSinceStartOfRequest();
} else {
$start = microtime(true);
// ... work ...
$usage = $formatter->resourceUsage(\SebastianBergmann\Timer\Duration::fromMicroseconds((microtime(true) - $start) * 1000000));
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!isset($_SERVER['REQUEST_TIME_FLOAT'])) {
// not in an HTTP request context; use a manual start time instead
}
Type guard
function hasRequestTimeFloat(): bool
{
return isset($_SERVER['REQUEST_TIME_FLOAT']) && is_float($_SERVER['REQUEST_TIME_FLOAT']);
}
Try / catch
use SebastianBergmann\Timer\TimeSinceStartOfRequestNotAvailableException;
try {
$usage = $formatter->resourceUsageSinceStartOfRequest();
} catch (TimeSinceStartOfRequestNotAvailableException $e) {
$usage = $formatter->resourceUsage(Duration::fromMicroseconds((microtime(true) - $fallbackStart) * 1000000));
}
Prevention
- Only use resourceUsageSinceStartOfRequest() in SAPI/HTTP request handlers
- In CLI scripts, record microtime(true) yourself and use resourceUsage(Duration)
- Check the request-context precondition (isset + is_float) before calling
- Add a unit test that exercises the fallback path
When it happens
Trigger: Calling resourceUsageSinceStartOfRequest() in a context where PHP never populates $_SERVER['REQUEST_TIME_FLOAT'] — most commonly CLI scripts (phpunit, workers, cron jobs) instead of an HTTP/SAPI request context.
Common situations: Running PHPUnit or a CLI command that reuses web-oriented formatting code; executing code via a custom runner or daemon where the SAPI does not set REQUEST_TIME_FLOAT; unit tests that invoke the formatter with a minimal/empty $_SERVER array.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Cannot determine time at which the request started because…
- Timer::start() has to be called before Timer::stop()
AI-assisted analysis of sebastianbergmann/php-timer@3efcdcf213 (2026-09-13).
Data as JSON: /api/errors/2a8a146bcbb42b49.
Report an issue: GitHub.
Appendix: source
Thrown at src/ResourceUsageFormatter.php:43
'KB' => 1024,
];
public function resourceUsage(Duration $duration): string
{
return sprintf(
'Time: %s, Memory: %s',
$duration->asString(),
$this->bytesToString(memory_get_peak_usage(true)),
);
}
/**
* @throws TimeSinceStartOfRequestNotAvailableException
*/
public function resourceUsageSinceStartOfRequest(): string
{
if (!isset($_SERVER['REQUEST_TIME_FLOAT'])) {
throw new TimeSinceStartOfRequestNotAvailableException(
'Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not available',
);
}
if (!is_float($_SERVER['REQUEST_TIME_FLOAT'])) {
throw new TimeSinceStartOfRequestNotAvailableException(
'Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not of type float',
);
}
return $this->resourceUsage(
Duration::fromMicroseconds(
(1000000 * (microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'])),
),
);
}
private function bytesToString(int $bytes): stringView on GitHub (pinned to 3efcdcf213)