Architecture
How PulseBoard works
PulseBoard runs on classic Swiss shared hosting: PHP rendered per request, one SQLite database, a scheduled worker and plain HTTP. No Node server, no Redis, no sockets. That choice keeps it cheap, robust and boring in the best sense. Here’s what each piece does and what it replaced in our first plan.
What changed from the first plan, and why
| First plan | What runs today | What it means for users |
|---|---|---|
| Next.js / Express server with SSR | PHP renders every page per request; the dashboard hydrates with a small vanilla JS file | Same first paint with real content; no build server, no cold starts |
| Redis-backed job queue (BullMQ) | A jobs table in SQLite; cron starts a worker every minute that works ~57 s, one job at a time, with retries and back-off | Jobs usually start within 1–5 s instead of instantly. Nothing lost if a worker dies: stuck jobs are re-queued after 5 minutes |
| WebSocket live counter | Short polling every 3 s with ETags; “304 Not Modified” when nothing changed; paused in hidden tabs | Updates arrive in ≤ 3 s instead of ~100 ms. For a team dashboard that’s indistinguishable in practice |
git push to a PaaS | git push to a repository on the hosting; a hook checks out the new version into place. Data in var/ is never touched by Git | Same workflow, deploys in seconds, database survives every deploy |
| Managed Postgres / Redis add-ons | One SQLite file with WAL mode, nightly consistent backup via VACUUM INTO, 7 copies kept | No extra monthly bills; one file to back up or move |
Honest limits
- Latency: “live” means within about three seconds. Sub-second push would need WebSockets, which we would add later through a hosted service (e.g. Ably or Pusher) or a managed server with WebSockets enabled, without changing the rest.
- Throughput: SQLite lets one writer at a time in. Writes here take well under a millisecond, which is plenty for hundreds of active teams. If we outgrow it, the queries move to MariaDB with little change.
- Job start time: the worker is started by cron, so a job queued right after a run ends may wait a few seconds. Long jobs are split so each run finishes inside its minute.
Security basics
- HTTPS everywhere, secure and HTTP-only session cookies, CSRF tokens on every form.
- Passwords hashed with bcrypt; API tokens stored only as SHA-256 hashes.
- Rate limits on sign-in, sign-up, API calls and job queueing.
- The database, logs and backups live outside the public web folder.