PHPackages                             pda/pheanstalk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. pda/pheanstalk

ActiveLibrary[Queues &amp; Workers](/categories/queues)

pda/pheanstalk
==============

PHP client for beanstalkd queue

v8.0.2(7mo ago)1.9k32.4M↓24.3%281[6 issues](https://github.com/pheanstalk/pheanstalk/issues)[1 PRs](https://github.com/pheanstalk/pheanstalk/pulls)20MITPHPPHP &gt;=8.3.0CI passing

Since Feb 28Pushed 3mo ago87 watchersCompare

[ Source](https://github.com/pheanstalk/pheanstalk)[ Packagist](https://packagist.org/packages/pda/pheanstalk)[ Docs](https://github.com/pheanstalk/pheanstalk)[ RSS](/packages/pda-pheanstalk/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)Dependencies (8)Versions (52)Used By (20)

Pheanstalk
==========

[](#pheanstalk)

[![Latest Stable Version](https://camo.githubusercontent.com/f6bcb8b3347615faeb521a0c8cf812051eb39f28ffaf54bad46b54dbbed7c63f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7064612f706865616e7374616c6b2e737667)](https://packagist.org/packages/pda/pheanstalk)[![Total Downloads](https://camo.githubusercontent.com/6e5d80e7845fbbac9cbae42c66e30a1e127eca776b7c608d2b56885f6b6982ee/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7064612f706865616e7374616c6b2e737667)](https://packagist.org/pda/pheanstalk)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/56e7da4d65763972e2dad942f4e6487eecd8975b785dbbe1b7844182c94167db/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f706865616e7374616c6b2f706865616e7374616c6b2f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/pheanstalk/pheanstalk/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/ecde388fb364a9a84e850328790063aa999c193280373d4bcde78e9da965d9cf/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f706865616e7374616c6b2f706865616e7374616c6b2f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/pheanstalk/pheanstalk/?branch=master)[![Build Status](https://camo.githubusercontent.com/74b1a542a9d70a2d73890aa96ffe6fe9bba8794003a5e72506816dce53c8c108/68747470733a2f2f7472617669732d63692e6f72672f706865616e7374616c6b2f706865616e7374616c6b2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/pheanstalk/pheanstalk)

Pheanstalk 5 is a pure PHP8.1+ client for use with [beanstalkd workqueue](https://beanstalkd.github.io/) versions 1.12 and later. In 2021 / 2022 / 2023 it was almost completely rewritten from scratch with the following goals in mind:

- Fully typed
- Passing the strict rule set for static analysis using PHPStan and Psalm
- Splitting the different roles into separate parts

Usage Example
-------------

[](#usage-example)

#### Producer

[](#producer)

```
use Pheanstalk\Pheanstalk;
use Pheanstalk\Values\TubeName;

$pheanstalk = Pheanstalk::create('127.0.0.1');
$tube       = new TubeName('testtube');

// Queue a Job
$pheanstalk->useTube($tube);
$pheanstalk->put("job payload goes here\n");

$pheanstalk->useTube($tube);
$pheanstalk->put(
    data: json_encode(['test' => 'data'], JSON_THROW_ON_ERROR),
    priority: Pheanstalk::DEFAULT_PRIORITY,
    delay: 30,
    timeToRelease: 60
);
```

#### Consumer / Worker

[](#consumer--worker)

```
use Pheanstalk\Pheanstalk;
use Pheanstalk\Values\TubeName;

$pheanstalk = Pheanstalk::create('127.0.0.1');
$tube       = new TubeName('testtube');

// we want jobs from 'testtube' only.
$pheanstalk->watch($tube);

// this hangs until a Job is produced.
$job = $pheanstalk->reserve();

try {
    $jobPayload = $job->getData();
    // do work.

    echo "Starting job with payload: {$jobPayload}\n";

    sleep(2);
    // If it's going to take a long time, periodically
    // tell beanstalk we're alive to stop it rescheduling the job.
    $pheanstalk->touch($job);
    sleep(2);

    // eventually we're done, delete job.
    $pheanstalk->delete($job);
}
catch(\Exception $e) {
    // handle exception.
    // and let some other worker retry.
    $pheanstalk->release($job);
}
```

#### Systemd configuration for Consumer / Worker

[](#systemd-configuration-for-consumer--worker)

Note that this does not aim to cover all possible scenarios or configurations.

```
[Unit]
Description=My App Worker

[Service]
User=deployer
Group=www-data
Restart=always
ExecStart=/usr/bin/php /var/www/html/worker.php

[Install]
WantedBy=multi-user.target

```

Running the tests
-----------------

[](#running-the-tests)

Make sure you have docker-compose installed.

```
> composer test
```

History
=======

[](#history)

Pheanstalk 5
------------

[](#pheanstalk-5)

### Migration to v5

[](#migration-to-v5)

Some breaking/important changes:

- no more chaining of `->watch->ignore->reserve/reserveWithTimeout`: each call should be made on its own
- use of `new TubeName()` instead of strings for tube names
- some constants from `PheanstalkInterface` have been moved to other interfaces:
    - `DEFAULT_PORT` to `SocketFactoryInterface`,
    - `DEFAULT_DELAY/DEFAULT_PRIORITY/DEFAULT_TTR` to `PheanstalkPublisherInterface`
- `put` method 4th parameter name changed from `ttr` to `timeToRelease`

Pheanstalk 4
------------

[](#pheanstalk-4)

In 2018 [Sam Mousa](https://github.com/sammousa) took on the responsibility of maintaining Pheanstalk.

Pheanstalk 4.0 drops support for older PHP versions. It contains the following changes (among other things):

- Strict PHP type hinting
- Value objects for Job IDs
- Functions without side effects
- Dropped support for persistent connections
- Add support for multiple socket implementations (streams extension, socket extension, fsockopen)

### Dropping support persistent connections

[](#dropping-support-persistent-connections)

Persistent connections are a feature where a TCP connection is kept alive between different requests to reduce overhead from TCP connection set up. When reusing TCP connections we must always guarantee that the application protocol, in this case beanstalks' protocol is in a proper state. This is hard, and in some cases impossible; at the very least this means we must do some tests which cause roundtrips. Consider for example a connection that has just sent the command `PUT 0 4000`. The beanstalk server is now going to read 4000 bytes, but if the PHP script crashes during this write the next request get assigned this TCP socket. Now to reset the connection to a known state it used to subscribe to the default tube: `use default`. Since the beanstalk server is expecting 4000 bytes, it will just write this command to the job and wait for more bytes..

To prevent these kinds of issues the simplest solution is to not use persistent connections.

### Dropped connection handling

[](#dropped-connection-handling)

Depending on the socket implementation used we might not be able to enable TCP keepalive. If we do not have TCP keepalive there is no way for us to detect dropped connections, the underlying OS may wait up to 15 minutes to decide that a TCP connection where no packets are being sent is disconnected. When using a socket implementation that supports read timeouts, like `SocketSocket` which uses the socket extension we use read and write timeouts to detect broken connections; the issue with the beanstalk protocol is that it allows for no packets to be sent for extended periods of time. Solutions are to either catch these connection exceptions and reconnect or use `reserveWithTimeout()` with a timeout that is less than the read / write timeouts.

Example code for a job runner could look like this (this is real production code):

```
use Pheanstalk\Pheanstalk;
use Pheanstalk\Values\TubeName;

interface Task {

}
interface TaskFactory {
    public function fromData(string $data): Task;
}
interface CommandBus {
    public function handle(Task $task): void;
}

function run(\Pheanstalk\PheanstalkSubscriber $pheanstalk, CommandBus $commandBus, TaskFactory $taskFactory): void
{
    /**
     * @phpstan-ignore-next-line
     */
    while (true) {
        $job = $pheanstalk->reserveWithTimeout(50);
        if (isset($job)) {
            try {

                $task = $taskFactory->fromData($job->getData());
                $commandBus->handle($task);
                echo "Deleting job: {$job->getId()}\n";
                $pheanstalk->delete($job);
            } catch (\Throwable $t) {
                echo "Burying job: {$job->getId()}\n";
                $pheanstalk->bury($job);
            }
        }
    }
}
```

Here connection errors will cause the process to exit (and be restarted by a task manager).

### Functions with side effects

[](#functions-with-side-effects)

In version 4 functions with side effects have been removed, functions like `putInTube` internally did several things:

1. Switch to the tube
2. Put the job in the new tube

In this example, the tube changes meaning that the connection is now in a different state. This is not intuitive and forces any user of the connection to always switch / check the current tube. Another issue with this approach is that it is harder to deal with errors. If an exception occurs it is unclear whether we did or did not switch tube.

### Migration to v4

[](#migration-to-v4)

A migration should in most cases be relatively simple:

- Change the constructor, either use the static constructor, use a DI container to construct the dependencies, or manually instantiate them.
- Change instances of `reserve()` with a timeout to `reserveWithTimeout(int $timeout)` since `reserve()` no longer accepts a `timeout` parameter.
- Run your tests, or use a static analyzer to test for calls to functions that no longer exist.
- Make sure that you handle connection exceptions (this is not new to V4, only in V4 you will get more of them due to the default usage of a socket implementation that has read / write timeouts).

Pheanstalk 3
------------

[](#pheanstalk-3)

Pheanstalk is a pure PHP 7.1+ client for the [beanstalkd workqueue](https://beanstalkd.github.io/). It has been actively developed, and used in production by many, since late 2008.

Created by [Paul Annesley](https://paul.annesley.cc/), Pheanstalk is rigorously unit tested and written using encapsulated, maintainable object oriented design. Community feedback, bug reports and patches has led to a stable 1.0 release in 2010, a 2.0 release in 2013, and a 3.0 release in 2014.

Pheanstalk 3.0 introduces PHP namespaces, PSR-1 and PSR-2 coding standards, and PSR-4 autoloader standard.

beanstalkd up to the latest version 1.10 is supported. All commands and responses specified in the [protocol documentation](https://github.com/kr/beanstalkd/tree/v1.3/doc/protocol.txt?raw=true) for beanstalkd 1.3 are implemented.

###  Health Score

77

—

ExcellentBetter than 100% of packages

Maintenance74

Regular maintenance activity

Popularity76

Solid adoption and visibility

Community58

Growing community involvement

Maturity91

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~96 days

Recently: every ~27 days

Total

49

Last Release

210d ago

Major Versions

v4.0.5 → v5.0.32024-01-19

v5.0.9 → v6.0.02025-01-02

v5.0.10 → v6.0.22025-03-13

v5.1.0 → v7.0.02025-03-20

v7.1.1 → v8.0.02025-10-06

PHP version history (4 changes)v2.0.0-rc1PHP &gt;=5.3.0

v4.0.0-alpha.1PHP &gt;=7.1.0

v5.0.0-alpha1PHP &gt;=8.1.0

v6.0.0PHP &gt;=8.3.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/18b13c534e3812b66a72645fe215301b54fc4d288f6396fee9385b681e27da18?d=identicon)[SamMousa](/maintainers/SamMousa)

![](https://www.gravatar.com/avatar/6002a108a76ce2d86c8ad10e4e1026270fd4a2cf1c3938402b73c3e6091bc701?d=identicon)[jnankin](/maintainers/jnankin)

![](https://www.gravatar.com/avatar/f3f55731e64b321b6e0e3bedda0aba190aede354b46901c386a47ee1a2d58acb?d=identicon)[pda](/maintainers/pda)

---

Top Contributors

[![SamMousa](https://avatars.githubusercontent.com/u/547021?v=4)](https://github.com/SamMousa "SamMousa (195 commits)")[![pda](https://avatars.githubusercontent.com/u/15759?v=4)](https://github.com/pda "pda (145 commits)")[![DavidGoodwin](https://avatars.githubusercontent.com/u/203929?v=4)](https://github.com/DavidGoodwin "DavidGoodwin (21 commits)")[![phansys](https://avatars.githubusercontent.com/u/1231441?v=4)](https://github.com/phansys "phansys (18 commits)")[![GrahamCampbell](https://avatars.githubusercontent.com/u/2829600?v=4)](https://github.com/GrahamCampbell "GrahamCampbell (10 commits)")[![v-mirchev](https://avatars.githubusercontent.com/u/6339587?v=4)](https://github.com/v-mirchev "v-mirchev (6 commits)")[![SplotyCode](https://avatars.githubusercontent.com/u/31861387?v=4)](https://github.com/SplotyCode "SplotyCode (6 commits)")[![armetiz](https://avatars.githubusercontent.com/u/1119250?v=4)](https://github.com/armetiz "armetiz (5 commits)")[![mnapoli](https://avatars.githubusercontent.com/u/720328?v=4)](https://github.com/mnapoli "mnapoli (3 commits)")[![gcatlin](https://avatars.githubusercontent.com/u/211427?v=4)](https://github.com/gcatlin "gcatlin (3 commits)")[![jbboehr](https://avatars.githubusercontent.com/u/225601?v=4)](https://github.com/jbboehr "jbboehr (2 commits)")[![rbruhn](https://avatars.githubusercontent.com/u/1283141?v=4)](https://github.com/rbruhn "rbruhn (2 commits)")[![leprechaun](https://avatars.githubusercontent.com/u/355637?v=4)](https://github.com/leprechaun "leprechaun (2 commits)")[![ljfreelancer88](https://avatars.githubusercontent.com/u/7919039?v=4)](https://github.com/ljfreelancer88 "ljfreelancer88 (2 commits)")[![TimWolla](https://avatars.githubusercontent.com/u/209270?v=4)](https://github.com/TimWolla "TimWolla (2 commits)")[![HypeMC](https://avatars.githubusercontent.com/u/2445045?v=4)](https://github.com/HypeMC "HypeMC (2 commits)")[![jimbojsb](https://avatars.githubusercontent.com/u/107836?v=4)](https://github.com/jimbojsb "jimbojsb (2 commits)")[![vstm](https://avatars.githubusercontent.com/u/1871866?v=4)](https://github.com/vstm "vstm (1 commits)")[![crynobone](https://avatars.githubusercontent.com/u/172966?v=4)](https://github.com/crynobone "crynobone (1 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

beanstalkd

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StyleECS

Type Coverage Yes

### Embed Badge

![Health badge](/badges/pda-pheanstalk/health.svg)

```
[![Health](https://phpackages.com/badges/pda-pheanstalk/health.svg)](https://phpackages.com/packages/pda-pheanstalk)
```

###  Alternatives

[leezy/pheanstalk-bundle

The LeezyPheanstalkBundle is a Symfony Bundle that provides a command line interface for manage the Beanstalkd workqueue server &amp; a pheanstalk integration.

1261.8M7](/packages/leezy-pheanstalk-bundle)[davidpersson/beanstalk

Minimalistic PHP client for beanstalkd.

199327.9k8](/packages/davidpersson-beanstalk)[udokmeci/yii2-beanstalk

Yii2 Beanstalk Client at the top of Paul Annesley's pheanstalk

70129.0k3](/packages/udokmeci-yii2-beanstalk)[foxxmd/laravel-elasticbeanstalk-queue-worker

Deploy your Laravel application as a queue worker on AWS ElasticBeanstalk

5494.9k](/packages/foxxmd-laravel-elasticbeanstalk-queue-worker)[xobotyi/beansclient

PHP7.1+ client for beanstalkd work queue with no dependencies

9227.3k](/packages/xobotyi-beansclient)[pmatseykanets/artisan-beans

Easily manage your Beanstalkd job queues right from the Laravel artisan command

4482.3k](/packages/pmatseykanets-artisan-beans)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
