
Released Solutions was engaged as a subcontracted technical delivery partner by Scepter Marketing, the agency that holds the client relationship. Scepter owned the account and the design; Released Solutions owned the engineering. This case study covers the engineering.
The product is a public directory that scores and compares how individual public schools support students with learning differences, so families can judge campuses on special-education provision rather than on general academic ratings. It works. The problem was never the idea — it was what the idea had been built on.
A commercial job-board plugin was carrying the entire school directory. Every school was a job listing. Every attribute of every school was a row in WordPress' generic metadata table.
| Measured on the original site | Value |
|---|---|
| Schools stored as job-board listings | 8,829 |
| Plugin holding them | WP Job Manager 2.4.5 |
Rows in wp_postmeta | 1,571,448 |
| …belonging to those listings | 1,547,906 — 98.5% |
| Implied metadata rows per school | ~175 |
| Active plugins | 25 |
Describing 8,829 schools cost 1.55 million rows, and every filtered search ran against a separately maintained index layered over them. Adding a data year, a new metric or a second state multiplied rows against the same structure. The ceiling was structural, not a matter of tuning.
And there was no way to earn from any of it. The site's only commerce was a donations plugin — a one-off ask, bolted on. Monetising the data had been the owner's ambition from the start, and nothing in the existing structure made it reachable: the depth of data worth paying for was precisely what the model could not hold.
Two further problems compounded it. Several of the 25 plugins were commercially licensed — each one a renewal, an update surface and a dependency. And the page builder had become the content model: 21 builder templates plus a builder child theme meant layout and data presentation were entangled, so changing what the data said was a design task.
A directory is not a job board, and the difference is not cosmetic.
Schools have fixed attributes, repeated yearly, compared against each other. That is a table with columns. Storing it as loose key-value rows attached to posts made every query a join against a million-row table.
Twenty-five dependencies, several paid, each able to break the site on an update or disappear on a vendor's decision. For a site whose value is its data, that is a lot of surface area protecting very little.
If a new data year requires touching page templates, the product cannot scale. The presentation layer needed to stop being the place the data model lived.
The school data moved out of WordPress' posts and metadata tables entirely, into two tables designed for it: one row per school, one row per school per data year. That is what makes multi-year comparison possible rather than expensive.
7,472 lines of PHP carrying the data model, the scoring, the search, subscriptions and payments, reviews, and the SEO and sitemap integration — plus a purpose-built theme of 3,197 lines of PHP and 3,483 lines of CSS. The third-party surface that remains is two plugins: an SEO plugin and a security plugin.
Scepter Marketing's design team produced the layout in Figma. That design was then consumed directly to build the home page, and its colour system and visual language were carried across the remaining pages from the same source. The division of labour is worth being precise about: their designers owned how it looks, and we owned how it works.
The original site's only commerce was a PayPal donations plugin: a one-off ask, with nothing to sell. The rebuild introduced a Stripe subscription programme, live and verified end to end on 1 June 2026, with accounts, tiers and recurring billing built into the same plugin that holds the data.
What makes it work is the architecture. A free account gets the most recent year of school data. Full Access Premium, at $100 a year, unlocks every year of history, side-by-side school comparison and all data categories — and those are precisely the things the old structure could not have carried. Multi-year history was unsellable when a single year already cost 1.55 million metadata rows. Giving the data its own tables is what turned depth of data into a product.
The engagement ran on a deliberately unhurried cadence — regular working sessions co-developing live with the site owner, while he ran his own parallel workstream getting the underlying data feeds right. The calendar length reflects that accommodation rather than drift, and against that schedule the project ran on time.
One decision worth recording: the original user accounts were deliberately not carried over, because they were spam. Migrating everything is easy. Deciding what not to migrate is the part that takes judgement.
The data model no longer lives in WordPress' metadata table — and the site now has something to sell.
Both sites were measured on the same day with the same tooling, on live installations. This is a structural comparison, not a performance claim — it is not a time series, so it cannot be distorted by seasonality, campaigns or a tracking change.
| Before | After | |
|---|---|---|
| Payment | PayPal donations | Stripe subscriptions, live 1 June 2026 |
| Revenue shape | One-off gifts | Recurring annual |
| Accounts | — | Free tier and paid tier |
| What the paid tier unlocks | — | Full data history, side-by-side comparison, all data categories |
Tiers and pricing as published on the site. No revenue, subscriber or conversion figures are claimed.
| Measure | Before | After | Change |
|---|---|---|---|
wp_postmeta rows | 1,571,448 | 111 | model left postmeta |
| Active plugins | 25 | 4 | −21 |
| Database size | 311.6 MB | 37.4 MB | −88% |
| Uploads | 326 MB / 1,521 files | 24 MB / 116 files | −93% |
wp_posts rows | 9,230 | 80 | schools left the posts table |
| Data years held | — | 3 (2019–2025) | multi-year comparison |
School counts are reported separately and deliberately not presented as growth: the original site held 8,829 job-listing records, and the rebuilt site holds 9,578 rows in its schools table. The two figures come from different systems and the relationship between them has not been established, so no migration or growth claim is made from them.
The plugin was not the problem. Asking a job board to be a database was the problem.
We rebuild products that have outgrown the tools they were assembled from — and we tell you which numbers are real.
