Exam Simulator Cloud · Security · Linux · IT
About · Engineering

How it's built

A case study in shipping a real product on free tiers and our own hardware: a Rust/WebAssembly exam engine, a Cloudflare Worker with D1, self-hosted Git and CI, tests on every push, backups with a restore drill and monitoring.

  • 18exams ready (29 in the catalog)
  • 4 444questions, 94 of them performance-based
  • 27case studies with 136 questions
  • 1 475concepts in 84 domains

Architecture

  1. CodeForgejoself-hosted Git on a home server
  2. CI/CDWoodpecker CIserver and agents on home-lab hardware
  3. EdgeCloudflare Workersstatic site, WASM engine and the accounts API
  4. DataCloudflare D1SQLite at the edge: classes, results, sessions

Browser: Rust → WebAssembly

The exam engine, adaptive practice and every page are Rust (Velvet framework) compiled to WebAssembly. Pages are prerendered at build time, so they load and read without JavaScript; state lives in local storage and works offline (service worker).

Worker + D1

A small JavaScript Worker serves the static assets and the class API: join with a class code, passkeys or a recovery code, signed session cookies, sync of results and learning state, teacher and admin views. D1 has versioned migrations that the Worker can also apply itself.

Content as data

Each exam is a folder of JSON (exam guide, domains and weights, question bank, optional performance-based items and case studies) compiled into the engine. Adding an exam needs no code change; every count on this site is computed from the same data at build time.

Tests and delivery

On every push

  1. Validate every exam bank (schema, content rules, catalog in sync, quality ratchet)
  2. Test the Rust engine (cargo test) and the Worker against a throwaway local D1 (node:test), in parallel
  3. Build the WASM, prerender every page, optimise with wasm-opt
  4. End-to-end in headless Chromium (Playwright), desktop and mobile
  5. Preview each branch on its own URL, isolated from production data
  6. Deploy main, apply migrations and smoke-test that the edge serves exactly that commit

Self-hosted CI

Forgejo and Woodpecker run in rootless Podman; the agents cache toolchains, crates, npm packages and browsers in a named volume. A push is live on the edge in about two minutes. No CI minutes to pay for — the runners are our own machines.

The quality approach

Static checks

A checker runs on every build: broken references, bad answer keys and option counts, missing explanations and duplicate questions fail the build. Near-duplicates, letter bias and giveaway-length answers are reported, and a ratchet stops the share of “the correct answer is the longest option” from ever getting worse per exam.

Runtime statistics

Per question: correct rate, option picks, point-biserial discrimination and answer rate from exam simulations, plus student reports. Questions that look ambiguous or too easy are flagged in the admin view for review.

Honest numbers

No pass estimate is shown until there is enough evidence (20 answers, 3 per domain, a quarter of the concepts). After that, scores and pass probability are ranges with a confidence word, and every score is labelled an estimate.

Operations

Backups

Nightly export of the D1 database to our own disk (14 daily, 8 weekly, checksummed), an off-site copy (30 daily, 26 weekly) and Cloudflare's Time Travel as a second net.

Restore drill

Once a month CI restores the newest backup into a throwaway local D1 and checks the schema version and row counts against the backup's manifest.

Monitoring

A deep health check (Worker, database and the deployed commit) every 15 minutes; failed deploys, backups or drills raise a de-duplicated push alert through self-hosted ntfy.

Trade-offs

  • Free tiers, hard limits. Cloudflare's free plan (100 000 Worker requests and 5 million D1 row reads a day) is far above a class's needs, but caps growth; the code keeps D1 reads indexed and small.
  • Self-hosted means our own uptime. 0 kr in cloud and CI subscription fees, but the hardware, its electricity and its maintenance are real costs, and a home-lab outage stops deploys (never the live site).
  • Offline-first. Practice works without a network and syncs later; the price is merge logic for learning state and a service worker to keep in step.
  • Estimates, not real scores. A linear scaled score is transparent and testable but cannot equate exam forms like the vendors do — so it is always labelled an estimate.
  • Content in the binary. Compiling the banks into the WASM makes every page instant and offline, at the cost of a larger first download (cached afterwards).

Cost

PartPlanSubscription fee
Workers + static assetsCloudflare Free0 kr
D1 databaseCloudflare Free0 kr
Git hosting + CI runnersself-hosted0 kr
Alerts + backupsself-hosted0 kr
Cloud and CI subscription fees0 kr / month

Not counted: the self-hosted hardware, its electricity and the time to run it.

Stack

Rust + Velvet framework → WebAssembly · Cloudflare Workers (JavaScript) + D1 (SQLite) · passkeys (WebAuthn) and signed session cookies · Forgejo + Woodpecker CI in rootless Podman · Playwright, node:test, cargo test and shell-tested ops scripts · ntfy alerts and systemd timers.

Built by Marko Svensson.

Independent. This simulator is not affiliated with, endorsed by or sponsored by Amazon Web Services, Linux Professional Institute, CompTIA, Microsoft, HashiCorp, Google Cloud, CNCF / Linux Foundation, ISC2 and PeopleCert (ITIL) or any other certification body. All trademarks belong to their owners; exam names are used only to identify the exams. The questions are original practice material, not real exam content.

AWS and the AWS exam names are trademarks of Amazon.com, Inc. or its affiliates. LPI, Linux Essentials and LPIC are trademarks of the Linux Professional Institute. Linux is a registered trademark of Linus Torvalds. CompTIA, A+, Network+, Security+, CySA+ and Linux+ are trademarks of CompTIA, Inc. Microsoft, Azure, Microsoft Entra, Microsoft Defender, Microsoft Sentinel, Microsoft Purview and Microsoft Foundry are trademarks of the Microsoft group of companies. HashiCorp, Terraform and HCP are trademarks of HashiCorp, an IBM company. Google Cloud, Gemini and Vertex AI are trademarks of Google LLC. Kubernetes, KCNA and CNCF are trademarks of The Linux Foundation. ISC2, CC and Certified in Cybersecurity are trademarks of ISC2, Inc. ITIL and PRINCE2 are registered trademarks of PeopleCert. Practice questions are original and not endorsed by PeopleCert.

Exam Simulator

Independent practice exams for cloud, security, Linux and IT certifications, built for a classroom. No email, no ads, no third-party trackers.

Svenska
Privacy: results stay in this browser unless you join a class; then your display name, results and basic usage logs (never raw IP addresses) are stored for your teacher.
Trademark notices

Not affiliated with, endorsed by or sponsored by Amazon Web Services, Linux Professional Institute, CompTIA, Microsoft, HashiCorp, Google Cloud, CNCF / Linux Foundation, ISC2, PeopleCert (ITIL). AWS and the AWS exam names are trademarks of Amazon.com, Inc. or its affiliates. LPI, Linux Essentials and LPIC are trademarks of the Linux Professional Institute. Linux is a registered trademark of Linus Torvalds. CompTIA, A+, Network+, Security+, CySA+ and Linux+ are trademarks of CompTIA, Inc. Microsoft, Azure, Microsoft Entra, Microsoft Defender, Microsoft Sentinel, Microsoft Purview and Microsoft Foundry are trademarks of the Microsoft group of companies. HashiCorp, Terraform and HCP are trademarks of HashiCorp, an IBM company. Google Cloud, Gemini and Vertex AI are trademarks of Google LLC. Kubernetes, KCNA and CNCF are trademarks of The Linux Foundation. ISC2, CC and Certified in Cybersecurity are trademarks of ISC2, Inc. ITIL and PRINCE2 are registered trademarks of PeopleCert. Practice questions are original and not endorsed by PeopleCert. Exam names are used here only to identify the exams. Questions are original practice material, not real exam content.