A web admin panel for Pinba — a MySQL storage engine that collects real-time performance statistics from PHP applications.
Pinba was originally developed by @tony2001 for MySQL ≤ 5.6 and is no longer maintained. This project ships with the @XOlegator/pinba_engine fork, which adds MySQL 8.0 and 8.4 support. Pinboard itself is agnostic to which engine build you use.
Pinba is a system for passive performance monitoring of PHP sites:
- PHP extension (
pinba) — embedded in each PHP process, collects request timing, memory usage, CPU time, and custom timer groups. Sends a UDP packet to a Pinba server at the end of every request. - Pinba MySQL engine (
pinba_engine) — a MySQL plugin that receives those UDP packets and stores them as virtual tables. Acts as the "server" that listens on UDP port 30002. - Pinboard (this project) — a Symfony web app that reads data from the Pinba MySQL engine, aggregates it on a 15-minute schedule, and displays dashboards with request-time histograms, memory usage graphs, error rates, and slow-request logs.
PHP app ──UDP──▶ MySQL + pinba_engine ──SQL──▶ Pinboard web UI
(pinba ext) (collects stats) (aggregates & shows)
The fastest way to run the full stack. No build step needed.
Prerequisites: Docker Engine + Docker Compose v2.
# 1. Copy the example env file and fill in the required values
cp .env.public.example .env
# Edit .env — set APP_SECRET (openssl rand -hex 32) and passwords
nano .env
# 2. Start the stack
docker compose -f docker-compose.public.yml up -d
# 3. Create the first admin user (run once)
docker exec pinboard-web php bin/console add-user admin@example.com yourpassword ROLE_ADMINOpen http://localhost:8080 (or PINBOARD_HTTP_PORT from your .env).
Add to your PHP configuration (php.ini or pool config):
pinba.enabled = 1
pinba.server = <docker-host-ip>:30002
; use PINBA_UDP_PORT from .env if you changed it from the defaultRestart PHP-FPM and make a few requests on your site.
When will data appear?
Pinboard aggregates raw Pinba data on a 15-minute schedule. There is a two-stage warm-up:
Time after first request What becomes visible ~15 min (1 aggregation) Server appears on the main dashboard ( /) with basic request stats~2.5 h (10 aggregations) Server appears in the navigation menu on the left The navigation menu requires at least 10 aggregation cycles to filter out one-off or test traffic. To see data immediately without waiting, trigger aggregation manually:
docker exec pinboard-aggregate php bin/console aggregateEven after a manual run the navigation menu will remain empty until 10 cycles have accumulated. Use the main dashboard link directly in the meantime.
| Image | Description |
|---|---|
xolegator/pinba-engine:8.4-lts |
MySQL 8.4 LTS with Pinba storage engine plugin |
xolegator/pinboard:latest |
Pinboard web UI + aggregate worker |
The MySQL image bundles the XOlegator/pinba_engine plugin — a fork of the original tony2001/pinba_engine with MySQL 8.0/8.4 support added.
For local development without Docker.
Requirements: PHP ≥ 8.5, MySQL 8.x with pinba_engine plugin, Node.js ≥ 22, pnpm ≥ 9.
# PHP dependencies
composer install
# Frontend dependencies and build
pnpm install
pnpm build
# App configuration
cp .env .env.local
# Edit .env.local — set DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
# Database migrations
php bin/console doctrine:migrations:migrate
# Create first user
php bin/console add-user admin@example.com yourpassword ROLE_ADMIN
# Start a web server (e.g. Symfony CLI or nginx + php-fpm)
symfony serveFor development with Docker, using source-mounted volumes and Xdebug support:
# Start dev stack (MySQL 8.4 LTS by default)
make up
# Or explicitly choose MySQL version:
make up84 # MySQL 8.4 LTS (same as default)
make up80 # MySQL 8.0 (for compatibility testing)
# Run migrations and create a user
make db_migrate
docker compose --env-file ./docker/.env -f ./docker/docker-compose.yml \
exec -u www-data php-fpm php bin/console add-user admin@example.com yourpassword ROLE_ADMINSee docs/docker.md for full details on both the dev stack and the public image stack.
| Command | Description |
|---|---|
php bin/console aggregate |
Run the aggregation pipeline (normally runs via cron every 15 min) |
php bin/console add-user <email> <password> [ROLE] [hosts_regexp] |
Create or update a user |
php bin/console users:migrate-file-to-db |
Migrate users from file-based auth to DB |
php bin/console users:migrate-db-to-file |
Migrate users from DB auth to file |
php bin/console register-crontab |
Print a crontab entry for the aggregation job |
Key environment variables (set in .env.local or as Docker env):
| Variable | Default | Description |
|---|---|---|
DB_HOST |
127.0.0.1 |
MySQL host |
DB_PORT |
3306 |
MySQL port |
DB_NAME |
pinba |
Database name |
DB_USER |
— | Database user |
DB_PASSWORD |
— | Database password |
DB_SERVER_VERSION |
8.4.0 |
MySQL server version (for Doctrine) |
APP_AUTH_USER_SOURCE |
file |
User storage: file or db |
APP_RECORDS_LIFETIME |
P1M |
How long to keep raw data (ISO 8601 duration) |
APP_AGGREGATION_PERIOD |
PT15M |
Aggregation window size |
APP_LOGGING_LONG_REQUEST_TIME_GLOBAL |
1.5 |
Slow request threshold (seconds) |
APP_NOTIFICATION_ENABLE |
0 |
Enable email notifications |
Full variable reference: docs/configuration.md
- XOlegator/pinba_engine — MySQL 8.0/8.4 port of the Pinba storage engine (fork of the original tony2001/pinba_engine, which supported MySQL ≤ 5.6 and is no longer maintained).
- PHP Pinba extension — the PHP extension that sends UDP packets. Available for PHP 7/8 via PECL or package managers.
- Configuration reference
- Docker: quick-start & dev stack
- Deployment & operations
- Testing
- Code standards
If you have an existing Pinboard 1.x (Silex-based) installation:
- Back up the database.
- Check out this branch / the new release.
- Run
composer install && pnpm install && pnpm build. - Copy your old
config/parameters.yml— file-based auth settings are preserved. - Run
php bin/console doctrine:migrations:migrate.
See docs/deployment.md for the full upgrade guide.
MIT — see LICENSE.
