A job board was running a national school directory

LearningDifferences.info helps families compare how well individual public schools support students with learning differences. Its 8,829 schools were stored as job listings, which cost 1.55 million database rows to describe. We gave the data its own home — and in doing so turned a donation button into a subscription product.

Client
LearningDifferences.info
Sector
Special-education data
Role
Subcontracted technical delivery
Agency partner
Launched
5 August 2026

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.

The
Challenge

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 siteValue
Schools stored as job-board listings8,829
Plugin holding themWP Job Manager 2.4.5
Rows in wp_postmeta1,571,448
…belonging to those listings1,547,906 — 98.5%
Implied metadata rows per school~175
Active plugins25

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.

The
Analysis

A directory is not a job board, and the difference is not cosmetic.

The data was relational

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.

The plugins were the risk

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.

Design and data had to separate

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
Solution

Two purpose-built tables instead of a million metadata rows

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.

One plugin, written for this product

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.

The design came from Scepter. AI built from it.

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.

From a donation button to a subscription product

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.

Built at the client's pace, on purpose

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
Results

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.

1.5M → 111
metadata rows
25 → 4
active plugins
−88%
database size
$0 → $100
free tier and a paid annual tier, where there was only a donate button

What changed commercially

 BeforeAfter
PaymentPayPal donationsStripe subscriptions, live 1 June 2026
Revenue shapeOne-off giftsRecurring annual
AccountsFree tier and paid tier
What the paid tier unlocksFull 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.

Measured on both installs, 18 September 2026

MeasureBeforeAfterChange
wp_postmeta rows1,571,448111model left postmeta
Active plugins254−21
Database size311.6 MB37.4 MB−88%
Uploads326 MB / 1,521 files24 MB / 116 files−93%
wp_posts rows9,23080schools left the posts table
Data years held3 (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.

Is your platform holding your data, or just storing it?

We rebuild products that have outgrown the tools they were assembled from — and we tell you which numbers are real.