PGSimCity: A 3D Postgres City That Makes Checkpoints and Bloat Visible
An explorable 3D city that shows how Postgres actually works. PGSimCity An explorable 3D city that shows how PostgreSQL actually works.** PGSimCity turns a PostgreSQL cluster into a city you can inspect, walk through, and break.
At a glance
- What is it?
- PGSimCity turns a PostgreSQL 18 cluster into a walkable 3D city, with colored buildings for buffers, WAL, and vacuum. It is a teaching model, not an emulator, and it knows exactly where its simplifications end.
- Who is it for?
- Adopt PGSimCity if you teach or learn PostgreSQL internals and need a spatial, interactive map of processes like checkpoints, WAL, and vacuum. Skip it if you need a numeric simulator or if your audience relies on screen readers, since the 3D scene has no nonvisual equivalent.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
Who This City Is For
PGSimCity targets engineers who are good at their job but have never operated a database. The README names the audience directly: people who need to understand why a checkpoint spikes latency, why one forgotten transaction bloats a table forever, and what synchronous_commit really charges them. That is a specific gap. Most database documentation explains mechanisms in text and diagrams, but this project translates those mechanisms into a persistent spatial metaphor. A backend row, a buffer pool with up to 1,024 frames, a WAL district, and a maintenance yard become places you can walk through. The project is not aimed at DBAs who already know these systems cold; it is for application developers and SREs who have felt the symptoms without seeing the machinery.
A Model, Not an Emulator: What That Means
The README is blunt about the boundary. The 3D city is a model of PostgreSQL, not an emulator: no PostgreSQL source code runs in that city, and the numbers are scaled so a human can watch them. That distinction matters. The city animates processes like the clock sweep and checkpoint fsync, but the values are not real timings. The project targets the PostgreSQL 18 major line, and 18.4 is the reviewed reference release. Mechanism claims follow the REL_18_STABLE source, and the README links to specific functions like GetAccessStrategy and CalculateCheckpointSegments. However, the current TypeScript buffer sample still uses a fixed 32-frame ring, which the project calls a disclosed historical simplification for the animation. That is honest, but it means you cannot use the animation as numeric version evidence until that model is aligned. The project also runs a deterministic suite that pins specific approximations, such as the WAL trigger as max_wal_size / (1 + checkpoint_completion_target), while PostgreSQL 18 rounds that calculation in whole WAL segments. So the city is a teaching aid, not a reference implementation.
What You See in the City: Districts and Semantics
The city is organized into districts, each mapped to a PostgreSQL component. The client sky sits north and shows connections from the application tier. The postmaster forks one backend per connection and never touches your data. The backend row holds 16 backend processes, and their lighting is their state, including idle in transaction. The buffer pool, shared_buffers, shows up to 1,024 representative frames, with 256 active at the 2 GiB model default, beside wal_buffers, the ProcArray, lock table, CLOG, and buffer mapping table. The excavation is the data directory, where memory ends and storage begins. Storage below shows heap files as fields of 8 KiB pages, B-trees as actual trees, TOAST, the FSM, and visibility map. The WAL district is east, with backends and walwriter writing into pg_wal, the archiver copying completed segments, and walsenders streaming WAL. The maintenance yard is west, with checkpointer, background writer, and autovacuum launcher. Standbys are south, with walreceivers, startup processes, and lag. Color is semantic: WAL is amber, dirty pages red, clean pages blue, vacuum violet, checkpoints pink, background writer teal, replication orange, storage green, indexes aqua, locks red. That color coding is not decoration; it lets you spot a checkpoint storm or a vacuum run from across the city.
Getting It Running: No Install, or a Local Build
The fastest route is the live city at the project homepage, which requires no install. The README invites you to explore it directly in a browser. For local use, the repository is on GitHub with the default branch main, written primarily in TypeScript. The project has a deterministic test suite that fails CI on a red test, meaning the suite is strict about pinned formulas. To run it yourself, you would clone the repository and follow the standard TypeScript workflow, though the README does not list explicit setup commands. The live demo is the intended entry point. The project also includes an opt-in Query flow and a Machine directory that can run PGlite, a real in-memory PostgreSQL compiled to WebAssembly. That is a notable difference: the city model itself is not an emulator, but the Machine component can run actual PostgreSQL code, giving you a bridge between the animated model and real behavior.
Scenarios That Teach: Cache Thrash, work_mem Cliff, and More
The README lists several scenarios designed to expose specific behaviors. Cache thrash sets shared_buffers to 16 MiB, below the manual control's 128 MiB minimum, so the clock sweep races and backends write their own dirty victims before reading another page. The work_mem cliff uses fixed Sort and HashAggregate nodes that spill at 2 MiB and fit at 4 MiB without replanning, showing private reservoirs, base/pgsql_tmp, temp counters, and latency breakdown. Long-running transaction sinks the xmin horizon blade and turns it red; autovacuum still travels to tables but reports zero removable rows while the sessions table bloats. Checkpoint storm shows the checkpointer's flywheel, the fsync phase shudder, and a wall of full-page writes flooding the WAL district. Setting synchronous_commit to off makes backends stop waiting in commit_wait, and the README says you can then read what you traded away. These scenarios are the core value: they turn abstract knobs into visible consequences.
Limitations and Where It Is the Wrong Tool
The most serious limitation is accessibility. The PostgreSQL lessons have keyboard and text-first routes, including a city architecture description generated from the layout, but the 3D scene and first-person walk do not have a nonvisual equivalent. The project acknowledges this in ACCESSIBILITY.md and calls it an irreducible spatial boundary. That rules out PGSimCity for any classroom or team where blind or low-vision engineers need full access. Another limitation is the model's numerical accuracy. The README explicitly warns that the animation must not be used as numeric version evidence for the buffer ring, and the deterministic suite pins approximations that differ from PostgreSQL 18's actual rounding. If you need precise numbers for capacity planning or performance tuning, this is the wrong tool. It is also not a substitute for reading the source; the README links to REL_18_STABLE functions, but the city is a simplification. Touch controls have been verified only in Chrome's mobile emulation, so mobile behavior is unproven on other browsers.
Alternatives: PGlite and the Source Itself
The closest alternative is PGlite, which the project itself uses in its Machine component. PGlite is a real in-memory PostgreSQL compiled to WebAssembly, so it executes actual SQL and produces real query plans and buffer statistics. The difference in approach is fundamental: PGlite gives you the real engine, while PGSimCity's 3D city is a scaled model with animated approximations. If you want to see exactly how a query touches buffers or how work_mem spills, PGlite gives you numeric truth but no spatial intuition. PGSimCity gives you the spatial story but not the numbers. Another alternative is reading the PostgreSQL source directly, as the project does. The README links to REL_18_STABLE functions like GetAccessStrategy and CalculateCheckpointSegments, so you can verify claims against the code. That is the highest-fidelity route, but it requires the ability to read C and trace call paths. PGSimCity lowers that barrier, but you must cross-check its animations against the source or the docs when precision matters.
Maintenance, License, and What to Verify First
The project is under Apache-2.0, which is permissive and allows commercial use with attribution. It is independent and non-commercial, and it contains no SimCity code or assets, so there is no trademark issue beyond the name. The release cadence is active: v0.40.0 landed on 2026-08-06, with v0.39.6 and v0.39.5 the day before, so fixes are frequent. The README notes that mistakes have been found and fixed throughout, and it invites corrections via a template for PostgreSQL mismatches. That is a healthy sign. Before you rely on any specific animation, verify the model's pinned formulas against the current REL_18_STABLE source. The deterministic suite pins the WAL trigger approximation and cache hit ratio, and the buffer ring is a known simplification. Check the repository's issue tracker for open mismatches, and use the correction template if you find one. The project is early, 0.x, so expect breaking changes in the model and the UI. If you adopt it for teaching, pin a specific version and re-verify after updates.
Editorial conclusion
Adopt PGSimCity if you teach or learn PostgreSQL internals and need a spatial, interactive map of processes like checkpoints, WAL, and vacuum. Skip it if you need a numeric simulator or if your audience relies on screen readers, since the 3D scene has no nonvisual equivalent. Before trusting any animation as evidence, verify the model's disclosed simplifications, such as the fixed 32-frame buffer ring and the WAL trigger rounding, against the linked PostgreSQL 18 source. Start with the T-key tour and the Cache thrash scenario, then check the deterministic suite's pinned formulas against the current REL_18_STABLE code.
Community notes