Skip to main content
Guides

PHP SDK

The Perfbase PHP SDK wraps the native extension and handles configuration, HTTP transport, and error handling. Use it directly when your framework doesn’t have a first-party integration, or when you need fine-grained control over what gets profiled.

Installation

Install the Perfbase PHP extension first. This is what does the actual profiling:

bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"

Then install the SDK via Composer:

composer require perfbase/perfbase-sdk

Quick start

use Perfbase\SDK\Perfbase;
use Perfbase\SDK\Config;

$config = Config::fromArray([
    'api_key' => 'your_api_key_here',
]);

$perfbase = new Perfbase($config);

$perfbase->startTraceSpan('my-request');

// Your application code runs here; the extension
// profiles every function call automatically.

$perfbase->stopTraceSpan('my-request');
$perfbase->submitTrace();

That’s it. The trace appears in your Perfbase dashboard within seconds.

Configuration

Create a configuration with Config::fromArray() or Config::new():

$config = Config::fromArray([
    'api_key'  => 'sk_live_abc123',
    'api_url'  => 'https://ingress.perfbase.cloud',
    'timeout'  => 10,
    'proxy'    => null,
    'flags'    => FeatureFlags::DefaultFlags,
]);
KeyTypeDefaultDescription
api_keystring-Required. Your project API key.
api_urlstringhttps://ingress.perfbase.cloudIngestion endpoint. Must be HTTPS.
timeoutint10HTTP request timeout in seconds.
proxystring|nullnullProxy URL. Supports http, https, socks5, socks5h.
flagsintDefaultFlagsBitmask controlling which subsystems to profile. See Feature flags.

Configuration is validated at creation time. Invalid values throw PerfbaseInvalidConfigException.

Profiling spans

A span represents a unit of work you want to profile, typically one HTTP request, queue job, or CLI command.

$perfbase->startTraceSpan('http.GET./users');

// everything between start and stop is profiled

$perfbase->stopTraceSpan('http.GET./users');

Span names must match ^[A-Za-z0-9_-]{1,64}$: letters, numbers, hyphens, and underscores, up to 64 characters. Invalid names throw PerfbaseInvalidSpanException.

Multiple concurrent spans are supported. Each span tracks its own timing independently:

$perfbase->startTraceSpan('db-migration');
$perfbase->startTraceSpan('seed-data');

runMigrations();
$perfbase->stopTraceSpan('db-migration');

seedDatabase();
$perfbase->stopTraceSpan('seed-data');

$perfbase->submitTrace();

You can also pass initial attributes when starting a span:

$perfbase->startTraceSpan('api-request', [
    'endpoint' => '/api/v1/users',
    'method'   => 'POST',
]);

Custom attributes

Add metadata to the current trace with setAttribute(). Attributes are trace-level (not span-scoped) and must be string key-value pairs:

$perfbase->setAttribute('user_id', '12345');
$perfbase->setAttribute('environment', 'production');
$perfbase->setAttribute('app_version', '2.4.1');

Attributes appear in the Perfbase dashboard alongside the trace, making it easy to filter and search.

Submitting traces

submitTrace() sends the profiling data to Perfbase and returns a SubmitResult:

$result = $perfbase->submitTrace();

if ($result->isSuccess()) {
    // Trace submitted. Profiler state is automatically reset.
}

if ($result->isRetryable()) {
    // Network error, 429, or 5xx; safe to retry later.
    error_log('Perfbase: ' . $result->getMessage());
}

if ($result->isPermanentFailure()) {
    // 4xx auth/validation error; check your API key and config.
    error_log('Perfbase: ' . $result->getMessage());
}

On success, the SDK automatically resets the profiler. On failure, the trace data is preserved so you can decide whether to retry.

The SDK does not retry automatically. This is intentional, so submissions never block your application longer than the configured timeout.

Feature flags

Feature flags control which PHP subsystems the extension profiles. Combine them with the bitwise OR operator:

use Perfbase\SDK\FeatureFlags;

$config = Config::fromArray([
    'api_key' => 'sk_live_abc123',
    'flags'   => FeatureFlags::TrackCpuTime | FeatureFlags::TrackPdo | FeatureFlags::TrackHttp,
]);
FlagDefaultDescription
UseCoarseClockOnFaster clock with lower overhead. Disable for sub-millisecond accuracy.
TrackCpuTimeOnCPU time per function call.
TrackPdoOnPDO database queries and execution times.
TrackHttpOnOutbound HTTP requests via cURL.
TrackCachesOnRedis, Memcached, and APCu operations.
TrackMongodbOnMongoDB operations.
TrackElasticsearchOnElasticsearch queries.
TrackQueuesOnQueue and background job operations.
TrackAwsSdkOnAWS SDK calls.
TrackMemoryAllocationOffHeap allocation tracking via Zend Memory Manager.
TrackFileOperationsOffFile I/O (fopen, fread, fwrite, etc.).
TrackFileCompilationOffPHP file compilation time.
TrackFileDefinitionsOffClass and function definitions per file.
TrackExceptionsOffException tracking (reserved for future use).

DefaultFlags enables the first 9 flags, which is a good balance of visibility and low overhead for most applications.

AllFlags enables everything. Useful for debugging, but increases overhead.

You can change flags at runtime without creating a new instance:

$perfbase->setFlags(FeatureFlags::AllFlags);

Error handling

The SDK uses exceptions for configuration and setup errors, and result objects for submission outcomes.

ExceptionWhen
PerfbaseExtensionExceptionThe ext-perfbase extension is not loaded or is missing required functions.
PerfbaseInvalidConfigExceptionA configuration value is invalid (missing API key, non-HTTPS URL, etc.).
PerfbaseInvalidSpanExceptionA span name doesn’t match the allowed pattern.

All exceptions extend PerfbaseException, so you can catch them with a single type:

use Perfbase\SDK\Exception\PerfbaseException;

try {
    $perfbase = new Perfbase($config);
    $perfbase->startTraceSpan('my-span');
} catch (PerfbaseException $e) {
    // Extension missing, bad config, or invalid span name
    error_log('Perfbase setup failed: ' . $e->getMessage());
}

Submission errors are never thrown. They are returned as SubmitResult so your application is never interrupted by a profiling failure.

Checking availability

Before constructing the SDK, you can check whether the extension is loaded:

if (Perfbase::isAvailable()) {
    $perfbase = new Perfbase($config);
    $perfbase->startTraceSpan('request');
}

This is useful for conditional profiling in environments where the extension may not be installed (e.g., local development without Docker).

Framework integrations

If you’re using Laravel, WordPress, or another supported framework, you don’t need the SDK directly. Use the framework package instead for automatic profiling of HTTP requests, queue jobs, and CLI commands:

The SDK is the right choice when you need manual control, or when your framework doesn’t have a first-party integration yet.