DEV Community

Ramananda Panda
Ramananda Panda

Posted on

πŸš€ I Built PQPM β€” A Process Manager That Doesn't Care What Language You Speak

And yes, your PHP queue workers, Go binaries, and Python bots can finally coexist in peace.**


Hero image β€” servers in a data center
Suggested hero image: Unsplash β€” Taylor Vick (Server Room)


The Itch I Couldn't Stop Scratching

If you've ever managed a VPS β€” especially with something like Virtualmin β€” you know the pain. You've got 14 users on a shared server. Dave is running a Laravel queue worker. Sarah has a Go API. And someone named admin3 (who no one remembers creating) is running a rogue Python Discord bot eating 90% of the RAM.

You SSH in. You nohup. You screen. You pray.

PM2? Great tool! ...if your entire universe is Node.js. But the moment you need to babysit a PHP artisan command or a compiled Go binary, PM2 looks at you like you just spoke Klingon.

I needed something that:

  • Let non-root users manage their own processes (without calling me at 2 AM)
  • Was language-agnostic β€” Go, PHP, Python, Rust, a bash script that plays elevator music β€” I don't judge
  • Had real resource limits so one bad actor doesn't nuke the whole server
  • Was dead simple to configure

So I built it. Meet PQPM β€” the Process Queue Process Manager.


Code on a terminal screen
Suggested image: Unsplash β€” Gabriel Heinzer (Terminal/Code)


What Even Is PQPM?

PQPM is a lightweight, system-level process manager written in Go. It runs as a daemon (pqpmd) on your Linux server and lets any user on the system manage their own long-running processes through a simple CLI (pqpm).

Think of it as a bouncer at a nightclub: the daemon has the master key (runs as root), but it immediately drops privileges to match the user who's requesting the action. User A can't touch User B's stuff. Period.

Here's the whole mental model:

  1. The Daemon (pqpmd) β€” runs as root, listens on a Unix socket
  2. The Config (~/.pqpm.toml) β€” each user defines their services in a dead-simple TOML file
  3. The CLI (pqpm) β€” users run commands like pqpm start my-worker with zero sudo required
  4. The Magic β€” the daemon verifies the caller's identity using kernel-level socket credentials (SO_PEERCRED), then spawns the process under that user's UID/GID

No sudo. No chmod 777 hacks. No "just run everything as root and hope for the best."


The Config File is Chef's Kiss 🀌

I'm a sucker for simple config files. XML can leave. YAML can take its "is this a string or a boolean" energy elsewhere. TOML just... makes sense.

Here's what a user's ~/.pqpm.toml looks like:

[service.my-worker]
command = "/usr/bin/php /home/user/public_html/artisan queue:work"
restart = "always"
max_memory = "512MB"
cpu_limit = "20%"

[service.api-server]
command = "/home/user/bin/api-server --port 8080"
restart = "on-failure"
max_memory = "1GB"
cpu_limit = "50%"
working_dir = "/home/user/api"
env = { NODE_ENV = "production", PORT = "8080" }

[service.python-bot]
command = "/usr/bin/python3 /home/user/bots/discord_bot.py"
restart = "always"
max_memory = "256MB"
cpu_limit = "10%"
Enter fullscreen mode Exit fullscreen mode

Three services. Three languages. One config file. Zero drama.


Gopher plush or Go mascot
Suggested image: Unsplash β€” Chinmay B (Gopher) or any Go mascot image from Gopherize.me


Why Go? Because Speed is Non-Negotiable

When your process manager is responsible for keeping other people's services alive, it better not be the thing that dies first.

Go gave me:

  • Goroutines & channels for async, non-blocking process monitoring (each managed process gets its own goroutine β€” beautiful)
  • Static binaries β€” pqpmd and pqpm are single-file executables. No runtime. No dependencies. Just curl, extract, and go
  • First-class syscall support β€” spawning processes, dropping privileges with setuid/setgid, reading SO_PEERCRED from Unix sockets β€” Go's golang.org/x/sys package is a dream
  • Cross-compilation β€” building for amd64 and arm64 in one make command

The entire dependency tree is laughably small: BurntSushi/toml for config parsing, spf13/cobra for the CLI, and golang.org/x/sys for syscalls. That's it. Three dependencies. In 2025. I'll wait while you pick your jaw up off the floor.


Security: The Part I Lost Sleep Over (So You Don't Have To)

This is a process manager that runs as root. Let me say that louder for the people in the back: it runs as root. If the security isn't airtight, you might as well email your SSH keys to a stranger.

Here's how PQPM stays paranoid (in a healthy way):

πŸ” Identity via SO_PEERCRED

When the CLI connects to the daemon over a Unix Domain Socket, the daemon asks the kernel β€” not the user β€” "who is this?" The kernel responds with the UID, GID, and PID. No tokens. No passwords. No trust-me-bro headers. The kernel doesn't lie.

πŸͺ‚ Immediate Privilege Drop

The daemon spawns the process as root but instantly drops to the target user's UID/GID. The spawned process never runs with elevated privileges. Not even for a millisecond... well, maybe a couple of nanoseconds. Go is fast.

🧱 Resource Limits via cgroups

Each process can have hard limits on memory and CPU using Linux cgroups (v2). If Dave's queue worker decides to allocate 16 GB of RAM, cgroups will politely (and firmly) say no.

πŸ“‚ Path Restrictions

Processes are locked to running within the user's authorized directories. No sneaky ../../etc/shadow business.


Lock and shield / cybersecurity
Suggested image: Unsplash β€” FlyD (Neon Lock)


The CLI: Boring On Purpose

I didn't want a CLI that requires a PhD to operate. Six commands. That's your entire vocabulary:

Command What It Does
pqpm start <name> Fire up a service
pqpm stop <name> Gracefully stop it
pqpm restart <name> Stop + start (shocking, I know)
pqpm status See what's running
pqpm log <name> Tail logs for a service
pqpm version Print the version

That's it. No pqpm init --template advanced --with-monitoring --enable-clustering --sacrifice-goat. Just start, stop, restart, status, log, version. Done.


Installation: The One-Linerβ„’

curl -sSL https://raw.githubusercontent.com/pqpm/pqpm/main/install.sh | sudo bash
Enter fullscreen mode Exit fullscreen mode

This detects your architecture, pulls the latest release from GitHub, drops the binaries into /usr/local/bin, creates runtime directories, and sets up the systemd service. The whole thing takes about 5 seconds.

Want to build from source? Also easy:

git clone https://github.com/pqpm/pqpm.git
cd pqpm
make build && sudo make install
Enter fullscreen mode Exit fullscreen mode

Updating? Run the one-liner again. Your managed processes keep running and get "re-adopted" by the daemon once it restarts. Like a responsible parent coming home from the grocery store.


Rocket launch
Suggested image: Unsplash β€” SpaceX (Rocket Launch)


Who Is This For?

  • VPS admins running shared hosting environments (especially Virtualmin/Webmin setups)
  • Small teams where multiple developers deploy services on the same box
  • Anyone tired of PM2 who runs more than just Node.js
  • The sysadmin who wants their users to stop asking for root access to run a queue worker
  • Solo devs running a $5 VPS with a Go API, a PHP backend, and a Python cron job β€” all at once

If you've ever typed nohup something & and then immediately regretted your life choices, PQPM is for you.


What's Next?

PQPM is at v0.2.3 and actively being developed. Here's what's on the roadmap (or at least, living rent-free in my head):

  • πŸ“Š Web dashboard β€” because sometimes you want to click buttons instead of typing commands
  • πŸ”” Notifications β€” get pinged when a process dies (and auto-restarts)
  • πŸ“ˆ Metrics export β€” Prometheus-compatible resource usage stats
  • 🐳 Container-aware mode β€” playing nice with Docker environments
  • πŸ§ͺ More tests β€” always more tests

Open source community / collaboration
Suggested image: Unsplash β€” Annie Spratt (Team collaboration)


Give It a Spin ⭐

PQPM is open-source (MIT licensed) and lives at github.com/pqpm/pqpm.

If it saves you even one sudo argument with a client, one 2 AM SSH session, or one "why is the server at 100% CPU" panic β€” I'll consider it a win.

Star the repo if you dig it. Open an issue if you find a bug. Submit a PR if you're feeling generous. Or just silently use it and never tell me β€” that's cool too. I'll never know. But my download counter will. πŸ‘€


Built with 🐹 Go, β˜• too much coffee, and a burning hatred for nohup.


Image Source Summary

Here's a quick reference for all the suggested images (all free to use via Unsplash):

Section Image Source
Hero / Banner Server room / data center Unsplash β€” Taylor Vick
"What Is PQPM" Terminal with code Unsplash β€” Gabriel Heinzer
"Why Go?" Go gopher / mascot Gopherize.me or Unsplash
Security section Neon lock / cybersecurity Unsplash β€” FlyD
Installation Rocket launch Unsplash β€” SpaceX
Community / CTA Team collaboration Unsplash β€” Annie Spratt

Top comments (0)