Skip to content

Metrics broken when using custom serialization/compression on PhpRedis database connection #1462

@dir

Description

@dir

Horizon Version

5.24.5

Laravel Version

11.7.0

PHP Version

8.3

Redis Driver

PhpRedis

Redis Version

6.0.2

Database Driver & Version

No response

Description

I recently integrated Laravel Horizon as a dedicated worker service for a horizontally scaled Laravel API.

It has been wonderful, but when I click on the metrics tab, it loads infinitely. After looking at the logs, I get the following error message on a variety of Horizon endpoints.

GET 500 http://example.com/
[msgpack] (php_msgpack_unserialize) Extra bytes

I suspect this is because I am using custom PHPRedis serializer and compression options in my config/database.php, like so:

'redis' => [
  'options' => array_merge(
    [
      'persistent' => true,
    ],
    env('REDIS_CLIENT', 'phpredis') === 'phpredis' ? [
      'serializer' => Redis::SERIALIZER_MSGPACK,
      'compression' => Redis::COMPRESSION_LZ4,
    ]: []
  ),
  
  'default' => [
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_PRIMARY_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => 0,
  ],
],

I am also ensured to schedule the horizon:snapshot command every five minutes in my routes/console.php file, and have confirmed it is running:

<?php

use Illuminate\Support\Facades\Schedule;

Schedule::command('horizon:snapshot')->everyFiveMinutes();

Another odd note is that Horizon seems to run the jobs fine, and the outputs for failed/completed/etc jobs is working perfectly. Mainly seems to be the metrics.

Steps To Reproduce

To reproduce, I have provided the bare minimum configuration to replicate:

config/database.php Redis configuration:

'redis' => [
        'client' => env('REDIS_CLIENT', 'phpredis'),

        'options' => array_merge(
            [
                'persistent' => true,
            ],
            env('REDIS_CLIENT', 'phpredis') === 'phpredis' ? [
                    'serializer' => Redis::SERIALIZER_MSGPACK,
                    'compression' => Redis::COMPRESSION_LZ4,
                ]: []
        ),

        'default' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_PRIMARY_HOST', '127.0.0.1'),
            'username' => env('REDIS_USERNAME'),
            'password' => env('REDIS_PASSWORD'),
            'port' => env('REDIS_PORT', '6379'),
            'database' => 0,
        ],
]

config/queue.php

    'connections' => [
        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'default',
            'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 3610),
            'block_for' => 1,
            'after_commit' => false,
        ],
    ],

config/cache.php

    'stores' => [
        'redis' => [
            'driver' => 'redis',
            'connection' => 'cache_write',
            'lock_connection' => 'default',
        ],
    ],

config/horizon.php

    'use' => 'default',
    'prefix' => 'horizon:',

routes/console.php

<?php

use Illuminate\Support\Facades\Schedule;

Schedule::command('horizon:snapshot')->everyFiveMinutes();

If anything else is needed on the replication-side, please let me know!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions