Skip to content

Technical FAQ

This FAQ gathers the most common questions that instructors and students ask about PerfShop. The answers are deliberately concise and point to reference pages for details.

License

How do I activate a PerfShop license?

Two possible paths:

  • Via .env — add PERFSHOP_LICENSE_KEY=PFSH-xxx.yyy to your .env file then restart the stack with docker compose restart perfshop-app. The license is loaded at startup by LicenseService.
  • Via the interface — open the chaos-admin panel (gestion.html page accessible to the superadmin), paste the key into the dedicated field of the license panel, and click Activate.

See License system.

Why is license activation public?

The POST /api/license/activate and POST /api/license/revoke endpoints are intentionally accessible without authentication. Without that, we would have a deadlock: with no active license, all admin endpoints return 402, so there would be no way to log in to activate the license.

Security is ensured by the RSA-PSS 2048 cryptographic verification of the key — an attacker cannot forge a valid license without access to the private key, which stays on perfshop.io.

What happens when my license expires?

Verification is instantaneous on every request. Starting the day after the expiration date (expiresAt), all calls to protected endpoints return HTTP 402 Payment Required. The shop, the student page and the HTML monitoring stay accessible. Historical Grafana dashboards remain viewable.

To extend, activate a new key via POST /api/license/activate — no restart needed.

Can I use PerfShop for free?

Yes, partially. The shop, the student page, the monitoring dashboard and the BAC1/BAC2 pedagogical journey are accessible without a license. Freemium Performance Chaos (level 1) and Chaos Scripting level 1 (Junior) are too. See Freemium vs Pro for the exact boundary.

You can also grab the source code and run it locally under AGPL-3.0-or-later — but that open source license requires you to publish your own modifications if you expose a modified instance in production. See License.

Pedagogical journey

How do I reset a pedagogical journey in progress?

From the instructor panel (chaos-admin/public/admin/), Pedagogical tab, click the Global reset button. This calls POST /api/chaos/pedagogique/reset which wipes all active sessions and sets current_step = 0 for every student.

To reset a single student, ask them to clear their localStorage.ped_student_token — on the next poll, the backend will create a new session via /join.

How do I enable or disable hints during a journey?

The instructor can toggle hints at any time via POST /pedagogique/hints { enabled: true|false } from the Pedagogical panel. The state is propagated to students on the next poll (/status every 15 seconds), and the "Hint" button of the pedagogical overlay appears or disappears accordingly.

The flag is stored in a volatile boolean pedagogiqueHintsEnabled on the backend side — see Hints and progression.

What should I do if a student is stuck on an enigma?

Three levers:

  1. Enable hints — if not already done (see above)
  2. Consult the cultural note — displayed after validation, but the instructor can read it from the i18n/enigmes/bacN/enigmes_fr.json files
  3. Targeted reset — ask the student to refresh their token to start over

See Enigma internationalization for the file format.

What happens if I exceed 500 concurrent pedagogical sessions?

The backend does not enforce a hard limit. The pedagogique_sessions table has no volume constraint and the optional memory cache is sized to absorb several thousand sessions. The /status polls (15-second interval) generate a reasonable load even at large scale.

As a rough guide, an average Docker Desktop instance handles ~200 concurrent sessions without breaking a sweat. Beyond that, monitor the backend JVM heap through Grafana or the HTML monitoring dashboard, and adjust -Xmx if necessary.

Administration

How do I add an admin account?

Log in as superadmin on chaos-admin, navigate to Management → Create account, enter the email, the password (min 6 characters) and check the desired rights (chaos-admin, monitoring, backoffice, jmeter, scripts), then click Create.

Only the superadmin sees this form. See Admin authentication.

How do I reset the admin password?

Two options:

  • Via .env — change ADMIN_PASSWORD=new-password then restart perfshop-app. The bootstrap detects that the stored hash no longer matches and updates the database automatically.
  • Via the My Account page — log in with the old password, open mon-compte.html, enter the new password twice, submit.

How do I change the language of the stack?

Change PERFSHOP_LANG=fr|en in your .env then restart everything:

docker compose down
docker compose up -d

The variable is propagated to all services (backend, frontend, chaos-admin, monitoring, welcome, scripts-ui, jmeter-ui). See i18n overview.

Chaos engineering

How do I view the logs of a running chaos?

Several complementary paths:

  • Grafana → Explore → Loki — filter by container="perfshop-app" and search for the chaos family prefix ([chaos.business], [chaos.security]…)
  • Grafana "Chaos Dashboard" — real-time tables per family, provisioned by default
  • HTML monitoring — simplified real-time counters (see Student monitoring)
  • chaos-admin panel — per-family counters (biz-counters-label, sec-hits-label, fn-counters-label) displayed at the top of each section

See Observability.

How do I know which chaos is currently active?

Call GET /api/chaos/student/status (no authentication required) — the response contains an object per family with the active level:

{
  "performance": { "active": "N2-03", "level": 2 },
  "scripting":   { "level": 1, "maxLevel": 4 },
  "business":    { "level": 0, "maxLevel": 4 },
  "functional":  { "level": 0, "maxLevel": 4 },
  "security":    { "level": 0, "maxLevel": 4 },
  "pedagogique": { "level": "bac1", "active": true }
}

The chaos-admin panel consumes this endpoint every 5 seconds and shows the state on screen.

Why does the 402 code appear on certain chaos?

The HTTP 402 Payment Required code is returned by LicenseInterceptor when you try to access a chaos or an interface that requires an active license which your instance does not have. The X-License-Required: true header confirms that it's a license block and not another error.

See Freemium vs Pro for the list of chaos and interfaces affected.

Can I enable several performance chaos at the same time?

No. The golden rule of student-side Performance Chaos is "only one scenario active at a time". Enabling a new scenario automatically disables the previous one — this is handled by PerformanceScenario.resetAll() on the backend side.

The 20 weather-themed scenarios N1-01 to N4-05 already combine several backend chaos in a single preset (for example CPU + thread pool + slow queries), so you can obtain complex configurations without manually stacking. See Weather scenarios.

On the instructor panel side, a Reset all button resets every family to zero in a single operation.

Deployment

How do I restart the stack after a NAS reboot?

If your Docker has automatic restart enabled (restart: unless-stopped in the compose — which is the default), the stack restarts on its own with the NAS. Otherwise:

cd /path/to/perfshop
docker compose up -d

The persistent volumes (MySQL database, Grafana, Loki, Tempo, Pyroscope, OpenSearch, Squash, Forgejo) are preserved between restarts. See Launching Docker Compose.

My port 9080 is already in use, how do I change the backend port?

Change BACKEND_HTTP_PORT=9090 in .env (or any other free port) and restart perfshop-app. Remember to also update PUBLIC_API_URL=http://localhost:9090 so the frontend points at the new port.

See the environment variables reference for the full list of configurable ports.

How do I expose PerfShop on a domain with HTTPS?

Use the dns mode of the welcome page and an HTTPS reverse proxy (Nginx, Caddy, Traefik) in front of the stack:

  1. Set WELCOME_MODE=dns in .env
  2. Fill all PUBLIC_*_URL with your real HTTPS subdomains
  3. Configure your reverse proxy to route each subdomain to the corresponding internal port
  4. Set SESSION_COOKIE_SECURE=true to secure the cookies
  5. Change the default passwords (ADMIN_PASSWORD, DB_PASSWORD, GF_SECURITY_ADMIN_PASSWORD, OPENSEARCH_ADMIN_PASSWORD…)

See Deployment topology.

Does PerfShop collect usage data?

No. PerfShop makes no outgoing calls to perfshop.io or any third-party server at startup or during operation. The instance you deploy is fully autonomous: no version, no hostname, no IP, no instance UUID is sent outside. The only outgoing network traffic comes from your own actions (opening the official documentation in your browser, activating a license via copy-paste).

See the license for the full privacy commitment.

Development

Can I contribute to PerfShop?

Yes, under AGPL-3.0-or-later. Fork the Forgejo repository, create a feature/... branch, commit your changes, push and open a Pull Request. See Forgejo Git workflow.

Contributions must respect the "commercial production" quality level: no pseudo-code, no TODOs, up-to-date tests, FR/EN symmetry maintained, documentation kept in sync.

My Maven build fails — what should I check?

Common causes:

  • Java 21 not availablejava -version must display 21.x
  • Maven too old — Maven 3.9+ is required
  • Internet connection — Maven must download dependencies on first build
  • Failing tests — use mvn package -DskipTests in dev to isolate the issue

See Prerequisites and Build backend.

My Vite build shows CORS warnings — what should I do?

In npm run dev mode, the Vite dev server runs on port 5173 and the backend on port 8080 (or 9080 in container). These two origins are different to the browser, so CORS applies.

Two options:

  1. Add http://localhost:5173 to CORS_ALLOWED_ORIGINS on the backend side, then restart the backend
  2. Configure a Vite proxy in vite.config.js that routes /api/* to http://localhost:8080

See Build frontend.

Data and database

How do I import additional test data?

Add a V11__my_test_data.sql file into backend/src/main/resources/db/migration-fr/ and restart the backend. Flyway will detect the new migration and run it automatically.

Warning — never modify the existing V1 to V10 migrations. Flyway rejects migrations that have been altered after application and refuses to start. See Database schema.

How do I start from an empty database?

docker compose down -v
docker compose up -d

The -v option deletes the Docker volumes, including mysql-data. On the next startup, Flyway replays every V1-V10 migration on the empty database and AdminUserService recreates the superadmin. All past orders, pedagogical sessions and license activations are lost.

How do I query the MySQL database directly?

docker exec -it perfshop-db mysql -u perfshop -p perfshop

Enter the DB_PASSWORD from your .env. You land in a MySQL shell where you can run SELECT queries against every table.

For common read queries (stats, debug), you can also go through Grafana → Explore pointing at the preconfigured MySQL datasource.

Observability

Grafana shows "No data" on some panels — what should I check?

In order:

  1. Is Prometheus up? — open http://localhost:9092/targets and check that all targets are UP
  2. Does the backend expose /actuator/prometheus? — test with curl http://localhost:9080/actuator/prometheus | head
  3. Does the Grafana time range include the present? — the top-right selector should be on "Last 15 minutes" or equivalent
  4. Is the Grafana datasource well configured? — in Grafana, Connections → Data sources, test the connection to the Prometheus datasource

See Prometheus and Grafana.

How do I get a heap dump of the backend?

Three paths:

  • Monitoring dashboard — open http://localhost:3001, heap dump widget section, click Download. The dump can take up to 60 seconds.
  • Direct APIcurl http://localhost:3001/api/heapdump -o heapdump.hprof
  • From the containerdocker exec perfshop-app sh -c 'curl http://localhost:9090/actuator/heapdump' > heapdump.hprof

The 9090 management port is not publicly exposed; only the monitoring proxy accesses it through the internal Docker network.

Analyze the .hprof file with Eclipse Memory Analyzer (MAT) or VisualVM.


This FAQ will grow as recurring questions come in. If your question is not here, contact contact@perfshop.io or open an issue on Forgejo.