The article you found by searching for "Gearman PHP 7" still has the right shape, just the wrong versions. PHP 7 went end-of-life in November 2022. In 2026 every supported PHP is 8.x (8.2, 8.3, or 8.4 depending on your distro), and the Gearman install story on Ubuntu has shifted around with it. This is the updated walkthrough: apt path, PECL path, the php.ini wiring that actually loads the extension, a working client/worker test, and where Gearman fits in a queue landscape now dominated by Redis, RabbitMQ, and managed services.
How do I install the Gearman PHP module on Ubuntu?
On Ubuntu 22.04 or 24.04 LTS the fastest path is the distro package: sudo apt install php8.3-gearman gearman-job-server, then sudo phpenmod gearman and restart PHP-FPM or Apache. That installs the extension, the gearmand daemon, and wires the extension into every SAPI in one step. If the prebuilt package is not available for your PHP version, fall back to PECL: install build prerequisites (php8.3-dev, libgearman-dev, gearman-job-server, re2c, pkg-config), then sudo pecl install gearman, drop extension=gearman.so into /etc/php/8.3/mods-available/gearman.ini, run sudo phpenmod gearman, and restart your PHP runtime. Verify with php -m | grep -i gearman and check the daemon with gearmand --version.
Jump to:
- Supported Ubuntu and PHP versions in 2026
- Path A: install Gearman via apt
- Path B: install Gearman via PECL
- Wire the extension into php.ini
- Start and enable the gearmand service
- Verify the install end to end
- A working client and worker in PHP 8.x
- When Gearman still makes sense in 2026
- Troubleshooting
- What to do next
- FAQ
Supported Ubuntu and PHP versions in 2026
Three Ubuntu LTS releases are realistically in play:
| Ubuntu | Default PHP | Gearman via apt | Notes |
|---|---|---|---|
| 24.04 LTS (Noble) | PHP 8.3 | php8.3-gearman | Standard support through April 2029. The default for new installs. |
| 22.04 LTS (Jammy) | PHP 8.1 | php8.1-gearman | Standard support through April 2027. PHP 8.1 itself is past upstream security support (Dec 2025), so most teams pin a newer PHP from ppa:ondrej/php. |
| 20.04 LTS (Focal) | PHP 7.4 | php7.4-gearman | Reached end of standard support in April 2025. Stay on this only with Ubuntu Pro for ESM. PHP 7.4 itself has been EOL since November 2022. |
For anything new, pick 24.04 LTS with PHP 8.3 (or 8.4 from ppa:ondrej/php if you want the latest). The rest of this guide uses 8.3 as the version slug. If you are on a different version, substitute 8.2, 8.4, etc. everywhere you see 8.3 in a path or package name.
If you need a refresher on adding the Ondrej PHP PPA for newer PHP versions on older Ubuntu, the official source is the ondrej/php Launchpad page. The two-liner is sudo add-apt-repository ppa:ondrej/php followed by sudo apt update.
Path A: install Gearman via apt
Whenever the distro package exists for your PHP version, this is the path. It installs the daemon and the extension in one shot:
sudo apt update
sudo apt install gearman-job-server php8.3-gearman
sudo phpenmod gearmangearman-job-server provides the gearmand daemon (the broker that holds job queues). php8.3-gearman is the PHP extension that talks to it. phpenmod symlinks the gearman.ini mod into the SAPI directories you have installed (CLI, Apache, FPM).
Restart whichever PHP runtime serves your app:
# If you run PHP-FPM
sudo systemctl restart php8.3-fpm
# If you run Apache with mod_php
sudo systemctl restart apache2That is the whole install on a happy path. Skip ahead to verify the install.
If apt install php8.3-gearman returns Unable to locate package, your Ubuntu release does not ship a prebuilt extension for that PHP version. Two options: install a different PHP version that does have a package, or build the extension yourself with PECL.
Path B: install Gearman via PECL
The PECL route compiles the extension from source against your installed PHP headers. It works on every PHP 8.x version, but it costs you a phpize/make cycle and the dependency installs that go with it.
Install the build prerequisites:
sudo apt update
sudo apt install \
gearman-job-server \
libgearman-dev \
php8.3-dev \
php-pear \
re2c \
pkg-config \
build-essentialBuild and install the extension:
sudo pecl install gearmanPECL will compile gearman.so into your PHP extension directory. Find that path with php -i | grep extension_dir if you need it.
If the build fails on pecl install, the usual culprit is a missing header. The package libgearman-dev provides libgearman/gearman.h; php8.3-dev provides phpize and the PHP API headers. Re-run sudo pecl install gearman after fixing whichever is missing.
Wire the extension into php.ini
The pecl install step compiles the .so but does not add it to any php.ini. The clean way to enable it is to drop a small .ini file into the per-SAPI mods directory and let phpenmod symlink it into every SAPI:
echo "extension=gearman.so" | sudo tee /etc/php/8.3/mods-available/gearman.ini
sudo phpenmod gearmanphpenmod creates symlinks in /etc/php/8.3/cli/conf.d/, /etc/php/8.3/fpm/conf.d/, and /etc/php/8.3/apache2/conf.d/ (whichever SAPIs are installed). Each filename gets a numeric prefix that controls load order: 20-gearman.ini is conventional for extensions with no dependencies.
If you only want the extension on one SAPI (CLI for worker scripts, but not Apache), add the line directly to that SAPI's php.ini instead:
# CLI only (worker scripts run from cron or systemd timers)
echo "extension=gearman.so" | sudo tee -a /etc/php/8.3/cli/php.iniRestart the relevant runtime after editing:
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2 # if you run mod_phpCLI does not need a restart, the next php invocation reads the new ini.
Start and enable the gearmand service
The gearman-job-server package on modern Ubuntu installs a systemd unit. Start it and enable it on boot:
sudo systemctl start gearmand
sudo systemctl enable gearmand
sudo systemctl status gearmandBy default gearmand listens on 127.0.0.1:4730. If your worker runs on a different host, edit /etc/default/gearmand and add a bind flag like PARAMS="--listen=0.0.0.0". Production deployments should put gearmand on a private network only, it has no built-in authentication.
For a persistent queue (jobs survive a gearmand restart), point it at a SQLite or MySQL queue:
# /etc/default/gearmand
PARAMS="--queue-type=builtin --listen=127.0.0.1"The default in-memory queue is fastest but loses jobs on restart. The SQLite queue (--queue-type=libsqlite3 --libsqlite3-db=/var/lib/gearmand/queue.db) is the cheap durable option for single-host setups.
Verify the install end to end
Three quick checks:
# 1. PHP can see the extension
php -m | grep -i gearman
# Expected: gearman
# 2. The daemon is reachable
gearmand --version
# 3. Port 4730 is listening
ss -ltnp | grep 4730If php -m | grep -i gearman returns nothing, the extension is not loaded. Common causes: phpenmod gearman was not run, the wrong SAPI's php.ini was edited, or PHP-FPM was not restarted. Check php --ini to see which files are loaded and confirm gearman.ini is in the list.
If ss -ltnp | grep 4730 returns nothing, gearmand is not running. sudo journalctl -u gearmand --since "5 minutes ago" usually tells you why, most often a port conflict or a missing data directory if you turned on the libsqlite3 queue.
A working client and worker in PHP 8.x
The Gearman PECL API is the same across PHP 7 and PHP 8, so old code mostly still runs. Here is the canonical hello-world pair to confirm the round-trip works.
worker.php:
<?php
declare(strict_types=1);
$worker = new GearmanWorker();
$worker->addServer('127.0.0.1', 4730);
$worker->addFunction('reverse', function (GearmanJob $job): string {
$payload = $job->workload();
return strrev($payload);
});
echo "Worker waiting for jobs...\n";
while ($worker->work()) {
if ($worker->returnCode() !== GEARMAN_SUCCESS) {
fwrite(STDERR, "Worker error: " . $worker->error() . "\n");
break;
}
}client.php:
<?php
declare(strict_types=1);
$client = new GearmanClient();
$client->addServer('127.0.0.1', 4730);
$result = $client->doNormal('reverse', 'Hello Gearman on PHP 8');
echo $result . "\n";Run them in two terminals:
# Terminal 1
php worker.php
# Terminal 2
php client.php
# Output: 8 PHP no namraeG olleHIf the client hangs, the worker is not connected to the same gearmand. If client.php throws Could not connect to 127.0.0.1:4730, the daemon is not running or is bound to a different interface.
For longer-running PHP workers, run them under a process supervisor (systemd unit, supervisord, or PM2 if you must) so they restart on crash. A bare while ($worker->work()) loop will exit on the first transient GEARMAN_NO_ACTIVE_FDS and you do not want to be on call for that.
When Gearman still makes sense in 2026
Gearman peaked in popularity around 2012-2015 and has had a quiet existence since. It is still maintained (gearman/gearmand on GitHub), and it still does one thing very well: distributing units of synchronous or background work across PHP workers with minimal ceremony.
When Gearman is the right call:
- You have an existing PHP codebase already using it and the cost of migration outweighs the cost of running gearmand on a couple of boxes.
- You want a job server that does not require setting up Redis, RabbitMQ, or a cloud service for development.
- You need both synchronous (
doNormal) and asynchronous (doBackground) job patterns in the same daemon without two different libraries. - Your worker code is already PHP and you want to keep the deployment surface small.
When a modern alternative is the better call:
| Tool | Strengths | Pick when... |
|---|---|---|
| Redis (Lists, Streams, Resque) | Already in your stack, persistent, fast, mature client libraries | You already use Redis for cache and want one less service to operate |
| Beanstalkd | Tiny, fast, priority queues, TTR per job | You want Gearman semantics with a smaller binary and better priority support |
| RabbitMQ | Topic exchanges, fanout, dead-letter queues, multi-language | You need routing, multiple consumers per message, or polyglot workers |
| AWS SQS | Managed, scales infinitely, no ops | You are on AWS and a few hundred ms latency per job is fine |
| Google Cloud Tasks | Managed HTTP-target queue, scheduled tasks | You want serverless workers (Cloud Run) consuming the queue |
| Laravel Horizon (Redis backend) | Built-in if you use Laravel, web UI for metrics | You are on Laravel and a Redis dependency is acceptable |
If you are starting greenfield and you can pick anything, the median-path answer in 2026 is "use Redis Streams with a small worker library" for single-region PHP work, "use SQS or Cloud Tasks" for serverless, and "use RabbitMQ" if you need topic routing. Gearman remains a reasonable choice for legacy maintenance and small self-hosted setups where simplicity matters more than features.
Troubleshooting
"Class GearmanClient not found" at runtime. PHP cannot see the extension. Run php -m | grep gearman from the SAPI you are using. If CLI shows the module but FPM does not, the FPM SAPI was not restarted (sudo systemctl restart php8.3-fpm) or gearman.ini was never symlinked into /etc/php/8.3/fpm/conf.d/. Confirm with ls /etc/php/8.3/fpm/conf.d/ | grep gearman.
pecl install gearman fails with "fatal error: 'libgearman/gearman.h' file not found". libgearman-dev is not installed. Run sudo apt install libgearman-dev and retry.
pecl install gearman fails on PHP 8.4 with ABI errors. PECL ships the latest release, but the package on pecl.php.net may lag a new PHP minor. If you hit a build error specifically on 8.4 around zend_object layout or ZEND_API, check the upstream issue tracker for a patched version, or use the php-gearman-extension HEAD: sudo pecl install gearman-channel://pecl.php.net/gearman-2.1.0 (substitute the latest stable). When in doubt, drop back to apt and a PHP version that has a prebuilt package.
"Could not connect to 127.0.0.1:4730". gearmand is not running or not listening on the loopback. Run sudo systemctl status gearmand and ss -ltnp | grep 4730. If the service is up but on a different interface, edit /etc/default/gearmand to set PARAMS="--listen=127.0.0.1" and restart.
Workers connect but never get jobs. Function names must match exactly between client and worker. addFunction('reverse', ...) on the worker only matches doNormal('reverse', ...) on the client, 'Reverse' or 'reverse_string' will silently never fire. Log both sides while debugging.
Jobs vanish after a gearmand restart. The default queue is in-memory. Enable persistence with --queue-type=libsqlite3 --libsqlite3-db=/var/lib/gearmand/queue.db in /etc/default/gearmand and create the directory if needed.
What to do next
- How to Increase PHP Memory Limit, Gearman workers that process large payloads (image jobs, PDF rendering) usually hit
memory_limitbefore they hit anything else. Bump it per-SAPI. - Bash For Loops: Syntax, Examples, and One-Liners, handy for batch-enqueueing test jobs from a shell loop while you tune worker concurrency.
- Bash While Loops, useful when you want a tiny health-check loop that pokes
gearmanduntil it responds during a deploy. - How to Export All MySQL Databases, if you back your workers with a MySQL job log, the same
mysqldumppatterns apply to backing up the queue state. - Increase Google Cloud VM Disk Size Without Rebooting, relevant if your gearmand box is on GCP and the SQLite queue file outgrew the volume.





